[Jifty-commit] r1762 - in jifty/branches/moose: . lib/Jifty lib/Jifty/Action lib/Jifty/Action/Record lib/Jifty/Filter lib/Jifty/Manual lib/Jifty/Test/WWW lib/Jifty/Web/Form lib/Jifty/Web/Session plugins/ProfileBehaviour/share/web/static/css plugins/ProfileBehaviour/share/web/static/js plugins/REST/lib/Jifty/Plugin/REST share/web/static/js

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Sat Aug 5 05:30:18 EDT 2006


Author: audreyt
Date: Sat Aug  5 05:18:48 2006
New Revision: 1762

Added:
   jifty/branches/moose/lib/Jifty/Filter/
   jifty/branches/moose/lib/Jifty/Filter/DateTime.pm
   jifty/branches/moose/lib/Jifty/Manual/Upgrading.pod
Modified:
   jifty/branches/moose/   (props changed)
   jifty/branches/moose/AUTHORS
   jifty/branches/moose/MANIFEST
   jifty/branches/moose/Makefile.PL
   jifty/branches/moose/lib/Jifty/Action.pm
   jifty/branches/moose/lib/Jifty/Action/Record/Create.pm
   jifty/branches/moose/lib/Jifty/Action/Redirect.pm
   jifty/branches/moose/lib/Jifty/ClassLoader.pm
   jifty/branches/moose/lib/Jifty/DateTime.pm
   jifty/branches/moose/lib/Jifty/LetMe.pm
   jifty/branches/moose/lib/Jifty/Manual/Tutorial.pod
   jifty/branches/moose/lib/Jifty/Notification.pm
   jifty/branches/moose/lib/Jifty/Request.pm
   jifty/branches/moose/lib/Jifty/Test.pm
   jifty/branches/moose/lib/Jifty/Test/WWW/Mechanize.pm
   jifty/branches/moose/lib/Jifty/Web.pm
   jifty/branches/moose/lib/Jifty/Web/Form.pm
   jifty/branches/moose/lib/Jifty/Web/Form/Clickable.pm
   jifty/branches/moose/lib/Jifty/Web/Form/Element.pm
   jifty/branches/moose/lib/Jifty/Web/Form/Field.pm
   jifty/branches/moose/lib/Jifty/Web/Form/Link.pm
   jifty/branches/moose/lib/Jifty/Web/Session.pm
   jifty/branches/moose/lib/Jifty/Web/Session/ClientSide.pm
   jifty/branches/moose/plugins/ProfileBehaviour/share/web/static/css/behaviour-profile.css
   jifty/branches/moose/plugins/ProfileBehaviour/share/web/static/js/behaviour.js
   jifty/branches/moose/plugins/REST/lib/Jifty/Plugin/REST/Dispatcher.pm
   jifty/branches/moose/share/web/static/js/app_behaviour.js
   jifty/branches/moose/share/web/static/js/jifty.js

Log:
 r16827 at T (orig r1713):  nelhage | 2006-08-01 02:45:19 +0800
 Jifty::Web::state_variables no longer prefixes keys with J:V- before
 returning them, and Clickables now serialize the *outgoing* state
 vars, instead of the previous request's.
 r16828 at T (orig r1714):  nelhage | 2006-08-01 03:36:26 +0800
 Forgot to push this with the last commit.
 r16829 at T (orig r1715):  nelhage | 2006-08-01 04:40:34 +0800
 Some Behaviour profiling UI fixes.
 r16845 at T (orig r1716):  audreyt | 2006-08-01 14:38:17 +0800
 * Jifty::Plugin::REST::Dispatcher - /=/action/ now works across HTML+HTTP.
   (t/ not yet updated.)
 r16857 at T (orig r1717):  zev | 2006-08-02 01:17:16 +0800
  r12087 at truegrounds:  zev | 2006-08-01 13:16:51 -0400
  * doc fix
 
 r16859 at T (orig r1719):  nelhage | 2006-08-02 02:29:42 +0800
 Doc fixes
 r16860 at T (orig r1720):  nelhage | 2006-08-02 02:31:01 +0800
 Adding Jifty::Filter::DateTime, a JDBI filter that promotes DateTime
 objects to Jifty::DateTime objects on read, setting the time zone
 appropriately.
 r16861 at T (orig r1721):  nelhage | 2006-08-02 03:08:55 +0800
 Slight cleanup
 r16863 at T (orig r1723):  nelhage | 2006-08-02 04:06:57 +0800
 POD++
 r16864 at T (orig r1724):  nelhage | 2006-08-02 05:46:31 +0800
 Workaround DateManip's parsing of bare days of weeks as references to
 days in the current week, instead of assuming future days.
 r16870 at T (orig r1725):  bartb | 2006-08-02 12:02:30 +0800
 Add myself to the AUTHORS file
 r16871 at T (orig r1726):  bartb | 2006-08-02 12:05:13 +0800
 A start at some docs on upgrading, needs reviewing and some more examples
 r16874 at T (orig r1727):  nelhage | 2006-08-02 22:59:19 +0800
 Documenting the ProfileBehaviour plugin.
 r16875 at T (orig r1728):  nelhage | 2006-08-03 02:28:31 +0800
 Preventing some DateTime warnings
 r16876 at T (orig r1729):  trs | 2006-08-03 02:35:39 +0800
  r15040 at zot:  tom | 2006-08-02 14:35:00 -0400
  Support turning off autocomplete on a per-form basis.  We still need per-field, but that's for later.
 
 r16877 at T (orig r1730):  trs | 2006-08-03 03:27:11 +0800
  r15042 at zot:  tom | 2006-08-02 15:27:03 -0400
  Patch from Todd Chapman to fix tutorial
 
 r16878 at T (orig r1731):  trs | 2006-08-03 06:01:06 +0800
  r15044 at zot:  tom | 2006-08-02 17:59:06 -0400
  * Ignore "fluff" errors since they cause non-W3C attributes like "autocomplete" to be warned about
  * Add html_ok method for checking the mech's current content so tests can use it while we retain control over Test::HTML::Lint
 
 r16887 at T (orig r1732):  nelhage | 2006-08-03 08:20:58 +0800
 No longer lose if you do a Jifty::Action::Redirect to the same page
 you're already on. Also, add the ability to force Web to redirect,
 even if it's to the current page.
 r16888 at T (orig r1733):  clkao | 2006-08-03 11:58:40 +0800
 misc cleanups.
 r16889 at T (orig r1734):  clkao | 2006-08-03 12:14:48 +0800
 Jifty::DateTime cleanups.
 
 r16900 at T (orig r1735):  trs | 2006-08-03 13:46:26 +0800
  r15050 at zot:  tom | 2006-08-03 01:45:33 -0400
  We need the anonymous subs because otherwise the method of the base class is always called, instead of the appropriate overridden method in a child class.
 
 r16901 at T (orig r1736):  trs | 2006-08-03 13:56:21 +0800
  r15052 at zot:  tom | 2006-08-03 01:56:04 -0400
  Inline my last commit message about needing to use anon subs for overload
 
 r16902 at T (orig r1737):  bartb | 2006-08-03 14:06:48 +0800
 Add a small bit of doc about creating your own classes that are normally created by J::ClassLoader
 r16904 at T (orig r1739):  clkao | 2006-08-03 14:16:55 +0800
 Form::Clickable: Don't mix self accessors and args.
 
 r16908 at T (orig r1740):  nelhage | 2006-08-04 00:18:37 +0800
 Writing out state variables at the start of forms, instead of at the
 end. 
 r16909 at T (orig r1741):  zev | 2006-08-04 00:37:17 +0800
  r12167 at truegrounds:  zev | 2006-08-02 17:17:58 -0400
  * added Jifty::Request::clear_state_variables
 
 r16910 at T (orig r1742):  zev | 2006-08-04 00:37:24 +0800
  r12168 at truegrounds:  zev | 2006-08-02 18:07:53 -0400
  * pod fix
 
 r16911 at T (orig r1743):  zev | 2006-08-04 00:37:45 +0800
 
 r16912 at T (orig r1744):  trs | 2006-08-04 02:25:49 +0800
  r15059 at zot:  tom | 2006-08-03 14:22:51 -0400
  Further explain XXX TODO
 
 r16913 at T (orig r1745):  trs | 2006-08-04 02:38:12 +0800
  r15066 at zot:  tom | 2006-08-03 14:38:05 -0400
  Give a description for get_html_ok so that you know what URLs fail/succeed in test output
 
 r16914 at T (orig r1746):  zev | 2006-08-04 03:25:49 +0800
  r12255 at truegrounds:  zev | 2006-08-03 15:25:42 -0400
  * we already do this in the J:W:F:Clickable constructor
 
 r16915 at T (orig r1747):  zev | 2006-08-04 07:40:23 +0800
  r12279 at truegrounds:  zev | 2006-08-03 19:40:08 -0400
  * added infrastructure to do mime mails
 
 r16917 at T (orig r1748):  audreyt | 2006-08-04 09:07:41 +0800
 * Web::Session::ClientSide - if reassembly of cookies failed, start a new session.
 r16920 at T (orig r1749):  trs | 2006-08-04 11:53:14 +0800
  r15059 at zot:  tom | 2006-08-03 14:22:51 -0400
  Further explain XXX TODO
 
 r16921 at T (orig r1750):  trs | 2006-08-04 11:53:19 +0800
 
 r16922 at T (orig r1751):  trs | 2006-08-04 11:53:25 +0800
  r15066 at zot:  tom | 2006-08-03 14:38:05 -0400
  Give a description for get_html_ok so that you know what URLs fail/succeed in test output
 
 r16923 at T (orig r1752):  trs | 2006-08-04 11:53:32 +0800
  r15070 at zot:  tom | 2006-08-03 23:52:55 -0400
  The setAttribute call doesn't work for "class" in IE
 
 r16924 at T (orig r1753):  jesse | 2006-08-04 14:28:25 +0800
  r14902 at pinglin:  jesse | 2006-08-04 02:27:39 -0400
  * Don't try to lowercase session information on postgres
 
 r16936 at T (orig r1754):  nelhage | 2006-08-05 01:27:34 +0800
 Unescape LetMe arguments properly
 r16937 at T (orig r1755):  trs | 2006-08-05 01:44:11 +0800
  r15081 at zot:  tom | 2006-08-04 13:43:59 -0400
  Use our own "enter" handler to select the button to click, since Safari sometimes gets it wrong with complex fields
 
 r16938 at T (orig r1756):  nelhage | 2006-08-05 01:54:10 +0800
 Don't attempt to disable hidden inputs, since this sometimes causes IE to die
 r16939 at T (orig r1757):  zev | 2006-08-05 02:28:29 +0800
  r12338 at truegrounds:  zev | 2006-08-04 14:28:16 -0400
  * add UTF-8 charset to message body on notifications
 
 r16940 at T (orig r1758):  nelhage | 2006-08-05 03:09:52 +0800
 Properly encode arguments when generating LetMe URLs.
 r16944 at T (orig r1759):  trs | 2006-08-05 12:43:23 +0800
 
 r16945 at T (orig r1760):  trs | 2006-08-05 12:43:38 +0800
  r15090 at zot:  tom | 2006-08-05 00:43:19 -0400
  Remove debugging statement
 
 r16946 at T (orig r1761):  clkao | 2006-08-05 12:56:06 +0800
 Forgot to commit this.


Modified: jifty/branches/moose/AUTHORS
==============================================================================
--- jifty/branches/moose/AUTHORS	(original)
+++ jifty/branches/moose/AUTHORS	Sat Aug  5 05:18:48 2006
@@ -11,3 +11,4 @@
 Kenichi Ishigaki <ishigaki at tcool.org>
 Chia-Liang Kao <clkao at clkao.org>
 Dobrica Pavlinusic <dpavlin at rot13.org>
+Bart Bunting <bart at bunting.net.au>

Modified: jifty/branches/moose/MANIFEST
==============================================================================
--- jifty/branches/moose/MANIFEST	(original)
+++ jifty/branches/moose/MANIFEST	Sat Aug  5 05:18:48 2006
@@ -54,6 +54,7 @@
 lib/Jifty/DateTime.pm
 lib/Jifty/Dispatcher.pm
 lib/Jifty/Everything.pm
+lib/Jifty/Filter/DateTime.pm
 lib/Jifty/Handle.pm
 lib/Jifty/Handler.pm
 lib/Jifty/I18N.pm
@@ -69,6 +70,7 @@
 lib/Jifty/Manual/PageRegions.pm
 lib/Jifty/Manual/Tutorial.pod
 lib/Jifty/Manual/Tutorial_ja.pod
+lib/Jifty/Manual/Upgrading.pod
 lib/Jifty/Mason/Halo.pm
 lib/Jifty/Model/Metadata.pm
 lib/Jifty/Model/Session.pm
@@ -130,6 +132,7 @@
 lib/Jifty/Web/Session.pm
 lib/Jifty/Web/Session/ClientSide.pm
 lib/Jifty/YAML.pm
+log
 Makefile.PL
 MANIFEST			This list of files
 MANIFEST.SKIP
@@ -177,6 +180,9 @@
 plugins/ProfileBehaviour/Makefile.PL
 plugins/ProfileBehaviour/share/web/static/css/behaviour-profile.css
 plugins/ProfileBehaviour/share/web/static/js/behaviour.js
+plugins/REST/lib/Jifty/Plugin/REST.pm
+plugins/REST/lib/Jifty/Plugin/REST/Dispatcher.pm
+plugins/REST/Makefile.PL
 README
 share/dtd/xhtml-lat1.ent
 share/dtd/xhtml-special.ent
@@ -207,6 +213,7 @@
 share/web/static/images/silk/bullet_arrow_up.png
 share/web/static/images/silk/calendar.png
 share/web/static/images/silk/cancel.png
+share/web/static/images/silk/cancel_grey.png
 share/web/static/images/silk/error.png
 share/web/static/images/silk/information.png
 share/web/static/images/silk/pencil.png
@@ -324,11 +331,21 @@
 t/Mapper/bin/jifty
 t/Mapper/lib/Mapper/Action/CrossBridge.pm
 t/Mapper/lib/Mapper/Action/GetGrail.pm
+t/Mapper/mapper
 t/Mapper/share/web/templates/autohandler
 t/Mapper/share/web/templates/index.html
 t/Mapper/t/00-prototype.t
 t/Mapper/t/01-raw-api.t
 t/Mapper/t/02-api.t
+t/TestApp-Plugin-REST/bin/jifty
+t/TestApp-Plugin-REST/etc/config.yml
+t/TestApp-Plugin-REST/lib/TestApp/Plugin/REST/Action/DoSomething.pm
+t/TestApp-Plugin-REST/lib/TestApp/Plugin/REST/Dispatcher.pm
+t/TestApp-Plugin-REST/lib/TestApp/Plugin/REST/Model/User.pm
+t/TestApp-Plugin-REST/t/00-model-User.t
+t/TestApp-Plugin-REST/t/00-prototype.t
+t/TestApp-Plugin-REST/t/01-config.t
+t/TestApp-Plugin-REST/t/02-basic-use.t
 t/TestApp/bin/jifty
 t/TestApp/lib/TestApp/Action/DoSomething.pm
 t/TestApp/lib/TestApp/Dispatcher.pm

Modified: jifty/branches/moose/Makefile.PL
==============================================================================
--- jifty/branches/moose/Makefile.PL	(original)
+++ jifty/branches/moose/Makefile.PL	Sat Aug  5 05:18:48 2006
@@ -19,14 +19,16 @@
 requires('Date::Manip');
 requires('Email::Folder');
 requires('Email::LocalDelivery');
+requires('Email::MIME');
+requires('Email::MIME::Creator');
 requires('Email::Send' => '1.99_01'); # Email::Send::Jifty::Test
 requires('Email::Simple');
-requires('Email::Simple::Creator');
 requires('Exporter::Lite');
 requires('File::Find::Rule');
 requires('File::MMagic');
 requires('File::ShareDir' => '0.04');
 requires('HTML::Entities');
+requires('HTML::Lint');
 requires('HTML::Mason' => 1.3101);           # HTML::Mason::Exceptions HTML::Mason::FakeApache HTML::Mason::MethodMaker HTML::Mason::Request HTML::Mason::Utils
 requires('HTML::Mason::Plugin');
 requires('HTTP::Cookies');

Modified: jifty/branches/moose/lib/Jifty/Action.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Action.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Action.pm	Sat Aug  5 05:18:48 2006
@@ -692,7 +692,7 @@
 
 =head2 _canonicalize_date DATE
 
-Parses and returns the date using L<Time::ParseDate>.
+Parses and returns the date using L<Jifty::DateTime::new_from_string>.
 
 =cut
 

Modified: jifty/branches/moose/lib/Jifty/Action/Record/Create.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Action/Record/Create.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Action/Record/Create.pm	Sat Aug  5 05:18:48 2006
@@ -32,8 +32,8 @@
     
     my $args = $self->SUPER::arguments;
     for my $arg (keys %{$args}) {
-        next unless $self->record->column($arg);
-        $args->{$arg}{default_value} = $self->record->column($arg)->default
+        my $column = $self->record->column($arg) or next;
+        $args->{$arg}{default_value} = $column->default
           if not $args->{$arg}->{default_value};
     }
     return $args;

Modified: jifty/branches/moose/lib/Jifty/Action/Redirect.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Action/Redirect.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Action/Redirect.pm	Sat Aug  5 05:18:48 2006
@@ -58,6 +58,7 @@
     my $page = $self->argument_value('url');
 
     Jifty->web->next_page($page);
+    Jifty->web->force_redirect(1);
     return 1;
 }
 

Modified: jifty/branches/moose/lib/Jifty/ClassLoader.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/ClassLoader.pm	(original)
+++ jifty/branches/moose/lib/Jifty/ClassLoader.pm	Sat Aug  5 05:18:48 2006
@@ -222,4 +222,26 @@
     wantarray ? @{ $self->{models} ||= [] } : $self->{models};
 }
 
+
+=head1 Writing your own classes
+
+If you require more functionality than is provided by the classes
+created by ClassLoader then you should create a class with the
+appropriate name and add your extra logic to it.
+
+For example you will almost certainly want to write your own
+dispatcher, so something like:
+
+ package MyApp::Dispatcher;
+ use Jifty::Dispatcher -base;
+
+If you want to add some application specific behaviour to a model's
+collection class, say for the User model, create F<UserCollection.pm>
+in your applications Model directory.
+
+ package MyApp::Model::UserCollection;
+ use base 'MyApp::Collection';
+
+=cut
+
 1;

Modified: jifty/branches/moose/lib/Jifty/DateTime.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/DateTime.pm	(original)
+++ jifty/branches/moose/lib/Jifty/DateTime.pm	Sat Aug  5 05:18:48 2006
@@ -35,19 +35,27 @@
     # Unless the user has explicitly said they want a floating time,
     # we want to convert to the end-user's timezone.  This is
     # complicated by the fact that DateTime auto-appends
-    $self->_get_current_user();
-    my $user_obj = $self->current_user->user_object;
-    if (    $user_obj
-        and $user_obj->can('time_zone')
-        and $user_obj->time_zone )
-    {
+    if (my $tz = $self->current_user_has_timezone) {
         $self->set_time_zone("UTC");
-        $self->set_time_zone( $user_obj->time_zone );
-
+        $self->set_time_zone( $tz );
     }
     return $self;
 }
 
+=head2 current_user_has_timezone
+
+Return timezone if the current user has it
+
+=cut
+
+sub current_user_has_timezone {
+    my $self = shift;
+    $self->_get_current_user();
+    my $user_obj = $self->current_user->user_object or return;
+    my $f = $user_obj->can('time_zone') or return;
+    return $f->($user_obj);
+}
+
 =head2 new_from_string STRING
 
 Take some user defined string like "tomorrow" and turn it into a
@@ -62,27 +70,22 @@
     my $string = shift;
     my $now;
     {
+        # Date::Manip interprets days of the week (eg, ''monday'') as
+        # days within the *curent* week. Detect these and prepend
+        # ``next''
+        # XXX TODO: Find a real solution (better date-parsing library?)
+        if($string =~ /^\s* (?:monday|tuesday|wednesday|thursday|friday|saturday|sunday)$/xi) {
+            $string = "next $string";
+        }
         local $ENV{'TZ'} = "GMT";
         $now = Date::Manip::UnixDate( $string, "%o" );
     }
     return undef unless $now;
     my $self = $class->from_epoch( epoch => $now, time_zone => 'gmt' );
-    $self->_get_current_user();
-    if (    $self->current_user->user_object
-        and $self->current_user->user_object->can('time_zone')
-        and $self->current_user->user_object->time_zone )
-    {
-
-        # If the DateTime we've been handed appears to actually be at
-        # a "time" then we want to make sure we get it to be that time
-        # in the local timezone
-        #
-        # If we had only a date, then we want to switch it to the
-        # user's timezone without adjusting the "time", as that could
-        # make 2006-12-01 into 2006-11-30
+    if (my $tz = $self->current_user_has_timezone) {
         $self->set_time_zone("floating")
             unless ( $self->hour or $self->minute or $self->second );
-        $self->set_time_zone( $self->current_user->user_object->time_zone );
+        $self->set_time_zone( $tz );
     }
     return $self;
 }

Added: jifty/branches/moose/lib/Jifty/Filter/DateTime.pm
==============================================================================
--- (empty file)
+++ jifty/branches/moose/lib/Jifty/Filter/DateTime.pm	Sat Aug  5 05:18:48 2006
@@ -0,0 +1,63 @@
+use warnings;
+use strict;
+
+=head1 NAME
+
+Jifty::Filter::DateTime -- A Jifty::DBI filter to work with
+                          Jifty::DateTime objects
+
+=head1 DESCRIPTION
+
+Jifty::Filter::DateTime promotes DateTime objects to Jifty::DateTime
+objects on load. This has the side effect of setting their time zone
+based on the record's current user's preferred time zone, when
+available.
+
+This is intended to be combined with C<Jifty::DBI::Filter::Date> or
+C<Jifty::DBI::Filter::DateTime>, e.g.
+
+    column created =>
+      type is 'timestamp',
+      filters are qw( Jifty::Filter::DateTime Jifty::DBI::Filter::DateTime),
+      label is 'Created',
+      is immutable;
+
+=cut
+
+package Jifty::Filter::DateTime;
+use base qw(Jifty::DBI::Filter);
+
+
+=head2 decode
+
+If the value is a DateTime, replace it with a Jifty::DateTime
+representing the same time, setting the time zone in the process.
+
+=cut
+
+
+sub decode {
+    my $self = shift;
+    my $value_ref = $self->value_ref;
+
+    return unless ref($$value_ref) && $$value_ref->isa('DateTime');
+
+    # XXX There has to be a better way to do this
+    my %args;
+    for (qw(year month day hour minute second nanosecond formatter)) {
+        $args{$_} = $$value_ref->$_ if(defined($$value_ref->$_));
+    }
+
+    my $dt = Jifty::DateTime->new(%args);
+
+    $$value_ref = $dt;
+}
+
+=head1 SEE ALSO
+
+L<Jifty::DBI::Filter::Date>, L<Jifty::DBI::Filter::DateTime>,
+L<Jifty::DateTime>
+
+=cut
+
+1;

Modified: jifty/branches/moose/lib/Jifty/LetMe.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/LetMe.pm	(original)
+++ jifty/branches/moose/lib/Jifty/LetMe.pm	Sat Aug  5 05:18:48 2006
@@ -184,9 +184,9 @@
     $self->path( shift @atoms );
     $self->checksum_provided( pop @atoms );
 
-    my %args = @atoms;
+    my %args = map {URI::Escape::uri_unescape($_)} @atoms;
     $self->until( delete $args{until} ) if $args{until};
-    
+
     $self->args(\%args);
 }
 
@@ -221,7 +221,7 @@
     return join ('/', 
         $args{'email'},
         $self->path,
-        %{$self->args},
+        (map {URI::Escape::uri_escape($_)} %{$self->args}),
         (defined $self->until ? ( 'until', $self->until ) : () ), #?
         $self->generate_checksum  
         );

Modified: jifty/branches/moose/lib/Jifty/Manual/Tutorial.pod
==============================================================================
--- jifty/branches/moose/lib/Jifty/Manual/Tutorial.pod	(original)
+++ jifty/branches/moose/lib/Jifty/Manual/Tutorial.pod	Sat Aug  5 05:18:48 2006
@@ -389,7 +389,7 @@
 only need to add the C<< $top->child( Post... >> part
 
   cat $(perl -MJifty::Util -e 'print Jifty::Util->share_root' \
-    )/share/web/templates/_elements/nav > share/web/templates/_elements/nav
+    )/web/templates/_elements/nav > share/web/templates/_elements/nav
 
 Otherwise, inside F<_elements>, open up a new file called C<nav> in your
 text editor and insert:

Added: jifty/branches/moose/lib/Jifty/Manual/Upgrading.pod
==============================================================================
--- (empty file)
+++ jifty/branches/moose/lib/Jifty/Manual/Upgrading.pod	Sat Aug  5 05:18:48 2006
@@ -0,0 +1,74 @@
+=head1 NAME
+
+Jifty::Manual::Upgrading
+
+=head2 DESCRIPTION
+
+Jifty provides a way for you to upgrade the database schema and data
+of your application between versions.  If all you are doing is adding
+new models or columns to existing models Jifty will do the upgrade
+almost automatically.  If more extensive changes are required you need
+to write some code to tell Jifty what to do.
+
+=head1 HOW TO
+
+=head2 New models and columns
+
+=head3 Adding a new model
+
+When adding a new model to your application you need to tell Jifty
+at which version of your application the model was created.  To do
+this add a since sub to your new model class.
+
+ sub since { 0.0.5 }
+
+=head3 Adding a new column to an existing model
+
+When you have a existing model and decide that you need to add another
+column to it you also need to tell Jifty about this.  This is done by
+using since as well, however the since goes into the column
+definition itself.  
+
+ column created_by => refers_to Wifty::Model::User, 
+		      since '0.0.20';
+
+
+=head2 data migration and schema changes
+
+If a file called C<Upgrade.pm> exists in your application it will be
+run by C<jifty schema --setup>.
+
+Upgrade.pm can be used to make any schema changes or to manipulate
+your applications data.
+
+At the very least your C<Upgrade.pm> should contain the following: 
+
+ package MyApp::Upgrade;
+
+ use base qw(Jifty::Upgrade);
+ use Jifty::Upgrade qw( since rename );
+
+ since '0.6.1' => sub {
+	....
+ };
+
+The C<since> function is where you do all the work.  Each C<since>
+will be run in version order until the application is up to date.
+
+
+=head3 Renaming a column
+
+To rename a column use C<rename> inside your C<since>.  You will also
+have to use the model class at the top of Upgrade.pm so Jifty can
+access it's schema definition.
+
+use MyApp::Model::User;
+
+since '0.61' => sub {
+  rename (table => 'MyApp::Model::User', 
+	  column => 'zip', 
+	  to => 'postcode'
+	 );
+};
+
+=head3 Migrating data

Modified: jifty/branches/moose/lib/Jifty/Notification.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Notification.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Notification.pm	Sat Aug  5 05:18:48 2006
@@ -5,8 +5,7 @@
 
 use base qw/Jifty::Object/;
 use Email::Send            ();
-use Email::Simple          ();
-use Email::Simple::Creator ();
+use Email::MIME::Creator;
 
 use Moose;
 has body        => qw( is rw isa Str );
@@ -94,13 +93,13 @@
     my $to         = join( ', ',
         map { ( $_->can('email') ? $_->email : $_ ) } grep {$_} @recipients );
     return unless ($to);
-    my $message = Email::Simple->create(
+    my $message = Email::MIME->create(
         header => [
             From    => $self->from    || 'A Jifty Application <nobody>',
             To      => $to,
             Subject => $self->subject || 'No subject',
         ],
-        body => join( "\n", $self->preface, $self->body, $self->footer )
+        parts => $self->parts
     );
     $self->set_headers($message);
 
@@ -122,7 +121,7 @@
 
 =head2 set_headers MESSAGE
 
-Takes a L<Email::Simple> object C<MESSAGE>, and modifies it as
+Takes a L<Email::MIME> object C<MESSAGE>, and modifies it as
 necessary before sending it out.  As the method name implies, this is
 usually used to add or modify headers.  By default, does nothing; this
 method is meant to be overridden.
@@ -248,6 +247,39 @@
 
 =cut
 
+=head2 full_body
+
+The main, plain-text part of the message.  This is the preface,
+body, and footer joined by newlines.
+
+=cut
+
+sub full_body {
+  my $self = shift;
+  return join( "\n", $self->preface, $self->body, $self->footer );
+}
+
+=head2 parts
+
+The parts of the message.  You want to override this if you want to
+send multi-part mail.  By default, this method returns a single
+part consisting of the result of calling C<< $self->full_body >>.
+
+Returns the parts as an array reference.
+
+=cut
+
+sub parts {
+  my $self = shift;
+  return [
+    Email::MIME->create(
+      attributes => { charset => 'UTF-8' },
+      body       => $self->full_body
+    )
+  ];
+
+}
+
 =head2 magic_letme_token_for PATH
 
 Returns a L<Jifty::LetMe> token which allows the current user to access a path on the

Modified: jifty/branches/moose/lib/Jifty/Request.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Request.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Request.pm	Sat Aug  5 05:18:48 2006
@@ -627,6 +627,19 @@
     delete $self->{'state_variables'}{$key};
 }
 
+=head2 clear_state_variables
+
+Remove all the state variables.
+
+=cut
+
+sub clear_state_variables {
+    my $self = shift;
+
+    $self->{'state_variables'} = {};
+}
+
+
 =head2 actions
 
 Returns a list of the actions in the request, as

Modified: jifty/branches/moose/lib/Jifty/Test.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Test.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Test.pm	Sat Aug  5 05:18:48 2006
@@ -191,7 +191,9 @@
 
 =head2 messages
 
-Returns the messages in the test mailbox, as a list of L<Email::Simple> objects.
+Returns the messages in the test mailbox, as a list of
+L<Email::Simple> objects.  You may have to use a module like
+L<Email::MIME> to parse multi-part messages stored in the mailbox.
 
 =cut
 

Modified: jifty/branches/moose/lib/Jifty/Test/WWW/Mechanize.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Test/WWW/Mechanize.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Test/WWW/Mechanize.pm	Sat Aug  5 05:18:48 2006
@@ -6,7 +6,8 @@
 
 $ENV{'http_proxy'} = ''; # Otherwise Test::WWW::Mechanize tries to go through your HTTP proxy
 
-use Test::HTML::Lint; # exports html_ok
+use HTML::Lint;
+use Test::HTML::Lint qw();
 use HTTP::Cookies;
 use XML::XPath;
 use Hook::LexWrap;
@@ -15,6 +16,12 @@
 
 my $Test = Test::Builder->new;
 
+# XXX TODO: We're leaving out FLUFF errors because it complains about non-standard
+# attributes such as "autocomplete" on <form> elements.  There should be a better
+# way to fix this.
+my $lint = HTML::Lint->new( only_types => [HTML::Lint::Error::STRUCTURE,
+                                           HTML::Lint::Error::HELPER] );
+
 =head1 NAME
 
 Jifty::Test::WWW::Mechanize - Subclass of L<Test::WWW::Mechanize> with
@@ -329,9 +336,26 @@
     {
         local $Test::Builder::Level = $Test::Builder::Level;
         $Test::Builder::Level++;
-        html_ok($self->content);
-    }       
-} 
+        Test::HTML::Lint::html_ok( $lint, $self->content, "html_ok for ".$self->uri );
+    }
+}
+
+=head2 html_ok [STRING]
+
+Tests the current C<content> using L<Test::HTML::Lint>.  If passed a string,
+tests against that instead of the current content.
+
+=cut 
+
+sub html_ok {
+    my $self    = shift;
+    my $content = shift || $self->content;
+    {
+        local $Test::Builder::Level = $Test::Builder::Level;
+        $Test::Builder::Level++;
+        Test::HTML::Lint::html_ok( $lint, $content );
+    }
+}
 
 =head2 submit_html_ok 
 
@@ -346,7 +370,7 @@
     {
         local $Test::Builder::Level = $Test::Builder::Level;
         $Test::Builder::Level++;
-        html_ok($self->content);
+        Test::HTML::Lint::html_ok( $lint, $self->content );
     }
 } 
 
@@ -369,7 +393,7 @@
     {
         local $Test::Builder::Level = $Test::Builder::Level;
         $Test::Builder::Level++;
-        html_ok($self->content);
+        Test::HTML::Lint::html_ok( $lint, $self->content );
     }
 } 
 

Modified: jifty/branches/moose/lib/Jifty/Web.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Web.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Web.pm	Sat Aug  5 05:18:48 2006
@@ -24,6 +24,7 @@
 has next_page               => qw( is rw isa Str );
 has request                 => qw( is rw isa Jifty::Request );
 has response                => qw( is rw isa Jifty::Response );
+has force_redirect          => qw( is rw isa Bool );
 has session                 => qw( is rw isa Jifty::Web::Session );
 has temporary_current_user  => qw( is rw isa Object );
 has _current_user           => qw( is rw isa Object );
@@ -66,7 +67,7 @@
     yui/calendar.js
     app.js
     app_behaviour.js
-    css_browser_selector.js                                 
+    css_browser_selector.js
 )]);
 
 =head1 METHODS
@@ -403,7 +404,7 @@
 numerical values running first.
 
 C<ARGUMENTS> are passed to the L<Jifty::Action/new> method.  In
-addition, if the current request (C<$self->request>) contains an
+addition, if the current request (C<< $self->request >>) contains an
 action with a matching moniker, any arguments that are in that
 requested action but not in the C<PARAMHASH> list are set.  This
 implements "sticky fields".
@@ -533,23 +534,31 @@
 Gets or sets the next page for the framework to show.  This is
 normally set during the C<take_action> method or a L<Jifty::Action>
 
+=head3 force_redirect [VALUE]
+
+Gets or sets whether we should force a redirect to C<next_page>, even
+if it's already the current page. You might set this, e.g. to force a
+redirect after a POSTed action.
+
 =head3 redirect_required
 
 Returns true if we need to redirect, now that we've processed all the
-actions.  The current logic just looks to see if a different
-L</next_page> has been set. We probably want to make it possible to
-force a redirect, even if we're redirecting back to the current page
+actions. We need a redirect if either C<next_page> is different from
+the current page, or C<force_redirect> has been set.
 
 =cut
 
 sub redirect_required {
     my $self = shift;
 
-    if ($self->next_page
+    return ( 1 ) if $self->force_redirect;
+
+    if (!$self->request->is_subrequest
+        and $self->next_page
         and ( ( $self->next_page ne $self->request->path )
-            or $self->request->state_variables
-            or $self->{'state_variables'} )
-        )
+              or $self->request->state_variables
+              or $self->{'state_variables'} )
+       )
     {
         return (1);
 
@@ -571,11 +580,11 @@
 
 sub redirect {
     my $self = shift;
-    my $page = shift || $self->next_page;
+    my $page = shift || $self->next_page || $self->request->path;
     $page = Jifty::Web::Form::Clickable->new( url => $page )
       unless ref $page and $page->isa("Jifty::Web::Form::Clickable");
 
-    carp "Don't include GET paramters in the redirect URL -- use a Jifty::Web::Form::Clickable instead.  See L<Jifty::Web/redirect>" if $page->url =~ /\?/;
+    carp "Don't include GET parameters in the redirect URL -- use a Jifty::Web::Form::Clickable instead.  See L<Jifty::Web/redirect>" if $page->url =~ /\?/;
 
     my %overrides = ( @_ );
     $page->parameter($_ => $overrides{$_}) for keys %overrides;
@@ -693,9 +702,6 @@
     if ( defined wantarray ) {
         return $clickable->generate;
     } else {
-        $clickable->state_variable( $_ => $self->{'state_variables'}{$_} )
-            for keys %{ $self->{'state_variables'} };
-
         my $request = Jifty->web->request->clone;
         my %clickable = $clickable->get_parameters;
         $request->argument($_ => $clickable{$_}) for keys %clickable;
@@ -1171,16 +1177,17 @@
 =head3 state_variables
 
 Returns all of the state variables that have been set for the next
-request, as a hash; they have already been prefixed with C<J:V->
+request, as a hash;
+
+N.B. These are B<not> prefixed with C<J:V->, as they were in earlier
+versions of Jifty
 
 =cut
 
-# FIXME: it seems wrong to have an accessor that exposes the
-# representation, so to speak
 sub state_variables {
     my $self = shift;
     my %vars;
-    $vars{ "J:V-" . $_ } = $self->{'state_variables'}->{$_}
+    $vars{$_} = $self->{'state_variables'}->{$_}
         for keys %{ $self->{'state_variables'} };
 
     return %vars;

Modified: jifty/branches/moose/lib/Jifty/Web/Form.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Web/Form.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Web/Form.pm	Sat Aug  5 05:18:48 2006
@@ -11,6 +11,7 @@
 has name            => qw( is rw isa Str );
 has call            => qw( is rw isa Any ); # Str | Jifty::Continuation
 has is_open         => qw( is rw isa Bool );
+has disable_autocomplete => qw( is rw isa Bool );
 no Moose;
 
 =head2 new ARGS
@@ -29,6 +30,11 @@
 All buttons in this form will act as continuation calls for the given
 continuation id.
 
+=item disable_autocomplete
+
+Disable B<browser> autocomplete for this form.  Jifty autocomplete will still
+work.
+
 =back
 
 =cut
@@ -40,6 +46,7 @@
     my %args = (
         name => undef,
         call => undef,
+        disable_autocomplete => undef,
         @_,
     );
 
@@ -70,12 +77,14 @@
     my $self = shift;
     my %args = (name => undef,
                 call => undef,
+                disable_autocomplete => undef,
                 @_);
 
     $self->actions( {} ) ;
     $self->printed_actions( {} ) ;
     $self->name($args{name});
     $self->call($args{call});
+    $self->disable_autocomplete($args{disable_autocomplete});
 }
 
 
@@ -184,8 +193,15 @@
 
     my $form_start = qq!<form method="post" action="$ENV{PATH_INFO}"!;
     $form_start   .= qq! name="@{[ $self->name ]}"! if defined $self->name;
+    $form_start   .= qq! autocomplete="off"! if defined $self->disable_autocomplete;
     $form_start   .= qq! enctype="multipart/form-data" >\n!;
     Jifty->web->out($form_start);
+
+    # Write out state variables early, so that if a form gets
+    # submitted before the page finishes loading, the state vars don't
+    # get lost
+    $self->_preserve_state_variables();
+
     $self->is_open(1);
     '';
 }
@@ -227,7 +243,6 @@
     Jifty->web->out( qq!<div class="hidden">\n! );
 
     $self->_print_registered_actions();
-    $self->_preserve_state_variables();
     $self->_preserve_continuations();
 
     Jifty->web->out( qq!</div>\n! );
@@ -279,7 +294,7 @@
     my %vars = Jifty->web->state_variables;
     for (keys %vars) {
         Jifty->web->out( qq{<input type="hidden" name="}
-                . $_
+                . 'J:V-' . $_
                 . qq{" value="}
                 . $vars{$_}
                 . qq{" />\n} );

Modified: jifty/branches/moose/lib/Jifty/Web/Form/Clickable.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Web/Form/Clickable.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Web/Form/Clickable.pm	Sat Aug  5 05:18:48 2006
@@ -133,41 +133,47 @@
 
 sub new {
     my $class = shift;
-    my $self  = bless {}, $class;
-
     my ($root) = $ENV{'REQUEST_URI'} =~ /([^\?]*)/;
 
-    my %args = (
-        url            => $root,
-        label          => 'Click me!',
-        tooltip        => '',
+    my $self = bless {
         class          => '',
+        label          => 'Click me!',
+        url            => $root,
         escape_label   => 1,
+        tooltip        => '',
         continuation   => Jifty->web->request->continuation,
         submit         => [],
         preserve_state => 0,
+    }, $class;
+
+    my %args = (
         parameters     => {},
         as_button      => 0,
         as_link        => 0,
         @_,
     );
+
     $args{render_as_button} = delete $args{as_button};
     $args{render_as_link}   = delete $args{as_link};
 
     $self->{parameters} = {};
 
+    for my $field ( $self->accessors() ) {
+        $self->$field( $args{$field} ) if exists $args{$field};
+    }
+
     for (qw/continuation call/) {
-        $args{$_} = $args{$_}->id if $args{$_} and ref $args{$_};
+        $self->{$_} = $self->{$_}->id if $self->{$_} and ref $self->{$_};
     }
 
-    if ( $args{submit} ) {
-        $args{submit} = [ $args{submit} ] unless ref $args{submit} eq "ARRAY";
-        $args{submit}
-            = [ map { ref $_ ? $_->moniker : $_ } @{ $args{submit} } ];
+    if ( $self->{submit} ) {
+        $self->{submit} = [ $self->{submit} ] unless ref $self->{submit} eq "ARRAY";
+        $self->{submit}
+            = [ map { ref $_ ? $_->moniker : $_ } @{ $self->{submit} } ];
 
         # If they have an onclick, add any and all submit actions to the onclick's submit list
-        if ($args{onclick}) {
-            $args{onclick} = [ (ref $args{onclick} eq "ARRAY" ? @{ $args{onclick} } : $args{onclick}), map { submit => $_ }, @{$args{submit}} ];
+        if ($self->{onclick}) {
+            $self->{onclick} = [ (ref $self->{onclick} eq "ARRAY" ? @{ $self->{onclick} } : $self->{onclick}), map { submit => $_ }, @{$self->{submit}} ];
         }
     }
 
@@ -179,13 +185,14 @@
     # Anything doing fragment replacement needs to preserve the
     # current state as well
     if ( grep { $self->$_ } $self->handlers or $self->preserve_state ) {
-        for ( Jifty->web->request->state_variables ) {
-            if ( $_->key =~ /^region-(.*?)\.(.*)$/ ) {
-                $self->region_argument( $1, $2 => $_->value );
-            } elsif ( $_->key =~ /^region-(.*)$/ ) {
-                $self->region_fragment( $1, $_->value );
+        my %state_vars = Jifty->web->state_variables;
+        while ( my ($key,  $val) = each %state_vars ) {
+            if ( $key =~ /^region-(.*?)\.(.*)$/ ) {
+                $self->region_argument( $1, $2 => $val );
+            } elsif ( $key =~ /^region-(.*)$/ ) {
+                $self->region_fragment( $1, $val );
             } else {
-                $self->state_variable( $_->key => $_->value );
+                $self->state_variable( $key => $val );
             }
         }
     }

Modified: jifty/branches/moose/lib/Jifty/Web/Form/Element.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Web/Form/Element.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Web/Form/Element.pm	Sat Aug  5 05:18:48 2006
@@ -17,7 +17,7 @@
 set of arguments.
 
 The format of the arguments passed to C<onclick> (or any similar
-method) is a hash reference or string Strings are inserted verbatim.
+method) is a hash reference or string.  Strings are inserted verbatim.
 
 Hash references can take a number of possible keys.  The most
 important is the mode of the fragment replacement, if any; it is

Modified: jifty/branches/moose/lib/Jifty/Web/Form/Field.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Web/Form/Field.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Web/Form/Field.pm	Sat Aug  5 05:18:48 2006
@@ -56,9 +56,12 @@
 
 use Scalar::Util;
 use HTML::Entities;
-use overload '""' => sub { shift->render}, bool => sub { 1 };
 
-=head2 accessors
+# We need the anonymous sub because otherwise the method of the base class is
+# always called, instead of the appropriate overridden method in a child class.
+use overload '""' => sub { shift->render }, bool => sub { 1 };
+
+=head2 new
 
 Lists the accessors that are able to be called from within a call to
 C<new>.  Subclasses should extend this list.
@@ -289,7 +292,8 @@
 
 sub classes {
     my $self = shift;
-    return join(' ', ($self->class||''), ($self->name ? "argument-".$self->name : ''));
+    my $name = $self->name;
+    return join(' ', ($self->class||''), ($name ? "argument-".$name : ''));
 }
 
 

Modified: jifty/branches/moose/lib/Jifty/Web/Form/Link.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Web/Form/Link.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Web/Form/Link.pm	Sat Aug  5 05:18:48 2006
@@ -24,7 +24,10 @@
 
 use base 'Jifty::Web::Form::Element';
 
-# Since we don't inherit from Form::Field, we don't otherwise stringify
+# Since we don't inherit from Form::Field, we don't otherwise stringify.
+# We need the anonymous sub because otherwise the method of the base class is
+# always called, instead of the appropriate overridden method in a possible
+# child class.
 use overload '""' => sub { shift->render }, bool => sub { 1 };
 
 =head2 accessors

Modified: jifty/branches/moose/lib/Jifty/Web/Session.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Web/Session.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Web/Session.pm	Sat Aug  5 05:18:48 2006
@@ -129,9 +129,9 @@
     } else {
         unless ($self->{cache}) {
             my $settings = Jifty::Model::SessionCollection->new;
-            $settings->limit( column => 'session_id', value => $self->id );
-            $settings->limit( column => 'key_type',   value => 'continuation', operator => '!=', entry_aggregator => 'and' );
-            $settings->limit( column => 'key_type',   value => 'session', operator => '!=', entry_aggregator => 'and' );
+            $settings->limit( column => 'session_id', value => $self->id, case_sensitive => '1' );
+            $settings->limit( column => 'key_type',   value => 'continuation', operator => '!=', entry_aggregator => 'and', case_sensitive => '1' );
+            $settings->limit( column => 'key_type',   value => 'session', operator => '!=', entry_aggregator => 'and', case_sensitive => '1' );
             while (my $row = $settings->next) {
                 $self->{cache}{$row->key_type}{$row->data_key} = $row->value;
             }
@@ -254,8 +254,8 @@
     return () unless $self->loaded;
 
     my $conts = Jifty::Model::SessionCollection->new;
-    $conts->limit( column => "key_type",   value => "continuation" );
-    $conts->limit( column => "session_id", value => $self->id );
+    $conts->limit( column => "key_type",   value => "continuation", case_sensitive => '1' );
+    $conts->limit( column => "session_id", value => $self->id, case_sensitive=> '1' );
 
     my %continuations;
     $continuations{ $_->key } = $_->value while $_ = $conts->next;

Modified: jifty/branches/moose/lib/Jifty/Web/Session/ClientSide.pm
==============================================================================
--- jifty/branches/moose/lib/Jifty/Web/Session/ClientSide.pm	(original)
+++ jifty/branches/moose/lib/Jifty/Web/Session/ClientSide.pm	Sat Aug  5 05:18:48 2006
@@ -90,9 +90,23 @@
             : Jifty::Model::Session->new_session_id,
     }
 
-    my ($data) = grep {
-        $_->name eq "JIFTY_DAT_$session_id"
-    } $splitter->join(values %cookies);
+    my $data;
+
+    {
+        local $@;
+        eval {
+            ($data) = grep {
+                $_->name eq "JIFTY_DAT_$session_id"
+            } $splitter->join(values %cookies);
+        };
+
+        if ($@) {
+            # Reassembly of cookie failed -- start a new session
+            $session_id = Jifty::Model::Session->new_session_id;
+            warn $@;
+        }
+    }
+
     if ($data) {
         local $@;
         eval {

Modified: jifty/branches/moose/plugins/ProfileBehaviour/share/web/static/css/behaviour-profile.css
==============================================================================
--- jifty/branches/moose/plugins/ProfileBehaviour/share/web/static/css/behaviour-profile.css	(original)
+++ jifty/branches/moose/plugins/ProfileBehaviour/share/web/static/css/behaviour-profile.css	Sat Aug  5 05:18:48 2006
@@ -1,7 +1,7 @@
 #behaviour-profile-data {
     width: 90%;
     height: 90%;
-    position: absolute;
+    position: fixed;
     left: 5%;
     top: 5%;
     background-color: white;
@@ -61,7 +61,7 @@
 
 
 #show-behaviour-profile {
-    position: absolute;
-    left: 0;
+    position: fixed;
+    left: 0.5em;
     bottom: 0;
 }

Modified: jifty/branches/moose/plugins/ProfileBehaviour/share/web/static/js/behaviour.js
==============================================================================
--- jifty/branches/moose/plugins/ProfileBehaviour/share/web/static/js/behaviour.js	(original)
+++ jifty/branches/moose/plugins/ProfileBehaviour/share/web/static/js/behaviour.js	Sat Aug  5 05:18:48 2006
@@ -204,11 +204,13 @@
 	link.href = '/css/behaviour-profile.css';
 	head.appendChild(link);
 
-	var open = this.createElement('a', null, '[Behaviour profile]');
+	var open = this.createElement('a', null, 'Behaviour profile');
 	open.id = 'show-behaviour-profile';
 	open.href ='#';
 	open.onclick = function() { Behaviour.toggleProfile() }
-	document.getElementsByTagName('body')[0].appendChild(open);
+	var div = this.createElement('div');
+	div.appendChild(open);
+	document.getElementsByTagName('body')[0].appendChild(div);
     },
 
     toggleProfile: function () {

Modified: jifty/branches/moose/plugins/REST/lib/Jifty/Plugin/REST/Dispatcher.pm
==============================================================================
--- jifty/branches/moose/plugins/REST/lib/Jifty/Plugin/REST/Dispatcher.pm	(original)
+++ jifty/branches/moose/plugins/REST/lib/Jifty/Plugin/REST/Dispatcher.pm	Sat Aug  5 05:18:48 2006
@@ -1,5 +1,7 @@
 use strict;
 use warnings;
+no warnings 'utf8';
+no warnings 'once';
 
 package Jifty::Plugin::REST::Dispatcher;
 use CGI qw( start_html end_html ul li a dl dt dd );
@@ -8,11 +10,6 @@
 use Jifty::JSON ();
 use Data::Dumper ();
 
-#before '/=/**' => run {
-#    authenticate_user();
-#    tangent('/login') unless Jifty->web->current_user->id;
-#};
-
 before qr{^ (/=/ .*) \. (js|json|yml|yaml|perl|pl) $}x => run {
     $ENV{HTTP_ACCEPT} = $2;
     dispatch $1;
@@ -42,8 +39,6 @@
 }
 
 sub outs {
-    no warnings 'utf8';
-
     my $prefix = shift;
     my $accept = ($ENV{HTTP_ACCEPT} || '');
     my $apache = Jifty->handler->apache;
@@ -112,14 +107,18 @@
     }
 }
 
-sub model {
-    my $model = shift;
-    return $model if $model->isa('Jifty::Record');
+sub action { resolve($_[0], 'Jifty::Action', Jifty->api->actions) }
+sub model  { resolve($_[0], 'Jifty::Record', Jifty->class_loader->models) }
 
-    $model =~ s/\W+/\\W+/g;
+sub resolve {
+    my $name = shift;
+    my $base = shift;
+    return $name if $name->isa($base);
 
-    foreach my $cls (Jifty->class_loader->models) {
-        return $cls if $cls =~ /$model$/i;
+    $name =~ s/\W+/\\W+/g;
+
+    foreach my $cls (@_) {
+        return $cls if $cls =~ /$name$/i;
     }
 
     abort(404);
@@ -180,15 +179,65 @@
 }
 
 sub list_actions {
-    die "hey list actions";
+    list(['action'], Jifty->api->actions);
 }
 
 sub list_action_params {
-    die "hey action params";
+    my ($action) = action($1) or abort(404);
+    Jifty::Util->require($action) or abort(404);
+    $action = $action->new or abort(404);
+
+    # XXX - Encapsulation?  Someone please think of the encapsulation!
+    no warnings 'redefine';
+    local *Jifty::Web::out = sub { shift; print @_ };
+    local *Jifty::Action::form_field_name = sub { shift; $_[0] };
+    local *Jifty::Action::register = sub { 1 };
+    local *Jifty::Web::Form::Field::Unrendered::render = \&Jifty::Web::Form::Field::render;
+
+    print start_html(-encoding => 'UTF-8', -declare_xml => 1, -title => ref($action));
+    Jifty->web->form->start;
+    for my $name ($action->argument_names) {
+        print $action->form_field($name);
+    }
+    Jifty->web->form->submit( label => 'POST' );
+    Jifty->web->form->end;
+    print end_html;
+    last_rule;
 }
 
 sub run_action {
-    die "run action";
+    my ($action) = action($1) or abort(404);
+    Jifty::Util->require($action) or abort(404);
+    $action = $action->new or abort(404);
+
+    # Jifty->api->is_allowed( $action ) or abort(403);
+
+    my $args = Jifty->web->request->arguments;
+    delete $args->{''};
+
+    $action->argument_values({ %$args });
+    $action->validate;
+
+    local $@;
+    eval { $action->run };
+
+    if ($@ or $action->result->failure) {
+        abort(500);
+    }
+
+    my $rec = $action->{record};
+    if ($rec and $rec->isa('Jifty::Record') and $rec->id) {
+        my $url    = Jifty->web->url(path => join '/', '=', map {
+            Jifty::Web->escape_uri($_)
+        } 'model', ref($rec), 'id', $rec->id);
+        Jifty->handler->apache->header_out('Location' => $url);
+    }
+
+    print start_html(-encoding => 'UTF-8', -declare_xml => 1, -title => 'models'),
+          ul(map { li(html_dump($_)) } $action->result->message, Jifty->web->response->messages),
+          end_html();
+
+    last_rule;
 }
 
 1;

Modified: jifty/branches/moose/share/web/static/js/app_behaviour.js
==============================================================================
--- jifty/branches/moose/share/web/static/js/app_behaviour.js	(original)
+++ jifty/branches/moose/share/web/static/js/app_behaviour.js	Sat Aug  5 05:18:48 2006
@@ -82,6 +82,21 @@
         }
     });
 
+  * Jifty has recently gained built-in support for limited profiling
+    of Behaviours via the ProfileBehaviour plugin (in the Jifty svn
+    tree). After installing the module, add it to your config.yml,
+    using, e.g:
+
+      Plugins:
+        - ProfileBehaviour: {}
+
+    Once you do this, all pages in your application should have a
+    ``Behaviour profile'' link at the bottom left hand corner of the
+    screen. Click it to get a breakdown of how much time your
+    javascript is spending in which behaviours, and whether the time
+    is spent in looking up the CSS Selector you passed (cssQuery
+    time), or in applying the Behaviour function (function time).
+    
 
     ** Footnote **
 

Modified: jifty/branches/moose/share/web/static/js/jifty.js
==============================================================================
--- jifty/branches/moose/share/web/static/js/jifty.js	(original)
+++ jifty/branches/moose/share/web/static/js/jifty.js	Sat Aug  5 05:18:48 2006
@@ -207,9 +207,13 @@
 
     disable_input_fields: function() {
         var disable = function() {
-            // Triggers https://bugzilla.mozilla.org/show_bug.cgi?id=236791
-            arguments[0].blur();
-            arguments[0].disabled = true;
+	    var elt = arguments[0];
+	    // Disabling hidden elements seems to  make IE sad for some reason
+	    if(elt.type != 'hidden') {
+		// Triggers https://bugzilla.mozilla.org/show_bug.cgi?id=236791
+		elt.blur();
+		elt.disabled = true;
+	    }
         };
         this.fields().each(disable);
         this.buttons().each(disable);
@@ -375,10 +379,41 @@
             extras.push(e);
         }
         return extras;
+    },
+
+    /* Someday Jifty may have the concept of "default"
+       buttons.  For now, this clicks the first button that will
+       submit the action associated with the form element.
+     */
+    clickDefaultButton: function(element) {
+        var action = Form.Element.getAction( element );
+        if ( action ) {
+            var buttons = action.buttons();
+            for ( var i = 0; i < buttons.length; i++ ) {
+                var b = buttons[i];
+                if ( Form.Element.buttonActions( b ).indexOf( action.moniker ) >= 0 ) {
+                    b.click();
+                    return true;
+                }
+            }
+        }
+        return false;
+    },
+
+    handleEnter: function(event) {
+        /* Trap "Enter" */
+        if (    event.keyCode == 13
+             && !event.metaKey && !event.altKey && !event.ctrlKey )
+        {
+            if ( Form.Element.clickDefaultButton( event.target ) )
+                event.preventDefault();
+        }
     }
 
 });
 
+JSAN.use("DOM.Events");
+
 // Form elements should AJAX validate if the CSS says so
 Behaviour.register({
     'input.ajaxvalidation, textarea.ajaxvalidation, input.ajaxcanonicalization, textarea.ajaxcanonicalization': function(elt) {
@@ -398,6 +433,19 @@
             buttonToLink(e);
             Element.addClassName( e, 'is_button_as_link' );
         }
+    },
+    "input.date, input.text": function(e) {
+        /* XXX TODO: Figure out how to make our enter handler detect
+           when the autocomplete is active so we can use it on autocompleted
+           fields
+         */
+        if (   !Element.hasClassName( e, "jifty_enter_handler_attached" )
+            && !Element.hasClassName( e, "ajaxautocompletes" ) )
+        {
+            /* Do not use keydown as the event, it will not work as expected in Safari */
+            DOM.Events.addListener( e, "keypress", Form.Element.handleEnter );
+            Element.addClassName( e, "jifty_enter_handler_attached" );
+        }
     }
 });
 
@@ -519,7 +567,7 @@
     // If we don't have XMLHttpRequest, bail and fallback on full-page
     // loads
     if(!Ajax.getTransport()) return true;
-    
+
     show_wait_message();
     var named_args = arguments[0];
     var trigger    = arguments[1];
@@ -815,9 +863,9 @@
     var node = document.createElement('div');
     var node_id = 'result-' + moniker;
     node.setAttribute('id', node_id);
-    node.setAttribute('class', 'popup_notification result-' + status);
+    node.className = "popup_notification result-" + status;
     node.innerHTML = text;
-        
+    
     var wrap1 = document.createElement("div");
     wrap1.setAttribute("class", "dropshadow_wrap1");
     var wrap2 = document.createElement("div");
@@ -828,7 +876,7 @@
     wrap1.appendChild(wrap2);
     wrap2.appendChild(wrap3);
     wrap3.appendChild(node);
-
+    
     if(popup.hasChildNodes()) {
         popup.insertBefore(wrap1, popup.firstChild);
     } else {


More information about the Jifty-commit mailing list