[Jifty-commit] r4210 - in jifty/branches/virtual-models: . lib/Jifty/Action/Record lib/Jifty/Model lib/Jifty/Plugin lib/Jifty/Plugin/AutoReference lib/Jifty/Plugin/LeakTracker lib/Jifty/Plugin/REST lib/Jifty/Script lib/Jifty/Test/WWW lib/Jifty/View/Static lib/Jifty/Web lib/Jifty/Web/Form share/plugins/Jifty/Plugin/AutoReference share/plugins/Jifty/Plugin/AutoReference/web share/plugins/Jifty/Plugin/AutoReference/web/static share/plugins/Jifty/Plugin/AutoReference/web/static/js share/po t/TestApp-Plugin-CompressedCSSandJS t/TestApp-Plugin-CompressedCSSandJS/bin t/TestApp-Plugin-CompressedCSSandJS/doc t/TestApp-Plugin-CompressedCSSandJS/etc t/TestApp-Plugin-CompressedCSSandJS/lib t/TestApp-Plugin-CompressedCSSandJS/lib/TestApp t/TestApp-Plugin-CompressedCSSandJS/lib/TestApp/Plugin t/TestApp-Plugin-CompressedCSSandJS/lib/TestApp/Plugin/CompressedCSSandJS t/TestApp-Plugin-CompressedCSSandJS/log t/TestApp-Plugin-CompressedCSSandJS/share t/TestApp-Plugin-CompressedCSSandJS/share/po t/TestApp-Plugin-CompressedCSSandJS/share/web t/TestApp-Plugin-CompressedCSSandJS/share/web/static t/TestApp-Plugin-CompressedCSSandJS/share/web/templates t/TestApp-Plugin-CompressedCSSandJS/t t/TestApp-Plugin-CompressedCSSandJS/var t/TestApp/t

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Thu Oct 4 09:23:04 EDT 2007


Author: sterling
Date: Thu Oct  4 09:22:57 2007
New Revision: 4210

Added:
   jifty/branches/virtual-models/lib/Jifty/Plugin/AutoReference/
   jifty/branches/virtual-models/lib/Jifty/Plugin/AutoReference.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/AutoReference/Widget.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker/
   jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker/View.pm
   jifty/branches/virtual-models/lib/Jifty/Test/WWW/Declare.pm
   jifty/branches/virtual-models/share/plugins/Jifty/Plugin/AutoReference/
   jifty/branches/virtual-models/share/plugins/Jifty/Plugin/AutoReference/web/
   jifty/branches/virtual-models/share/plugins/Jifty/Plugin/AutoReference/web/static/
   jifty/branches/virtual-models/share/plugins/Jifty/Plugin/AutoReference/web/static/js/
   jifty/branches/virtual-models/share/plugins/Jifty/Plugin/AutoReference/web/static/js/autoreference.js
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/Makefile.PL
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/bin/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/bin/jifty   (contents, props changed)
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/doc/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/etc/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/etc/config.yml
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/lib/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/lib/TestApp/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/lib/TestApp/Plugin/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/lib/TestApp/Plugin/CompressedCSSandJS/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/log/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/share/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/share/po/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/share/web/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/share/web/static/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/share/web/templates/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/t/
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/t/css.t
   jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/var/
   jifty/branches/virtual-models/t/TestApp/t/18-test-www-declare.t
Modified:
   jifty/branches/virtual-models/   (props changed)
   jifty/branches/virtual-models/META.yml
   jifty/branches/virtual-models/Makefile.PL
   jifty/branches/virtual-models/lib/Jifty/Action/Record/Update.pm
   jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm
   jifty/branches/virtual-models/lib/Jifty/Client.pm
   jifty/branches/virtual-models/lib/Jifty/Collection.pm
   jifty/branches/virtual-models/lib/Jifty/Config.pm
   jifty/branches/virtual-models/lib/Jifty/Continuation.pm
   jifty/branches/virtual-models/lib/Jifty/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Everything.pm
   jifty/branches/virtual-models/lib/Jifty/Handler.pm
   jifty/branches/virtual-models/lib/Jifty/Model/Session.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin.pm
   jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm
   jifty/branches/virtual-models/lib/Jifty/Request.pm
   jifty/branches/virtual-models/lib/Jifty/Script/App.pm
   jifty/branches/virtual-models/lib/Jifty/Util.pm
   jifty/branches/virtual-models/lib/Jifty/View/Static/Handler.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Form.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Form/Link.pm
   jifty/branches/virtual-models/lib/Jifty/Web/Session.pm
   jifty/branches/virtual-models/share/po/zh_tw.po

Log:
 r12937 at riddle:  andrew | 2007-10-04 08:21:41 -0500
 Merge down from trunk.
  r12259 at riddle:  andrew | 2007-09-21 14:06:12 -0500
   r12245 at riddle (orig r4130):  sartak | 2007-09-18 15:07:02 -0500
    r42743 at onn:  sartak | 2007-09-17 12:44:04 -0400
    Add a 'now' method to Jifty::DateTime which sets the timezone to the current user's timezone.
    DateTime::now passes time_zone => UTC to Jifty::DateTime::now, which caused it to skip over the currentuser/timezone magic.
   
   r12246 at riddle (orig r4131):  sartak | 2007-09-18 15:07:09 -0500
    r42750 at onn:  sartak | 2007-09-17 12:56:10 -0400
    Add some more tests for Jifty::DateTime in the TestApp
   
   r12247 at riddle (orig r4132):  sartak | 2007-09-18 15:07:13 -0500
    r42755 at onn:  sartak | 2007-09-17 14:26:59 -0400
    Add support for "title" attribute on elements, which shows tooltips
   
   r12248 at riddle (orig r4133):  sartak | 2007-09-18 15:07:18 -0500
    r42785 at onn:  sartak | 2007-09-18 16:06:26 -0400
    Add new LeakDetector plugin. It kinda sorta works :)
   
   r12249 at riddle (orig r4134):  sartak | 2007-09-18 15:27:33 -0500
    r42796 at onn:  sartak | 2007-09-18 16:27:18 -0400
    Some cleanups in LeakDetector
   
   r12250 at riddle (orig r4135):  sartak | 2007-09-18 15:35:55 -0500
    r42798 at onn:  sartak | 2007-09-18 16:35:47 -0400
    More cleanup, hide zero-leak requests by default
   
   r12251 at riddle (orig r4136):  sartak | 2007-09-18 15:46:01 -0500
    r42800 at onn:  sartak | 2007-09-18 16:45:51 -0400
    Include the list of object types leaked in the request report
   
   r12252 at riddle (orig r4137):  sartak | 2007-09-19 12:34:21 -0500
    r42802 at onn:  sartak | 2007-09-18 17:01:23 -0400
    Move files from LeakDetector to LeakTracker (because that's the term Cat uses)
   
   r12253 at riddle (orig r4138):  sartak | 2007-09-19 12:34:24 -0500
    r42803 at onn:  sartak | 2007-09-18 17:02:47 -0400
    Fix package names, add copyright notices
   
   r12254 at riddle (orig r4139):  sartak | 2007-09-19 12:34:29 -0500
    r42805 at onn:  sartak | 2007-09-19 10:51:27 -0400
    Move memleak deps into its own Makefile.PL section
   
   r12255 at riddle (orig r4140):  sartak | 2007-09-19 12:34:36 -0500
    r42812 at onn:  sartak | 2007-09-19 11:02:34 -0400
    POD for LeakTracker's subs
   
   r12256 at riddle (orig r4141):  jesse | 2007-09-19 21:43:18 -0500
    r67430 at pinglin:  jesse | 2007-09-19 22:41:42 -0400
    * Switch to a single call to Module::Pluggable to help improve startup performance.
   
   r12258 at riddle (orig r4143):  jesse | 2007-09-20 11:00:20 -0500
    r67448 at pinglin:  jesse | 2007-09-20 11:59:56 -0400
    * Some parts of that last commit to use only one Module::Pluggable weren't as hot as they appeared to be;
   
  
  r12659 at riddle:  andrew | 2007-09-30 16:46:44 -0500
   r12569 at dynpc145 (orig r4144):  clkao | 2007-09-24 02:54:07 -0500
   allow onsubmit in form to include custom javascript.
   
   r12574 at dynpc145 (orig r4149):  clkao | 2007-09-24 18:29:17 -0500
   In Jifty::Model::Session:
   * Turn session_id, data_key, key_type into case_sensitive,
     so we don't do useless tolower on loading sessions.
   
   * index session_id by default.
   
   r12575 at dynpc145 (orig r4150):  clkao | 2007-09-24 19:09:37 -0500
   Update zh-tw po to include translations for
   authentication::password plugin.
   
   r12576 at dynpc145 (orig r4151):  jesse | 2007-09-24 23:14:36 -0500
    r67563 at pinglin:  jesse | 2007-09-25 00:13:14 -0400
    * Updated the JSON and YAML transports for web service requests to allow complex data structures in actions
   
   r12648 at dynpc145 (orig r4152):  sunnavy | 2007-09-26 07:52:27 -0500
   doc fixes
   r12649 at dynpc145 (orig r4153):  sartak | 2007-09-26 13:57:39 -0500
    r42802 at onn:  sartak | 2007-09-18 17:01:23 -0400
    Move files from LeakDetector to LeakTracker (because that's the term Cat uses)
   
   r12650 at dynpc145 (orig r4154):  sartak | 2007-09-26 13:57:48 -0500
    r42803 at onn:  sartak | 2007-09-18 17:02:47 -0400
    Fix package names, add copyright notices
   
   r12651 at dynpc145 (orig r4155):  sartak | 2007-09-26 13:57:53 -0500
    r42805 at onn:  sartak | 2007-09-19 10:51:27 -0400
    Move memleak deps into its own Makefile.PL section
   
   r12652 at dynpc145 (orig r4156):  sartak | 2007-09-26 13:57:57 -0500
    r42812 at onn:  sartak | 2007-09-19 11:02:34 -0400
    POD for LeakTracker's subs
   
   r12653 at dynpc145 (orig r4157):  sartak | 2007-09-26 13:58:31 -0500
    r43101 at onn:  sartak | 2007-09-26 14:47:29 -0400
    Initial implementation of Jifty::Test::WWW::Declare, with basic tests in TestApp
   
   r12654 at dynpc145 (orig r4158):  sartak | 2007-09-26 13:58:38 -0500
    r43102 at onn:  sartak | 2007-09-26 14:57:22 -0400
    Override T:W:D's get with ours which prepends the server's URL
    Start documentation
   
   r12656 at dynpc145 (orig r4160):  clkao | 2007-09-27 13:50:29 -0500
   New as_string method for Jifty::Web::Form::Link.
   
   r12657 at dynpc145 (orig r4161):  sunnavy | 2007-09-28 09:28:15 -0500
   doc fixes
   r12658 at dynpc145 (orig r4162):  jesse | 2007-09-28 13:44:05 -0500
    r67623 at pinglin:  jesse | 2007-09-28 14:43:47 -0400
    * When loading a web request from a data structure, don't totally throw away the path it was requested at.
   
  
  r12800 at riddle:  andrew | 2007-10-02 12:57:19 -0500
   r12683 at dynpc145 (orig r4165):  jesse | 2007-10-01 14:52:42 -0500
    r27276 at hualien:  jesse | 2007-10-01 15:50:22 -0400
    * Fixes to several of my fixes for Jifty::Request::load_from_data_structure
   
   r12686 at dynpc145 (orig r4168):  alexmv | 2007-10-01 16:45:26 -0500
    r22186 at zoq-fot-pik:  chmrr | 2007-10-01 17:41:16 -0400
     * Force a clone which doesn't have as many bugs
   
   r12688 at dynpc145 (orig r4170):  jesse | 2007-10-01 23:55:17 -0500
    r27295 at hualien:  jesse | 2007-10-02 00:50:39 -0400
    * Rather than helpfully failing to load model classes that have compiletime errors, actually die with the error that caused the class not to load.
   
  
  r12827 at riddle:  andrew | 2007-10-03 13:41:53 -0500
  Use blessed() instead of ref() to keep an if statement from tripping on ->isa().
  r12837 at riddle:  andrew | 2007-10-03 22:57:39 -0500
  Added a new plugin that provides an autocomplete widget specially for record references. Helpful in cases when a select is just be too big to contemplate.
  r12838 at riddle:  andrew | 2007-10-03 22:58:08 -0500
   r12828 at riddle (orig r4200):  jesse | 2007-10-03 12:07:01 -0500
    r27368 at hualien:  jesse | 2007-10-03 13:06:49 -0400
    * Allow users to name their apps in lowercase (as pragmas ?!)
        - Reported by SteveH++
        
   
   r12835 at riddle (orig r4204):  alexmv | 2007-10-03 21:55:38 -0500
    r23400 at zoq-fot-pik:  chmrr | 2007-10-03 22:53:18 -0400
     * Recursively transform content structures
     * Set a flag when we change the method, in case apps care
   
  
  r12840 at riddle:  andrew | 2007-10-03 23:01:09 -0500
  Adding missing JavaScript file and cleaning up a method left-over from testing.
  r12936 at riddle:  andrew | 2007-10-04 08:20:15 -0500
   r12843 at riddle (orig r4208):  clkao | 2007-10-04 02:25:39 -0500
   Fix a bug that after you access a static css file, it breaks the
   compressed css by not actually squishing main.css, hence requests
   static css files under __jifty/css.
   
  
 


Modified: jifty/branches/virtual-models/META.yml
==============================================================================
--- jifty/branches/virtual-models/META.yml	(original)
+++ jifty/branches/virtual-models/META.yml	Thu Oct  4 09:22:57 2007
@@ -27,6 +27,10 @@
   DBD::SQLite: 0
   Devel::Cover: 0
   Devel::EvalContext: 0
+  Devel::Events: 0.02
+  Devel::Events::Generator::Objects: 0
+  Devel::Events::Handler::ObjectTracker: 0
+  Devel::Size: 0
   GD: 0
   GD::Graph: 0
   Image::Info: 0

Modified: jifty/branches/virtual-models/Makefile.PL
==============================================================================
--- jifty/branches/virtual-models/Makefile.PL	(original)
+++ jifty/branches/virtual-models/Makefile.PL	Thu Oct  4 09:22:57 2007
@@ -9,6 +9,7 @@
 requires('Class::Container');
 requires('Class::Data::Inheritable');
 requires('Class::Trigger' => '0.12');
+requires('Clone' => '0.27');
 requires('CGI' => '3.19');
 requires('CGI::Cookie::Splitter');
 requires('Crypt::CBC');
@@ -46,7 +47,7 @@
 requires('Hook::LexWrap');
 requires('IPC::PubSub' => '0.23' );
 requires('IPC::Run3');
-requires('Jifty::DBI' => '0.42' );            # Jifty::DBI::Collection Jifty::DBI::Handle Jifty::DBI::Record::Cachable Jifty::DBI::SchemaGenerator
+requires('Jifty::DBI' => '0.44' );            # Jifty::DBI::Collection Jifty::DBI::Handle Jifty::DBI::Record::Cachable Jifty::DBI::SchemaGenerator
 requires('Locale::Maketext::Extract' => '0.20');
 requires('Locale::Maketext::Lexicon' => '0.60');
 requires('Log::Log4perl' => '1.04');
@@ -74,6 +75,7 @@
 requires('Test::LongString');
 requires('Test::More' => 0.62 ),
 requires('Test::Pod::Coverage'),
+requires('Test::WWW::Declare'),
 requires('Test::WWW::Mechanize' => 1.04 ),
 requires('Test::WWW::Selenium'),
 requires('WWW::Mechanize' => 1.30 ),
@@ -111,7 +113,7 @@
         recommends('Test::HTML::Lint'),
         recommends('Test::MockModule' => '0.05'),
         recommends('Test::MockObject' => '1.07'),
-        recommends('Module::Refresh' => '0.09')
+        recommends('Module::Refresh' => '0.09'),
     ],
     'Development of the jifty framework' => [
         -default => 0,
@@ -159,6 +161,13 @@
         recommends('XML::Simple'),
         recommends('Image::Info'), # for testing
     ],
+    'Memory Leak Plugin' => [
+        -default => 0,
+        recommends('Devel::Events' => '0.02'),
+        recommends('Devel::Events::Handler::ObjectTracker'),
+        recommends('Devel::Events::Generator::Objects'),
+        recommends('Devel::Size'),
+    ],
 );
 
 

Modified: jifty/branches/virtual-models/lib/Jifty/Action/Record/Update.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Action/Record/Update.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Action/Record/Update.pm	Thu Oct  4 09:22:57 2007
@@ -18,6 +18,8 @@
 
 use base qw/Jifty::Action::Record/;
 
+use Scalar::Util qw/ blessed /;
+
 =head1 METHODS
 
 =head2 arguments
@@ -125,7 +127,7 @@
         # Skip fields that have not changed
         my $old = $self->record->$field;
         # XXX TODO: This ignore "by" on columns
-        $old = $old->id if ref($old) and $old->isa( 'Jifty::Record' );
+        $old = $old->id if blessed($old) and $old->isa( 'Jifty::Record' );
     
         # if both the new and old values are defined and equal, we don't want to change em
         # XXX TODO "$old" is a cheap hack to scalarize datetime objects

Modified: jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm	Thu Oct  4 09:22:57 2007
@@ -323,13 +323,16 @@
     Jifty::Module::Pluggable->import(
         # $base goes last so we pull in the view class AFTER the model classes
         search_path => [map { $base . "::" . $_ } ('Model', 'Action', 'Notification', 'Event')],
-        require => 1,
+        require => 0,
         except  => qr/\.#/,
         inner   => 0
     );
     
     # Construct the list of models for the application for later reference
     my %models;
+    for ($self->plugins) {
+        Jifty::Util->require($_);  
+    }
     $models{$_} = 1 for grep {/^($base)::Model::(.*)$/ and not /Collection(?:$||\:\:)/} $self->plugins;
     $self->models(sort keys %models);
 

Modified: jifty/branches/virtual-models/lib/Jifty/Client.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Client.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Client.pm	Thu Oct  4 09:22:57 2007
@@ -100,13 +100,11 @@
     # For each field name given, set the field's value
     for my $arg (keys %args) {
         my $input = $action_form->find_input("J:A:F-$arg-$moniker");
-        unless ($input) {
-            return;
-        } 
+        return unless $input;
         $input->value($args{$arg});
     } 
 
-    # Return the form in case they want to do soemthing with it
+    # Return the form in case they want to do something with it
     return $action_form;
 }
 
@@ -276,7 +274,7 @@
 
 Finds the error span on the current page for the name FIELD in the
 action MONIKER, and returns the text (tags stripped) from it.  (If the
-field can't be found.
+field can't be found, return undef).
 
 =cut
 

Modified: jifty/branches/virtual-models/lib/Jifty/Collection.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Collection.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Collection.pm	Thu Oct  4 09:22:57 2007
@@ -44,9 +44,9 @@
 
 =head2 results_are_readable
 
-If your results from the query is guaranteed to be readable by
+If your results from the query are guaranteed to be readable by
 current_user, you can create the collection with
-C<results_are_readable => 1>.  This is cause check_read_rights to
+C<results_are_readable => 1>.  This causes check_read_rights to
 bypass normal current_user_can checks.
 
 =cut

Modified: jifty/branches/virtual-models/lib/Jifty/Config.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Config.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Config.pm	Thu Oct  4 09:22:57 2007
@@ -16,7 +16,7 @@
 
 This class is automatically loaded during Jifty startup. It contains the configuration information loaded from the F<config.yml> file (generally stored in the F<etc> directory of your application, but see L</load> for the details). This configuration file is stored in L<YAML> format.
 
-This configuration file contains two major sections named "C<framework>" and "C<application>". The framework section contains Jifty-specific configuration options and the application section contains whatever configuration options you want to use with your application. (I.e., if there's any configuration information your application needs to know at startup, this is a good place top put it.)
+This configuration file contains two major sections named "C<framework>" and "C<application>". The framework section contains Jifty-specific configuration options and the application section contains whatever configuration options you want to use with your application. (I.e., if there's any configuration information your application needs to know at startup, this is a good place to put it.)
 
 =cut
 

Modified: jifty/branches/virtual-models/lib/Jifty/Continuation.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Continuation.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Continuation.pm	Thu Oct  4 09:22:57 2007
@@ -41,7 +41,7 @@
 
 Continuations are generally created just before their request would
 take effect, activated by the presence of certain query parameters.
-The rest of the request is saved, its execution to be continued at a
+The rest of the request is saved, its execution is to be continued at a
 later time.
 
 Continuations are run after any actions have run.  When a continuation

Modified: jifty/branches/virtual-models/lib/Jifty/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Dispatcher.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Dispatcher.pm	Thu Oct  4 09:22:57 2007
@@ -422,6 +422,7 @@
     my $stage = shift;
     my $pkg   = ref($self) || $self;
     no strict 'refs';
+    no warnings 'once';
     @{ $pkg . '::RULES_' . $stage };
 }
 

Modified: jifty/branches/virtual-models/lib/Jifty/Everything.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Everything.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Everything.pm	Thu Oct  4 09:22:57 2007
@@ -78,9 +78,7 @@
 use Jifty::Subs::Render ();
 
 use Jifty::Module::Pluggable;
-Jifty::Module::Pluggable->import(search_path => ['Jifty::Web::Form::Field'],
-                          require     => 1,
-                          except      => qr/\.#/);
-__PACKAGE__->plugins;
+#Jifty::Module::Pluggable->import(search_path => ['Jifty::Web::Form::Field'], require     => 1, except      => qr/\.#/);
+#__PACKAGE__->plugins;
 
 1;

Modified: jifty/branches/virtual-models/lib/Jifty/Handler.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Handler.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Handler.pm	Thu Oct  4 09:22:57 2007
@@ -27,6 +27,7 @@
 use base qw/Class::Accessor::Fast/;
 use Module::Refresh ();
 use Jifty::View::Declare::Handler ();
+use Class::Trigger;
 
 BEGIN {
     # Creating a new CGI object breaks FastCGI in all sorts of painful
@@ -191,35 +192,44 @@
         @_
     );
 
-    # Build a new stash for the life of this request
-    $self->stash( {} );
-    local $Jifty::WEB = Jifty::Web->new();
-
-    if ( Jifty->config->framework('DevelMode') ) {
-        Module::Refresh->refresh;
-        Jifty::I18N->refresh;
-    }
+    $self->call_trigger('before_request', $args{cgi});
 
-    Jifty::I18N->get_language_handle;
+    # this is scoped deeper because we want to make sure everything is cleaned
+    # up for the LeakDetector plugin. I tried putting the triggers in the
+    # method (Jifty::Server::handle_request) that calls this, but Jifty::Server
+    # isn't being loaded in time
+    {
+        # Build a new stash for the life of this request
+        $self->stash( {} );
+        local $Jifty::WEB = Jifty::Web->new();
+
+        if ( Jifty->config->framework('DevelMode') ) {
+            Module::Refresh->refresh;
+            Jifty::I18N->refresh;
+        }
 
-    $self->cgi( $args{cgi} );
-    $self->apache( HTML::Mason::FakeApache->new( cgi => $self->cgi ) );
+        Jifty::I18N->get_language_handle;
 
-    Jifty->web->request( Jifty::Request->new()->fill( $self->cgi ) );
-    Jifty->web->response( Jifty::Response->new );
-    Jifty->api->reset;
-    for ( Jifty->plugins ) {
-        $_->new_request;
-    }
-    Jifty->log->debug( "Received request for " . Jifty->web->request->path );
-    Jifty->web->setup_session;
+        $self->cgi( $args{cgi} );
+        $self->apache( HTML::Mason::FakeApache->new( cgi => $self->cgi ) );
 
-    # Return from the continuation if need be
-    Jifty->web->request->return_from_continuation;
-    Jifty->web->session->set_cookie;
-    $self->dispatcher->handle_request();
-    $self->cleanup_request();
+        Jifty->web->request( Jifty::Request->new()->fill( $self->cgi ) );
+        Jifty->web->response( Jifty::Response->new );
+        Jifty->api->reset;
+        for ( Jifty->plugins ) {
+            $_->new_request;
+        }
+        Jifty->log->debug( "Received request for " . Jifty->web->request->path );
+        Jifty->web->setup_session;
+
+        # Return from the continuation if need be
+        Jifty->web->request->return_from_continuation;
+        Jifty->web->session->set_cookie;
+        $self->dispatcher->handle_request();
+        $self->cleanup_request();
+    }
 
+    $self->call_trigger('after_request', $args{cgi});
 }
 
 =head2 cleanup_request

Modified: jifty/branches/virtual-models/lib/Jifty/Model/Session.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Model/Session.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Model/Session.pm	Thu Oct  4 09:22:57 2007
@@ -18,15 +18,15 @@
 use Jifty::DBI::Schema;
 use Jifty::Record schema {
 
-column session_id => type is 'varchar(32)';
-column data_key => type is 'text';
+column session_id => type is 'varchar(32)', is case_sensitive, is indexed;
+column data_key => type is 'text', is case_sensitive;
 column value => type is 'blob',
   filters are 'Jifty::DBI::Filter::Storable';
 column created => type is 'timestamp',
   filters are 'Jifty::DBI::Filter::DateTime';
 column updated => type is 'timestamp',
   filters are 'Jifty::DBI::Filter::DateTime';
-column key_type => type is 'varchar(32)';
+column key_type => type is 'varchar(32)', is case_sensitive;
 };
 
 use base qw( Jifty::Record );

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin.pm	Thu Oct  4 09:22:57 2007
@@ -55,7 +55,6 @@
     my $self = $class->SUPER::new( { @_ });
 
     # Get a classloader set up
-    Jifty::ClassLoader->new(base => $class)->require;
     Jifty::Util->require($class->dispatcher);
 
     # XXX TODO: Add .po path

Added: jifty/branches/virtual-models/lib/Jifty/Plugin/AutoReference.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/AutoReference.pm	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,128 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::AutoReference;
+use base qw/ Jifty::Plugin /;
+
+use Jifty::Plugin::AutoReference::Widget;
+
+=head1 NAME
+
+Jifty::Plugin::AutoReference - a plugin to provide a special reference completer
+
+=head1 SYNOPSIS
+
+Add this to your F<config.yml>:
+
+  Plugins:
+   - AutoReference: {}
+
+and then this to your models:
+
+  use MyApp::Record schema {
+      column employer =>
+          references MyApp::Model::Company,
+          label is 'Employer',
+          is AutoReference,
+          ;
+  };
+
+=head1 DESCRIPTION
+
+Provides a special autocompletion widget for reference columns. See L<Jifty::Plugin::AutoReference::Widget>.
+
+=cut
+
+sub init {
+    Jifty->web->add_javascript(qw/ autoreference.js /);
+}
+
+sub _auto_reference_autocompleter {
+    my ($column, $from) = @_;
+
+    my $reference = $column->refers_to;
+    my $field     = $column->by || 'id';
+
+    my $brief     = $reference->can('_brief_description') ? 
+                        $reference->_brief_description : 'name';
+
+    return sub {
+        my $self  = shift;
+        my $value = shift;
+
+        my $collection = Jifty::Collection->new(
+            record_class => $reference,
+            current_user => $self->current_user,
+        );
+
+        $collection->unlimit;
+        $collection->rows_per_page(20);
+
+        if (length $value) {
+            $collection->limit(
+                column   => $brief,
+                value    => $value,
+                operator => 'MATCHES',
+                entry_aggregator => 'AND',
+            );
+        }
+
+        $collection->limit(
+            column   => $brief,
+            value    => 'NULL',
+            operator => 'IS NOT',
+            entry_aggregator => 'AND',
+        );
+
+        $collection->limit(
+            column   => $brief,
+            value    => '',
+            operator => '!=',
+            entry_aggregator => 'AND',
+        );
+
+        $collection->columns('id', $brief);
+        $collection->order_by(column => $brief);
+
+        Jifty->log->info($collection->build_select_query);
+
+        my @choices;
+        while (my $record = $collection->next) {
+            push @choices, { 
+                label => $record->brief_description.' [id:'.$record->id.']', 
+                value => $record->id,
+            };
+        }
+
+        return @choices;
+    };
+}
+
+sub _auto_reference {
+    my ($column, $from) = @_;
+
+    my $name = $column->name;
+
+    no strict 'refs';
+    *{$from.'::autocomplete_'.$name} 
+        = _auto_reference_autocompleter($column, $from);
+}
+
+use Jifty::DBI::Schema;
+Jifty::DBI::Schema->register_types(
+    AutoReference =>
+        sub { _init_handler is \&_auto_reference, render_as 'Jifty::Plugin::AutoReference::Widget' } );
+
+=head1 AUTHORS
+
+Andrew Sterling Hanenkamp C<< <hanenkamp at cpan.org> >>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 Boomer Consulting, Inc. All Rights Reserved.
+
+This program is free software and may be modified and distributed under the same terms as Perl itself.
+
+=cut
+
+1;

Added: jifty/branches/virtual-models/lib/Jifty/Plugin/AutoReference/Widget.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/AutoReference/Widget.pm	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,76 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::AutoReference::Widget;
+use base qw/ Jifty::Web::Form::Field /;
+
+=head1 NAME
+
+Jifty::Plugin::AutoReference::Widget - an autocomplete widget for references
+
+=head1 SYNOPSIS
+
+  use MyApp::Record schema {
+      column employer =>
+          references MyApp::Model::Company,
+          label is 'Employer',
+          is AutoReference,
+          ;
+  };
+
+=head1 DESCRIPTION
+
+Provides a special autocomplete widget that can be useful when there are too many items for a Select box to be practical.
+
+B<WARNING:> As of this writing, it should be noted that this widget does not degrade gracefully. If you need a widget that operates properly even when JavaScript is unavailable, this widget won't do that job at this time.
+
+=cut
+
+sub render {
+    my $self = shift;
+
+    $self->autocompleter(1);
+    return $self->SUPER::render(@_);
+}
+
+sub render_widget {
+    my $self = shift;
+
+    # Render the shown autocomplete field first
+    my $input_name = $self->input_name;
+    $self->input_name($input_name.'-display');
+    my $element_id = $self->element_id;
+    $self->_element_id($element_id.'-display');
+    my $class = $self->class;
+    $self->class(join ' ', ($class||''), 'text');
+    $self->SUPER::render_widget(@_);
+    $self->input_name($input_name);
+    $self->_element_id($element_id);
+    $self->class($class);
+
+    # Render the hidden value field second
+    $self->type('hidden');
+    $self->SUPER::render_widget(@_);
+    $self->type('text');
+
+    return '';
+}
+
+sub autocomplete_javascript {
+    my $self = shift;
+    return qq{new Jifty.Plugin.AutoReference('@{[$self->element_id]}-display','@{[$self->element_id]}','@{[$self->element_id]}-autocomplete')};
+}
+
+=head1 AUTHORS
+
+Andrew Sterling Hanenkamp C<< <hanenkamp at cpan.org> >>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 Boomer Consulting, Inc. All Rights Reserved.
+
+This program is free software and may be modified and distributed under the same terms as Perl itself.
+
+=cut
+
+1;

Added: jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker.pm	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,138 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::LeakTracker;
+use base qw/Jifty::Plugin Class::Data::Inheritable/;
+use Data::Dumper;
+use Devel::Events::Handler::ObjectTracker;
+use Devel::Events::Generator::Objects;
+use Devel::Size 'total_size';
+
+our $VERSION = 0.01;
+
+__PACKAGE__->mk_accessors(qw(tracker generator));
+our @requests;
+
+my $empty_array = total_size([]);
+
+=head2 init
+
+init installs the triggers needed around each HTTP request
+=cut
+
+sub init {
+    my $self = shift;
+    return if $self->_pre_init;
+
+    Jifty::Handler->add_trigger(
+        before_request => sub { $self->before_request(@_) }
+    );
+
+    Jifty::Handler->add_trigger(
+        after_request  => sub { $self->after_request(@_) }
+    );
+}
+
+=head2 before_request
+
+This trigger sets up Devel::Events to instrument bless and free so it can keep
+track of all the objects created and destroyed in this request
+
+=cut
+
+sub before_request
+{
+    my $self = shift;
+    $self->tracker(Devel::Events::Handler::ObjectTracker->new());
+    $self->generator(
+        Devel::Events::Generator::Objects->new(handler => $self->tracker)
+    );
+
+    $self->generator->enable();
+}
+
+=head2 after_request
+
+This extracts all the data gathered by Devel::Events and puts it into the
+global C<@Jifty::Plugin::LeakTracker::requests> so the LeakTracker dispatcher
+and views can query it to make nice reports
+
+=cut
+
+sub after_request
+{
+    my $self = shift;
+    my $handler = shift;
+    my $cgi = shift;
+
+    $self->generator->disable();
+
+    my $leaked = $self->tracker->live_objects;
+    my @leaks = keys %$leaked;
+
+    # XXX: Devel::Size seems to segfault Jifty at END time
+    my $size = total_size([ @leaks ]) - $empty_array;
+
+    push @requests, {
+        id => 1 + @requests,
+        url => $cgi->url(-absolute=>1,-path_info=>1),
+        size => $size,
+        objects => Dumper($leaked),
+        time => scalar gmtime,
+        leaks => \@leaks,
+    };
+
+    $self->generator(undef);
+    $self->tracker(undef);
+}
+
+=head1 NAME
+
+Jifty::Plugin::LeakTracker
+
+=head1 DESCRIPTION
+
+Memory leak detection and reporting for your Jifty app
+
+=head1 USAGE
+
+Add the following to your site_config.yml
+
+ framework:
+   Plugins:
+     - LeakTracker: {}
+
+This makes the following URLs available:
+
+View the top-level leak report (how much each request has leaked)
+
+    http://your.app/leaks
+
+View the top-level leak report, including zero-leak requests
+
+    http://your.app/leaks/all
+
+View an individual request's detailed leak report (which objects were leaked)
+
+    http://your.app/leaks/3
+
+=head1 WARNING
+
+If you use this in production, be sure to block off 'leaks' from
+non-administrators. The full Data::Dumper output of the objects
+leaked is available, which may of course contain sensitive information.
+
+=head1 SEE ALSO
+
+L<Jifty::Plugin::LeakTracker::View>, L<Jifty::Plugin::LeakTracker::Dispatcher>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 Best Practical Solutions
+
+This is free software and may be modified and distributed under the same terms as Perl itself.
+
+=cut
+
+1;
+

Added: jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker/Dispatcher.pm	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,41 @@
+package Jifty::Plugin::LeakTracker::Dispatcher;
+use warnings;
+use strict;
+
+use Jifty::Dispatcher -base;
+
+# http://your.app/leaks -- display full leak report
+on 'leaks' => run {
+    set 'skip_zero' => 1;
+    show "leaks/all";
+};
+
+# http://your.app/leaks/all -- full leak report with non-leaked requests
+on 'leaks/all' => run {
+    set 'skip_zero' => 0;
+    show "leaks/all";
+};
+
+# http://your.app/leaks/xxx -- display leak report for request ID xxx
+on 'leaks/#' => run {
+    abort(404) if $1 < 1;
+    my $leak = $Jifty::Plugin::LeakTracker::requests[$1 - 1]
+        or abort(404);
+    set leak => $leak;
+    show "leaks/one";
+};
+
+=head1 SEE ALSO
+
+L<Jifty::Plugin::LeakTracker>, L<Jifty::Plugin::LeakTracker::View>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 Best Practical Solutions
+
+This is free software and may be modified and distributed under the same terms as Perl itself.
+
+=cut
+
+1;
+

Added: jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker/View.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/LeakTracker/View.pm	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,108 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::LeakTracker::View;
+use Jifty::View::Declare -base;
+use Scalar::Util 'blessed';
+
+=head1 NAME
+
+Jifty::Plugin::LeakTracker::View - Views for memory leak detection
+
+=head1 TEMPLATES
+
+=head2 leaks/chart
+
+This shows a chart using L<Chart>. It expects to find the arguments in the C<args> parameter, which is setup for it in L<Jifty::Plugin::Chart::Dispatcher>.
+
+This will output a PNG file unless there is an error building the chart.
+
+=cut
+
+template 'leaks/all' => sub {
+    my $skip_zero = get 'skip_zero';
+
+    html {
+        body {
+            h1 { "Leaked Objects" }
+            p {
+                if ($skip_zero) {
+                    a { attr { href => "/leaks/all" }
+                        "Show zero-leak requests" }
+                }
+                else {
+                    a { attr { href => "/leaks" }
+                        "Hide zero-leak requests" }
+                }
+            }
+            hr {}
+
+            table {
+                row {
+                    th { "ID" }
+                    th { "Leaks" }
+                    th { "Bytes leaked" }
+                    th { "Time" }
+                    th { "URL" }
+                };
+
+                for (@Jifty::Plugin::LeakTracker::requests)
+                {
+                    next if $skip_zero && @{$_->{leaks}} == 0;
+
+                    row {
+                        cell { a { attr { href => "leaks/$_->{id}" }
+                                   $_->{id} } }
+
+                        cell { scalar @{$_->{leaks}} }
+                        cell { $_->{size} }
+                        cell { $_->{time} }
+                        cell { $_->{url} }
+                    };
+                }
+            }
+        }
+    }
+};
+
+template 'leaks/one' => sub {
+    my $leak = get 'leak';
+
+    html {
+        body {
+            h1 { "Leaks from Request $leak->{id}" }
+            ul {
+                li { "URL: $leak->{url}" }
+                li { "Time: $leak->{time}" }
+                li { "Objects leaked: " . scalar(@{$leak->{leaks}}) }
+                li { "Total memory leaked: $leak->{size} bytes" }
+            }
+            p { a { attr { href => "/leaks" } "Table of Contents" } }
+            hr {}
+            h2 { "Object types leaked:" }
+            ul {
+                my %seen;
+                for (map { blessed $_ } @{ $leak->{leaks} }) {
+                    next if $seen{$_}++;
+                    li { $_ }
+                }
+            }
+            hr {}
+            pre { $leak->{objects} }
+        }
+    }
+};
+
+=head1 SEE ALSO
+
+L<Jifty::Plugin::LeakTracker>, L<Jifty::Plugin::LeakTracker::Dispatcher>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2007 Best Practical Solutions
+
+This is free software and may be modified and distributed under the same terms as Perl itself.
+
+=cut
+
+1;

Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm	Thu Oct  4 09:22:57 2007
@@ -21,6 +21,7 @@
 
 before POST qr{^ (/=/ .*) ! (DELETE|PUT|GET|POST|OPTIONS|HEAD|TRACE|CONNECT) $}x => run {
     $ENV{REQUEST_METHOD} = $2;
+    $ENV{REST_REWROTE_METHOD} = 1;
     dispatch $1;
 };
 
@@ -167,6 +168,34 @@
     return \%data;
 }
 
+=head2 recurse_object_to_data REF
+
+Takes a reference, and calls C<object_to_data> on it if that is
+meaningful.  If it is an arrayref, or recurses on each element.  If it
+is a hashref, recurses on each value.  Returns the new datastructure.
+
+=cut
+
+sub recurse_object_to_data {
+    my $o = shift;
+    return $o unless ref $o;
+
+    my $updated = object_to_data($o);
+    if ($o ne $updated) {
+        return $updated;
+    } elsif (ref $o eq "ARRAY") {
+        my @a = map {recurse_object_to_data($_)} @{$o};
+        return \@a;
+    } elsif (ref $o eq "HASH") {
+        my %h;
+        $h{$_} = recurse_object_to_data($o->{$_}) for keys %{$o};
+        return \%h;
+    } else {
+        return $o;
+    }
+}
+
+
 =head2 list PREFIX items
 
 Takes a URL prefix and a set of items to render. passes them on.
@@ -719,11 +748,7 @@
     for (keys %{$out->{field_warnings}}) {
         delete $out->{field_warnings}->{$_} unless $out->{field_warnings}->{$_};
     }
-    $out->{content} = $result->content;
-
-    for my $key ( keys %{ $out->{content} } ) {
-        $out->{content}{$key} = object_to_data( $out->{content}{$key} );
-    }
+    $out->{content} = recurse_object_to_data($result->content);
     
     outs(undef, $out);
 

Modified: jifty/branches/virtual-models/lib/Jifty/Request.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Request.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Request.pm	Thu Oct  4 09:22:57 2007
@@ -123,9 +123,9 @@
     # Check it for something appropriate
     if ($data) {
         if ($ct eq "text/x-json") {
-            return $self->from_data_structure(eval{Jifty::JSON::jsonToObj($data)});
+            return $self->from_data_structure(eval{Jifty::JSON::jsonToObj($data)}, $cgi);
         } elsif ($ct eq "text/x-yaml") {
-            return $self->from_data_structure(eval{Jifty::YAML::Load($data)});
+            return $self->from_data_structure(eval{Jifty::YAML::Load($data)}, $cgi);
         }
     }
 
@@ -146,48 +146,71 @@
 sub from_data_structure {
     my $self = shift;
     my $data = shift;
+    my $cgi;
+    $cgi = shift if (@_);
 
-    $self->path(Jifty::Util->canonicalize_path($data->{path} || "/"));
-    $self->just_validating($data->{validating}) if $data->{validating};
+    my $path = $data->{'path'};
+    
+    if ($cgi && ! $path) {
+        $path = URI::Escape::uri_unescape($cgi->path_info);
+        $path =~ s/\?.*//;
+    };
+
+    if (!$path) {
+        $path = '/';
+    }
 
-    if (ref $data->{continuation} eq "HASH") {
-        $self->continuation_id($data->{continuation}{id});
-        $self->continuation_type($data->{continuation}{type} || "parent");
-        $self->continuation_path($data->{continuation}{create});
+    $self->path( Jifty::Util->canonicalize_path( $path));
+    $self->just_validating( $data->{validating} ) if $data->{validating};
+
+    if ( ref $data->{continuation} eq "HASH" ) {
+        $self->continuation_id( $data->{continuation}{id} );
+        $self->continuation_type( $data->{continuation}{type} || "parent" );
+        $self->continuation_path( $data->{continuation}{create} );
     }
 
-    my %actions = %{$data->{actions} || {}};
-    for my $a (values %actions) {
+    my %actions = %{ $data->{actions} || {} };
+    for my $moniker ( keys %actions ) {
+        my $a = $actions{$moniker};
         next unless ref $a eq "HASH";
         my %arguments;
-        for my $arg (keys %{$a->{fields} || {}}) {
-            if (ref $a->{fields}{$arg}) {
-                # Double-fallback exists for historical reasons only;
-                # Jifty applications after July 10th, 2006 should
-                # never generate them.
-                for my $type (qw/doublefallback fallback value/) {
-                    $arguments{$arg} = $a->{fields}{$arg}{$type}
-                      if exists $a->{fields}{$arg}{$type};
+        if ( exists $a->{fields} ) {
+            for my $arg ( keys %{ $a->{fields} || {} } ) {
+                if ( ref $a->{fields}{$arg} ) {
+
+                    # Double-fallback exists for historical reasons only;
+                    # Jifty applications after July 10th, 2006 should
+                    # never generate them.
+                    for my $type (qw/doublefallback fallback value/) {
+                        $arguments{$arg} = $a->{fields}{$arg}{$type}
+                            if exists $a->{fields}{$arg}{$type};
+                    }
+                } else {
+                    $arguments{$arg} = $a->{fields}{$arg};
                 }
-            } else {
-                $arguments{$arg} = $a->{fields}{$arg};
             }
+        } elsif ( exists $a->{params} ) {
+            %arguments = %{$a->{params}};
         }
-        $self->add_action(moniker   => $a->{moniker},
-                          class     => $a->{class},
-                          order     => $a->{order},
-                          active    => exists $a->{active} ? $a->{active} : 1,
-                          arguments => \%arguments,
-                         );
+
+        $self->add_action(
+            moniker => $a->{moniker} || $moniker,
+            class   => $a->{class},
+            order   => $a->{order},
+            active => exists $a->{active} ? $a->{active} : 1,
+            arguments => \%arguments,
+        );
     }
 
-    my %variables = ref $data->{variables} eq "HASH" ? %{$data->{variables}} : ();
-    for my $v (keys %variables) {
-        $self->add_state_variable(key => $v, value => $variables{$v});
+    my %variables
+        = ref $data->{variables} eq "HASH" ? %{ $data->{variables} } : ();
+    for my $v ( keys %variables ) {
+        $self->add_state_variable( key => $v, value => $variables{$v} );
     }
 
-    my %fragments = ref $data->{fragments} eq "HASH" ? %{$data->{fragments}} : ();
-    for my $f (values %fragments) {
+    my %fragments
+        = ref $data->{fragments} eq "HASH" ? %{ $data->{fragments} } : ();
+    for my $f ( values %fragments ) {
         next unless ref $f eq "HASH";
         my $current = $self->add_fragment(
             name      => $f->{name},
@@ -195,12 +218,15 @@
             arguments => $f->{args},
             wrapper   => $f->{wrapper} || 0,
         );
-        while (ref $f->{parent} eq "HASH" and $f = $f->{parent}) {
-            $current = $current->parent(Jifty::Request::Fragment->new({
-                name => $f->{name},
-                path => $f->{path},
-                arguments => $f->{args},
-            }));
+        while ( ref $f->{parent} eq "HASH" and $f = $f->{parent} ) {
+            $current = $current->parent(
+                Jifty::Request::Fragment->new(
+                    {   name      => $f->{name},
+                        path      => $f->{path},
+                        arguments => $f->{args},
+                    }
+                )
+            );
         }
     }
 

Modified: jifty/branches/virtual-models/lib/Jifty/Script/App.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Script/App.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Script/App.pm	Thu Oct  4 09:22:57 2007
@@ -52,7 +52,7 @@
 
     # Turn my-app-name into My::App::Name.
 
-    $self->mod_name (join ("::", map { ucfirst } split (/\-/, $self->prefix)));
+    $self->mod_name (join ("::", split (/\-/, $self->prefix)));
     my $dist = $self->mod_name;
     $self->dist_name($self->prefix);
 

Added: jifty/branches/virtual-models/lib/Jifty/Test/WWW/Declare.pm
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Test/WWW/Declare.pm	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,72 @@
+#!/usr/bin/env perl
+package Jifty::Test::WWW::Declare;
+use strict;
+use warnings;
+use base qw(Exporter);
+BEGIN { require Jifty::Test; require Test::WWW::Declare }
+
+our @EXPORT = qw($server $URL get);
+
+our $server;
+our $URL;
+
+sub import
+{
+    my $class = shift;
+
+    # examine the plan
+    Test::More->import(@_);
+
+    # set up database and other things
+    Jifty::Test->setup($class);
+
+    # export the DSL-ey functions
+    Test::WWW::Declare->export_to_level(2);
+
+    # export $server, $URL, and whatever else J:T:W:D adds
+    # note that this must come AFTER T:W:D->export because we override some
+    # of its functions
+    __PACKAGE__->export_to_level(1);
+
+    # create a server (which will be automatically exported)
+    $server = Jifty::Test->make_server;
+    $URL = $server->started_ok;
+}
+
+=head1 NAME
+
+Jifty::Test::WWW::Declare - Subclass of L<Test::WWW::Declare> with
+extra Jifty features
+
+=head1 SYNOPSIS
+
+    use Jifty::Test::WWW::Declare tests => 2;
+
+    session user => run {
+        flow 'login page' => check {
+            get 'login';
+            content should match qr{Email:};
+            content should match qr{Password:};
+        };
+    };
+
+=head1 FUNCTIONS
+
+=head2 get PATH
+
+Automatically prepend the server's URL to the PATH. You may avoid this by
+specifying the full URL yourself (it checks for C</^http/>).
+
+=cut
+
+sub get
+{
+    my $url = shift;
+    $url = "$URL/$url"
+        unless $url =~ /^http/;
+
+    Test::WWW::Declare::get($url);
+}
+
+1;
+

Modified: jifty/branches/virtual-models/lib/Jifty/Util.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Util.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Util.pm	Thu Oct  4 09:22:57 2007
@@ -243,10 +243,10 @@
     my $error = $@;
     if (my $message = $error) { 
         $message =~ s/ at .*?\n$//;
-        if ($args{'quiet'} and $message =~ /^Can't locate/) {
+        if ($args{'quiet'} and $message =~ /^Can't locate $pkg/) {
             return 0;
         }
-        elsif ( $error !~ /^Can't locate/) {
+        elsif ( $error !~ /^Can't locate $pkg/) {
             die $error;
         } else {
             Jifty->log->error(sprintf("$message at %s line %d\n", (caller(1))[1,2]));

Modified: jifty/branches/virtual-models/lib/Jifty/View/Static/Handler.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/View/Static/Handler.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/View/Static/Handler.pm	Thu Oct  4 09:22:57 2007
@@ -250,10 +250,10 @@
         $apache->send_http_header();
 
         if ($compression eq 'gzip') {
-        undef $/;
-        binmode STDOUT;
-        # XXX TODO: Cache this
-        print STDOUT Compress::Zlib::memGzip(<$fh>);
+            local $/;
+            binmode STDOUT;
+            # XXX TODO: Cache this
+            print STDOUT Compress::Zlib::memGzip(<$fh>);
         } else{
             $apache->send_fd($fh);
         }

Modified: jifty/branches/virtual-models/lib/Jifty/Web/Form.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web/Form.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Form.pm	Thu Oct  4 09:22:57 2007
@@ -5,7 +5,7 @@
 
 use base qw/Jifty::Object Class::Accessor::Fast/;
 
-__PACKAGE__->mk_accessors(qw(actions printed_actions name call is_open disable_autocomplete target submit_to));
+__PACKAGE__->mk_accessors(qw(actions printed_actions name call is_open disable_autocomplete target submit_to onsubmit));
 
 =head1 NAME
 
@@ -200,6 +200,7 @@
     $form_start .= qq! name="@{[ $self->name ]}"! if defined $self->name;
     $form_start .= qq! target="@{[ $self->target ]}"! if defined $self->target;
     $form_start .= qq! autocomplete="off"!  if defined $self->disable_autocomplete;
+    $form_start .= qq! onsubmit="! .Jifty->web->escape( $self->onsubmit ). qq!"!  if defined $self->onsubmit;
     $form_start .= qq! enctype="multipart/form-data" >\n!;
     Jifty->web->out($form_start);
 

Modified: jifty/branches/virtual-models/lib/Jifty/Web/Form/Link.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web/Form/Link.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Form/Link.pm	Thu Oct  4 09:22:57 2007
@@ -86,15 +86,14 @@
 
 =cut
 
-=head2 render
+=head2 as_string
 
-Render the string of the link, including any necessary javascript.
+Returns the string of the link, including any necessary javascript.
 
 =cut
 
-sub render {
+sub as_string {
     my $self = shift;
-
     my $label = $self->label;
     $label = Jifty->web->escape( $label )
         if ( $self->escape_label );
@@ -103,17 +102,38 @@
     $tooltip = Jifty->web->escape( $tooltip )
         if ( defined $tooltip and $self->escape_label );
 
-    Jifty->web->out(qq(<a));
-    Jifty->web->out(qq( id="@{[$self->id]}"))         if $self->id;
-    Jifty->web->out(qq( class="@{[$self->class]}"))   if $self->class;
-    Jifty->web->out(qq( title="@{[$tooltip]}"))       if defined $tooltip;
-    Jifty->web->out(qq( target="@{[$self->target]}")) if $self->target;
-    Jifty->web->out(qq( accesskey="@{[$self->key_binding]}")) if $self->key_binding;
-    Jifty->web->out(qq( href="@{[Jifty->web->escape($self->url)]}"));
-    Jifty->web->out( $self->javascript() );
-    Jifty->web->out(qq(>$label</a>));
-    $self->render_key_binding();
+    my $output = '';
+
+    $output .= (qq(<a));
+    $output .= (qq( id="@{[$self->id]}"))         if $self->id;
+    $output .= (qq( class="@{[$self->class]}"))   if $self->class;
+    $output .= (qq( title="@{[$tooltip]}"))       if defined $tooltip;
+    $output .= (qq( target="@{[$self->target]}")) if $self->target;
+    $output .= (qq( accesskey="@{[$self->key_binding]}")) if $self->key_binding;
+    $output .= (qq( href="@{[Jifty->web->escape($self->url)]}"));
+    $output .= ( $self->javascript() );
+    $output .= (qq(>$label</a>));
+
+    $output .= (
+        '<script type="text/javascript"><!--' .
+        "\n" .
+        Jifty->web->escape($self->key_binding_javascript).
+        "\n" .
+        "--></script>") if $self->key_binding;
+
+    return $output;
+}
+
+=head2 render
+
+Render the string of the link, including any necessary javascript.
+
+=cut
+
+sub render {
+    my $self = shift;
 
+    Jifty->web->out($self->as_string);
     return ('');
 }
 

Modified: jifty/branches/virtual-models/lib/Jifty/Web/Session.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web/Session.pm	(original)
+++ jifty/branches/virtual-models/lib/Jifty/Web/Session.pm	Thu Oct  4 09:22:57 2007
@@ -285,8 +285,8 @@
     return () unless $self->loaded;
 
     my $conts = Jifty::Model::SessionCollection->new;
-    $conts->limit( column => "key_type",   value => "continuation", case_sensitive => '1' );
-    $conts->limit( column => "session_id", value => $self->id, case_sensitive=> '1' );
+    $conts->limit( column => "key_type",   value => "continuation" );
+    $conts->limit( column => "session_id", value => $self->id );
 
     my %continuations;
     $continuations{ $_->key } = $_->value while $_ = $conts->next;

Added: jifty/branches/virtual-models/share/plugins/Jifty/Plugin/AutoReference/web/static/js/autoreference.js
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/share/plugins/Jifty/Plugin/AutoReference/web/static/js/autoreference.js	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,38 @@
+if (!Jifty.Plugin) Jifty.Plugin = {};
+
+Jifty.Plugin.AutoReference = Class.create();
+Object.extend(Object.extend(Jifty.Plugin.AutoReference.prototype, Jifty.Autocompleter.prototype), {
+    initialize: function(field, hiddenField, div) {
+        this.hiddenField = $(hiddenField);
+
+        // Copied from Jifty.Autocompleter.initialize
+        this.field  = $(field);
+        this.action = Form.Element.getAction(this.hiddenField);
+        this.url    = '/__jifty/autocomplete.xml';
+
+        Event.observe(this.field, "focus", this.onFocus.bindAsEventListener(this));
+        this.baseInitialize(this.field, $(div), {
+            minChars: "0",
+            beforeShow: this.beforeShow,
+            beforeHide: this.beforeHide,
+            frequency: 0.1,
+            onShow: this.onShow,
+            onHide: this.onHide,
+            updateElement: this.updateElment,
+            afterUpdateElement: this.afterUpdate
+        });
+    },
+
+    updateElement: function(selection) {
+        var label = Element.collectTextNodes(document.getElementsByClassName('informal', selection)[0]);
+        var value = Element.collectTextNodes(document.getElementsByClassName('hidden_value', selection)[0]);
+
+        this.field.value = label;
+        this.hiddenField.value = value;
+    },
+
+    afterUpdate: function(field, selection) {
+        
+        Form.Element.validate(this.hiddenField);
+    }
+});

Modified: jifty/branches/virtual-models/share/po/zh_tw.po
==============================================================================
--- jifty/branches/virtual-models/share/po/zh_tw.po	(original)
+++ jifty/branches/virtual-models/share/po/zh_tw.po	Thu Oct  4 09:22:57 2007
@@ -54,61 +54,76 @@
 "\n"
 "%2\n"
 
-#: lib/Jifty/Action/Record/Search.pm:125
+#: lib/Jifty/Plugin/Authentication/Facebook/View.pm:43
+msgid ""
+" id is 'facebook_link' };\n"
+"        span { _(\"Login to Facebook now to link it with your current account!\") };\n"
+"        a {{ href is $plugin->get_link_url };\n"
+"            img {{ src is 'http://static.ak.facebook.com/images/devsite/facebook_login.gif', border is '0' "
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Facebook/View.pm:26
+msgid ""
+" id is 'facebook_login' };\n"
+"        span { _(\"Login to Facebook now to get started!\") };\n"
+"        a {{ href is $plugin->get_login_url };\n"
+"            img {{ src is 'http://static.ak.facebook.com/images/devsite/facebook_login.gif', border is '0' "
+msgstr ""
+
+#: lib/Jifty/Action/Record/Search.pm:172
 msgid "!=>< allowed"
 msgstr "可使用 !=>< 符號"
 
-#: lib/Jifty/Notification.pm:94
+#: lib/Jifty/Notification.pm:108 lib/Jifty/Notification.pm:125
 #. ($appname, Jifty->config->framework('AdminEmail')
 msgid "%1 <%2>"
 msgstr "%1 <%2>"
 
-#: lib/Jifty/Action/Record/Search.pm:115
+#: lib/Jifty/Action/Record/Search.pm:143
 #. ($label)
 msgid "%1 after"
 msgstr "%1 晚於"
 
-#: lib/Jifty/Action/Record/Search.pm:116
+#: lib/Jifty/Action/Record/Search.pm:146
 #. ($label)
 msgid "%1 before"
 msgstr "%1 早於"
 
-#: lib/Jifty/Action/Record/Search.pm:112
+#: lib/Jifty/Action/Record/Search.pm:133
 #. ($label)
 msgid "%1 contains"
 msgstr "%1 包含"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:141
-#. ($collection-> count)
+#:
 msgid "%1 entries"
 msgstr "共 %1 筆"
 
-#: lib/Jifty/Action/Record/Search.pm:123
+#: lib/Jifty/Action/Record/Search.pm:166
 #. ($label)
 msgid "%1 greater or equal to"
 msgstr "%1 至少為"
 
-#: lib/Jifty/Action/Record/Search.pm:121
+#: lib/Jifty/Action/Record/Search.pm:160
 #. ($label)
 msgid "%1 greater than"
 msgstr "%1 大於"
 
-#: lib/Jifty/Action/Record/Search.pm:108
+#: lib/Jifty/Action/Record/Search.pm:121
 #. ($label)
 msgid "%1 is not"
 msgstr "%1 不等於"
 
-#: lib/Jifty/Action/Record/Search.pm:113
+#: lib/Jifty/Action/Record/Search.pm:136
 #. ($label)
 msgid "%1 lacks"
 msgstr "%1 不包含"
 
-#: lib/Jifty/Action/Record/Search.pm:124
+#: lib/Jifty/Action/Record/Search.pm:169
 #. ($label)
 msgid "%1 less or equal to"
 msgstr "%1 至多為"
 
-#: lib/Jifty/Action/Record/Search.pm:122
+#: lib/Jifty/Action/Record/Search.pm:163
 #. ($label)
 msgid "%1 less than"
 msgstr "%1 小於"
@@ -124,17 +139,17 @@
 msgid "%1 seconds"
 msgstr "%1 秒"
 
-#: lib/Jifty/Action/Record/Search.pm:117
+#: lib/Jifty/Action/Record/Search.pm:149
 #. ($label)
 msgid "%1 since"
 msgstr "%1 自"
 
-#: lib/Jifty/Action/Record/Search.pm:118
+#: lib/Jifty/Action/Record/Search.pm:152
 #. ($label)
 msgid "%1 until"
 msgstr "%1 至"
 
-#: lib/Jifty/Action/Record/Search.pm:77
+#: lib/Jifty/Action/Record/Search.pm:81
 msgid "(any)"
 msgstr "(不限)"
 
@@ -146,32 +161,32 @@
 msgid "A link to reset your password has been sent to your email account."
 msgstr "重設密碼的通知信已送到您的電郵地址."
 
-#: lib/Jifty/Notification.pm:96
+#: lib/Jifty/Notification.pm:110 lib/Jifty/Notification.pm:127
 #. ($appname)
 msgid "A notification from %1!"
 msgstr "%1 捎來的訊息!"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:443
+#:
 msgid "Actions"
 msgstr "操作"
 
-#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:28
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:33
 msgid "Administration"
 msgstr "管理介面"
 
-#: lib/Jifty/View/Declare/Helpers.pm:363 share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Page.pm:176 share/web/templates/_elements/wrapper:11
 msgid "Administration mode is enabled."
 msgstr "系統管理模式開啟中."
 
-#: lib/Jifty/View/Declare/Helpers.pm:360 share/web/templates/_elements/wrapper:11
+#: lib/Jifty/View/Declare/Page.pm:173 share/web/templates/_elements/wrapper:11
 msgid "Alert"
 msgstr "請注意"
 
-#: lib/Jifty/Action/Record/Create.pm:82
+#: lib/Jifty/Action/Record/Create.pm:92
 msgid "An error occurred.  Try again later"
 msgstr "系統無法執行此項操作, 請稍後再試"
 
-#: lib/Jifty/Action/Record/Search.pm:129
+#: lib/Jifty/Action/Record/Search.pm:177
 msgid "Any field contains"
 msgstr "任意欄位包含"
 
@@ -179,15 +194,15 @@
 msgid "Anyway, the software has logged this error."
 msgstr ""
 
-#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:19
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:53
 msgid "Authentication token"
 msgstr ""
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:489 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:59
+#:
 msgid "Back to the admin console"
 msgstr "回到管理介面"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:461
+#:
 msgid "Back to the application"
 msgstr "回到應用程式"
 
@@ -200,7 +215,7 @@
 msgid "Calendar"
 msgstr "日曆"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:338
+#: lib/Jifty/View/Declare/CRUD.pm:417
 msgid "Cancel"
 msgstr "取消"
 
@@ -212,36 +227,40 @@
 msgid "Close window"
 msgstr "關閉視窗"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:382
+#:
 msgid "Confirm delete?"
 msgstr "是否確定刪除?"
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:97
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:94
 msgid "Confirmation resent."
+msgstr "確認信已寄出."
+
+#: lib/Jifty/Plugin/OpenID/View.pm:65
+msgid "Continue"
 msgstr ""
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:213
+#: lib/Jifty/View/Declare/CRUD.pm:668
 msgid "Create"
 msgstr "建立"
 
-#: lib/Jifty/Action/Record/Create.pm:81
+#: lib/Jifty/Action/Record/Create.pm:91
 #. (ref($record)
 msgid "Create of %1 failed: %2"
 msgstr "無法建立 %1: %2"
 
-#: lib/Jifty/Action/Record/Create.pm:105
+#: lib/Jifty/Action/Record/Create.pm:118
 msgid "Created"
 msgstr "成功建立項目."
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:415
+#:
 msgid "Database Administration"
 msgstr "資料庫管理"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:380
+#: lib/Jifty/View/Declare/CRUD.pm:427
 msgid "Delete"
 msgstr "刪除"
 
-#: lib/Jifty/Action/Record/Delete.pm:76
+#: lib/Jifty/Action/Record/Delete.pm:82
 msgid "Deleted"
 msgstr "成功刪除項目."
 
@@ -249,11 +268,11 @@
 msgid "Dismiss"
 msgstr "關閉"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:458 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:486 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:56
+#:
 msgid "Done?"
 msgstr "設定完畢?"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:388 share/web/templates/__jifty/halo:126 share/web/templates/__jifty/halo:20
+#: lib/Jifty/View/Declare/CRUD.pm:347 share/web/templates/__jifty/halo:126 share/web/templates/__jifty/halo:20
 msgid "Edit"
 msgstr "編輯"
 
@@ -266,23 +285,27 @@
 msgid "Email"
 msgstr "電郵"
 
-#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:33
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:52
 msgid "Email address"
 msgstr "電郵地址"
 
-#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:35
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:54
 msgid "Email address confirmed?"
 msgstr "已確認電郵地址?"
 
-#: lib/Jifty/Action.pm:1158
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:209
+msgid "Fill in your address below, and we'll send out another confirmation email to you. "
+msgstr "請填入您的電郵,我們會再寄一封確認信給您."
+
+#: lib/Jifty/Action.pm:1312
 msgid "Foo cannot contain -, *, +, or ?."
 msgstr ""
 
-#: lib/Jifty/Action.pm:1152
+#: lib/Jifty/Action.pm:1306
 msgid "Foo cannot contain uppercase letters."
 msgstr ""
 
-#: lib/Jifty/Action.pm:1136
+#: lib/Jifty/Action.pm:1285
 msgid "Foo values are always in lowercase."
 msgstr ""
 
@@ -294,6 +317,10 @@
 msgid "Go back home..."
 msgstr "回首頁..."
 
+#: lib/Jifty/Plugin/OpenID/View.pm:35
+msgid "Go for it!"
+msgstr ""
+
 #: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:34
 msgid "Hashed Password"
 msgstr ""
@@ -307,20 +334,26 @@
 msgid "Hello, %1!"
 msgstr "%1 您好!"
 
-#: lib/Jifty/Plugin/SkeletonApp/View.pm:31 share/web/templates/_elements/sidebar:5
-#. ($u->$method()
+#: lib/Jifty/Plugin/Authentication/Facebook/Action/LoginFacebookUser.pm:103
+#. (Jifty->web->current_user->user_object->facebook_name)
+msgid "Hi %1!"
+msgstr ""
+
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:31 share/web/templates/_elements/sidebar:4
+#. ($u->username)
+#. (Jifty->web->current_user->username)
 msgid "Hiya, %1."
 msgstr "%1 您好."
 
-#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:23
+#: lib/Jifty/Plugin/SkeletonApp/Dispatcher.pm:26
 msgid "Home"
 msgstr "首頁"
 
-#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:30
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:49
 msgid "How should I display your name to other users?"
 msgstr "您在本系統的代號"
 
-#: lib/Jifty/Action.pm:1090
+#: lib/Jifty/Action.pm:1212
 msgid "I changed $field for you"
 msgstr ""
 
@@ -328,29 +361,45 @@
 msgid "I'm not sure how this happened."
 msgstr ""
 
+#: lib/Jifty/Plugin/OpenID/View.pm:59
+msgid "If the username provided conflicts with an existing username or contains invalid characters, you will have to give us a new one."
+msgstr ""
+
+#: lib/Jifty/Plugin/OpenID/View.pm:27
+msgid "If you have a Livejournal or other OpenID account, you don't even need to sign up. Just log in."
+msgstr ""
+
 #: lib/Jifty/Plugin/ErrorTemplates/View.pm:62
 msgid "Internal error"
 msgstr ""
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:78 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:79
-msgid "It doesn't look like there's an account by that name."
+#: lib/Jifty/Plugin/OpenID/Action/AuthenticateOpenID.pm:59
+msgid "Invalid OpenID URL.  Please check to make sure it is correct.  (@{[$csr->err]})"
 msgstr ""
 
-#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:89
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:63 lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:75 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:79
+msgid "It doesn't look like there's an account by that name."
+msgstr "沒有這個帳號."
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:106
 msgid "It looks like somebody else is using that address. Is there a chance you have another account?"
 msgstr ""
 
+#: lib/Jifty/Plugin/OpenID/Dispatcher.pm:43
+msgid "It looks like someone is already using that OpenID."
+msgstr ""
+
 #: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:75
 msgid "It looks like you already have an account. Perhaps you want to <a href=\"/login\">log in</a> instead?"
-msgstr ""
+msgstr "您似乎已經有帳號了.按這裡<a href=\"/login\">登入</a>."
 
 #: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:75
 msgid "It looks like you didn't enter the same password into both boxes. Give it another shot?"
-msgstr ""
+msgstr "兩組密碼不同.請再試一次."
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:82
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:79
 msgid "It looks like you're already confirmed."
-msgstr ""
+msgstr "您的帳號已通過認證."
 
 #:
 msgid "Jifty Administrative Console"
@@ -364,27 +413,39 @@
 msgid "Jifty Pod Online"
 msgstr "Jifty 線上 POD 文件"
 
-#: lib/Jifty/View/Declare/Helpers.pm:375 share/web/templates/_elements/wrapper:18
+#: lib/Jifty/View/Declare/Page.pm:194 share/web/templates/_elements/wrapper:18
 msgid "Loading..."
 msgstr "請稍候..."
 
-#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:106
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:132 lib/Jifty/Plugin/Authentication/Password/View.pm:88
 msgid "Login"
 msgstr "登入"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:55
+#: lib/Jifty/Plugin/Authentication/Facebook/View.pm:24
+msgid "Login to Facebook now to get started!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Facebook/View.pm:41
+msgid "Login to Facebook now to link it with your current account!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:82
 msgid "Login with a password"
 msgstr "使用密碼登入"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:40
+#: lib/Jifty/Plugin/OpenID/View.pm:17
+msgid "Login with your OpenID"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:57
 msgid "Login!"
 msgstr "登入!"
 
-#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:123
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:151
 msgid "Logout"
 msgstr "登出"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:63
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:90
 msgid "Lost your password?"
 msgstr "忘記密碼了?"
 
@@ -396,47 +457,50 @@
 msgid "Manage records:"
 msgstr "管理記錄:"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:46 lib/Jifty/Plugin/AdminUI/View-not-yet.pm:473
-#. ($object_type)
-msgid "Manage records: [_1]"
-msgstr ""
-
 #: share/web/templates/__jifty/error/mason_internal_error:1
 msgid "Mason error"
 msgstr "Mason 系統錯誤"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:429
+#:
 msgid "Models"
 msgstr "模型"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:81
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:114
 msgid "New password"
 msgstr "新的密碼"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:172
+#: lib/Jifty/View/Declare/CRUD.pm:628
 msgid "Next Page"
 msgstr "下一頁"
 
-#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:29
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:48
 msgid "Nickname"
 msgstr "暱稱"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:52
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:79
 msgid "No account yet? It's quick and easy. "
 msgstr "還沒有註冊帳號嗎? "
 
-#: lib/Jifty/Action/Record/Search.pm:130
+#: lib/Jifty/Action/Record/Search.pm:178
 msgid "No field contains"
 msgstr "沒有欄位包含"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:139
+#:
 msgid "No items found"
 msgstr "未找到記錄"
 
-#: lib/Jifty/Web.pm:302
+#: lib/Jifty/View/Declare/CRUD.pm:547
+msgid "No items found."
+msgstr ""
+
+#: lib/Jifty/Web.pm:307
 msgid "No request to handle"
 msgstr "沒有可處理的要求"
 
+#: lib/Jifty/Plugin/UUID/Widget.pm:37
+msgid "No value yet"
+msgstr ""
+
 #:
 msgid "Online Documentation"
 msgstr "線上文件"
@@ -445,7 +509,19 @@
 msgid "Online docs"
 msgstr "線上文件"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:134
+#: lib/Jifty/Plugin/OpenID/Action/AuthenticateOpenID.pm:27
+msgid "OpenID URL"
+msgstr ""
+
+#: lib/Jifty/Plugin/OpenID/Action/VerifyOpenID.pm:54
+msgid "OpenID verification failed.  It looks like you cancelled the OpenID verification request."
+msgstr ""
+
+#: lib/Jifty/Plugin/OpenID/Action/VerifyOpenID.pm:63
+msgid "OpenID verification failed: "
+msgstr ""
+
+#: lib/Jifty/View/Declare/CRUD.pm:595
 #. ($page, $collection->pager->last_page)
 msgid "Page %1 of %2"
 msgstr "第 %1 頁, 共 %2 頁"
@@ -458,15 +534,15 @@
 msgid "Parent"
 msgstr "上層元件"
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:29 lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:32 lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:26
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:29 lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:32 lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:59
 msgid "Password"
 msgstr "密碼"
 
-#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:88
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:134
 msgid "Passwords need to be at least six characters long"
 msgstr "密碼至少需要有六個字"
 
-#: lib/Jifty/Record.pm:272 lib/Jifty/Record.pm:351 lib/Jifty/Record.pm:70
+#: lib/Jifty/Record.pm:485 lib/Jifty/Record.pm:564 lib/Jifty/Record.pm:71
 msgid "Permission denied"
 msgstr "權限不足."
 
@@ -474,10 +550,14 @@
 msgid "Please email us!"
 msgstr "請寫信通知我們!"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:163
+#: lib/Jifty/View/Declare/CRUD.pm:617
 msgid "Previous Page"
 msgstr "上一頁"
 
+#: lib/Jifty/View/Declare/CRUD.pm:430
+msgid "Really delete?"
+msgstr ""
+
 #: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:65
 msgid "Really, really sorry."
 msgstr "十二萬分抱歉."
@@ -495,11 +575,11 @@
 msgid "Rendered in %1s"
 msgstr "頁面繪製時間: %1 秒"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:78
+#:
 msgid "Reset lost password"
 msgstr "重設密碼"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:53
+#:
 msgid "Run the action"
 msgstr "執行動作"
 
@@ -507,7 +587,7 @@
 msgid "SQL Statements"
 msgstr "SQL 陳述式"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:327
+#: lib/Jifty/View/Declare/CRUD.pm:408
 msgid "Save"
 msgstr "儲存"
 
@@ -515,31 +595,35 @@
 msgid "Schema"
 msgstr "綱要"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:304
+#: lib/Jifty/View/Declare/CRUD.pm:298
 msgid "Search"
 msgstr "搜尋"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:119
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:150 lib/Jifty/Plugin/Authentication/Password/View.pm:180
 msgid "Send"
 msgstr "寄出"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:97
+#:
 msgid "Send a link to reset your password"
 msgstr "寄送重設密碼的鏈結"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:109 lib/Jifty/Plugin/Authentication/Password/View.pm:114
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:175
 msgid "Send a password reminder"
 msgstr "重設密碼"
 
-#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:111
+#: lib/Jifty/Plugin/Feedback/View.pm:21
+msgid "Send us feedback!"
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Dispatcher.pm:137 lib/Jifty/Plugin/Authentication/Password/View.pm:42 lib/Jifty/Plugin/Authentication/Password/View.pm:47
 msgid "Sign up"
 msgstr "註冊"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:53
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:80
 msgid "Sign up for an account!"
 msgstr "現在就註冊!"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:30 lib/Jifty/Plugin/Authentication/Password/View.pm:35
+#:
 msgid "Signup"
 msgstr "註冊"
 
@@ -560,32 +644,45 @@
 msgid "Sorry about this."
 msgstr "非常抱歉."
 
+#: lib/Jifty/Plugin/Authentication/Facebook/Action/LoginFacebookUser.pm:62
+msgid "Sorry, something weird happened (we couldn't create a user for you).  Try again later."
+msgstr ""
+
 #:
 msgid "Table of Contents"
 msgstr "目錄"
 
-#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:82
+#: lib/Jifty/Plugin/Feedback/View.pm:23
+#. (Jifty->config->framework('ApplicationName')
+msgid "Tell us what's good, what's bad, and what else you want %1 to do!"
+msgstr ""
+
+#: lib/Jifty/Plugin/User/Mixin/Model/User.pm:99
 #. ($new_email)
 msgid "That %1 doesn't look like an email address."
 msgstr ""
 
-#: lib/Jifty/Action.pm:878
+#: lib/Jifty/Action.pm:975
 msgid "That doesn't look like a correct value"
 msgstr "欄位格式錯誤."
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:71 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:72 lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:70
+#: lib/Jifty/Plugin/Authentication/Password/Action/SendAccountConfirmation.pm:68 lib/Jifty/Plugin/Authentication/Password/Action/SendPasswordReminder.pm:72 lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:70
 msgid "That doesn't look like an email address."
 msgstr ""
 
-#: lib/Jifty/Action/Record.pm:249
+#: lib/Jifty/Action/Record.pm:300
 msgid "That doesn't look right, but I don't know why"
 msgstr "欄位內容錯誤."
 
-#: lib/Jifty/Action/Record.pm:181
+#: lib/Jifty/Plugin/OpenID/Dispatcher.pm:48
+msgid "The OpenID '$openid' has been linked to your account."
+msgstr ""
+
+#: lib/Jifty/Action/Record.pm:205
 msgid "The passwords you typed didn't match each other"
 msgstr "兩組密碼不符合."
 
-#: lib/Jifty/Web.pm:365
+#: lib/Jifty/Web.pm:428
 msgid "There was an error completing the request.  Please try again later."
 msgstr "系統執行錯誤, 請稍候再試."
 
@@ -597,15 +694,15 @@
 msgid "There's a pretty good chance that error message doesn't mean anything to you, but we'd rather you have a little bit of information about what went wrong than nothing. We've logged this error, so we know we need to write something friendly explaining just what happened and how to fix it."
 msgstr ""
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:419
+#:
 msgid "This console lets you manage the records in your Jifty database. Below, you should see a list of all your database tables. Feel free to go through and add, delete or modify records."
 msgstr "您可利用此介面來管理資料庫的內容. 請點選表格名稱, 進行增刪及編輯."
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:425
+#:
 msgid "To disable this administrative console, add \"AdminMode: 0\" under the \"framework:\" settings in the config file (etc/config.yml)."
 msgstr "如欲停用管理介面, 請在設定檔 (etc/config.yml) 的 \"framework:\" 設定內加上 \"AdminMode: 0\" 即可."
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:127
+#: lib/Jifty/View/Declare/CRUD.pm:515
 msgid "Toggle search"
 msgstr "切換搜尋畫面"
 
@@ -621,7 +718,7 @@
 msgid "Type that again?"
 msgstr "請再輸入一次"
 
-#: lib/Jifty/Action/Record/Update.pm:156
+#: lib/Jifty/Action/Record/Update.pm:168
 msgid "Updated"
 msgstr "成功更新項目."
 
@@ -633,6 +730,10 @@
 msgid "W00t"
 msgstr "喔耶"
 
+#: lib/Jifty/Plugin/OpenID/View.pm:53
+msgid "We need you to set a username or quickly check the one associated with your OpenID. Your username is what other people will see when you ask questions or make suggestions"
+msgstr ""
+
 #: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:114
 msgid "We've sent a confirmation message to your email box."
 msgstr "系統已將確認信寄送到您的電郵信箱."
@@ -642,7 +743,11 @@
 msgid "Welcome %1 to the %2"
 msgstr "歡迎 %1 蒞臨 %2"
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:181
+#: lib/Jifty/Plugin/OpenID/Dispatcher.pm:64
+msgid "Welcome back, "
+msgstr ""
+
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:182
 #. ($user->name)
 msgid "Welcome back, %1."
 msgstr "歡迎回來, %1."
@@ -652,20 +757,27 @@
 msgid "Welcome to %1!"
 msgstr "歡迎光臨 %1!"
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:113
+#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:57 lib/Jifty/Plugin/Authentication/Password/Action/Signup.pm:113
 #. (Jifty->config->framework('ApplicationName')
 msgid "Welcome to %1, %2."
 msgstr "歡迎光臨 %1, %2!"
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/ConfirmEmail.pm:57
-#. (Jifty->config->framework('ApplicationName')
+#:
 msgid "Welcome to %1, %2. "
 msgstr "歡迎光臨 %1, %2. "
 
-#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:1
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:76 share/web/templates/index.html:1
 msgid "Welcome to your new Jifty application"
 msgstr "歡迎光臨您嶄新的 Jifty 應用程式"
 
+#: lib/Jifty/Plugin/OpenID/Action/CreateOpenIDUser.pm:104
+msgid "Welcome, "
+msgstr ""
+
+#: lib/Jifty/Plugin/OpenID/View.pm:42
+msgid "You already logged in."
+msgstr ""
+
 #: lib/Jifty/Plugin/Authentication/Password/Action/ResetLostPassword.pm:63
 msgid "You don't exist."
 msgstr "您不存在."
@@ -682,39 +794,44 @@
 msgid "You have already confirmed your account."
 msgstr "您已經確認過這個帳號了."
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:98
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:146
 msgid "You lost your password. A link to reset it will be sent to the following email address:"
 msgstr ""
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:115
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:176
 msgid "You lost your password. A reminder will be send to the following mail:"
 msgstr ""
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:152
-msgid "You may have mistyped your email address or password. Give it another shot."
+#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:146 lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:152
+msgid "You may have mistyped your email or password. Give it another shot."
 msgstr ""
 
-#: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:146
-msgid "You may have mistyped your email or password. Give it another shot."
+#: lib/Jifty/Plugin/Authentication/Facebook/Action/LinkFacebookUser.pm:40
+msgid "You must be logged in to link your user to your Facebook account."
 msgstr ""
 
-#: lib/Jifty/Action.pm:865
+#: lib/Jifty/Action.pm:962
 msgid "You need to fill in this field"
 msgstr "此欄位不能留空."
 
-#: lib/Jifty/Plugin/SkeletonApp/View.pm:75 share/web/templates/index.html:3
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:76 share/web/templates/index.html:3
 #. ('http://hdl.loc.gov/loc.pnp/cph.3c13461')
 msgid "You said you wanted a pony. (Source %1)"
 msgstr "您可不正是想要一匹小馬嗎? (參見 %1)"
 
-#: lib/Jifty/Plugin/Authentication/Password/View.pm:69
+#: lib/Jifty/Plugin/Authentication/Password/View.pm:96
 msgid "You're already logged in."
 msgstr "您已經登入了."
 
-#: lib/Jifty/Plugin/SkeletonApp/View.pm:34 share/web/templates/_elements/sidebar:7
+#: lib/Jifty/Plugin/SkeletonApp/View.pm:34 share/web/templates/_elements/sidebar:6
 msgid "You're not currently signed in."
 msgstr "您目前尚未登入."
 
+#: lib/Jifty/Plugin/Authentication/Facebook/Action/LinkFacebookUser.pm:72
+#. (Jifty->web->current_user->user_object->facebook_name)
+msgid "Your account has been successfully linked to your Facebook user %1!"
+msgstr ""
+
 #: lib/Jifty/Plugin/Authentication/Password/Action/Login.pm:38
 msgid "Your browser can remember your login for you"
 msgstr "下次開啟瀏覽器時, 是否保留您的登入狀態?"
@@ -723,15 +840,15 @@
 msgid "Your password has been reset.  Welcome back."
 msgstr "成功重設您的密碼. 歡迎回來."
 
-#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:28
+#: lib/Jifty/Plugin/Authentication/Password/Mixin/Model/User.pm:61
 msgid "Your password should be at least six characters"
 msgstr "您的密碼必須至少有六個字"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:246
+#:
 msgid "asc"
 msgstr "遞增"
 
-#: lib/Jifty/Plugin/AdminUI/View-not-yet.pm:264
+#:
 msgid "desc"
 msgstr "遞減"
 
@@ -755,6 +872,6 @@
 msgid "type your password again"
 msgstr "請再次鍵入您的密碼"
 
-#: lib/Jifty/Action.pm:1050
+#: lib/Jifty/Action.pm:1172
 msgid "warning"
 msgstr ""

Added: jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/Makefile.PL
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/Makefile.PL	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,7 @@
+use inc::Module::Install;
+
+name        'TestApp::Plugin::JQuery';
+version     '0.01';
+requires    'Jifty' => '0.70129';
+
+WriteAll;

Added: jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/bin/jifty
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/bin/jifty	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,11 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+use File::Basename qw(dirname); 
+use UNIVERSAL::require;
+
+use Jifty;
+use Jifty::Script;
+
+local $SIG{INT} = sub { warn "Stopped\n"; exit; };
+Jifty::Script->dispatch();

Added: jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/etc/config.yml
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/etc/config.yml	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,55 @@
+--- 
+framework: 
+  AdminMode: 1
+  ApplicationClass: TestApp::Plugin::CompressedCSSandJS
+  ApplicationName: TestApp::Plugin::CompressedCSSandJS
+  ApplicationUUID: DC3B58E4-4F3C-11DC-9ECB-E5DB6F105773
+  ConfigFileVersion: 2
+  Database: 
+    CheckSchema: 1
+    Database: testapp_plugin_singlepage
+    Driver: SQLite
+    Host: localhost
+    Password: ''
+    RecordBaseClass: Jifty::DBI::Record::Cachable
+    RecordUUIDs: active
+    User: ''
+    Version: 0.0.1
+  DevelMode: 1
+  L10N: 
+    PoDir: share/po
+  LogLevel: DEBUG
+  Mailer: Sendmail
+  MailerArgs: []
+
+  Plugins: 
+    - LetMe: {}
+    - SkeletonApp: {}
+    - REST: {}
+    - Halo: {}
+    - ErrorTemplates: {}
+    - OnlineDocs: {}
+    - CompressedCSSandJS: {}
+    - AdminUI: {}
+    - User: {}
+    - CompressedCSSandJS: {}
+
+  PubSub: 
+    Backend: Memcached
+    Enable: ~
+  SkipAccessControl: 0
+  TemplateClass: TestApp::Plugin::CompressedCSSandJS::View
+  Web: 
+    BaseURL: http://localhost
+    DataDir: var/mason
+    Globals: []
+
+    MasonConfig: 
+      autoflush: 0
+      default_escape_flags: h
+      error_format: text
+      error_mode: fatal
+    Port: 8888
+    ServeStaticFiles: 1
+    StaticRoot: share/web/static
+    TemplateRoot: share/web/templates

Added: jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/t/css.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp-Plugin-CompressedCSSandJS/t/css.t	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,20 @@
+use strict;
+use warnings;
+use lib 't/lib';
+use Jifty::SubTest;
+use Jifty::Test tests => 7;
+use Jifty::Test::WWW::Mechanize;
+
+my $server  = Jifty::Test->make_server;
+my $URL = $server->started_ok;
+my $mech = Jifty::Test::WWW::Mechanize->new();
+
+$mech->get_ok("$URL/static/css/main.css","Got main.css");
+$mech->content_contains('@import "combobox.css"');
+$mech->get_ok("$URL");
+ok($mech->content =~ m{<link rel="stylesheet" type="text/css" href="/__jifty/css/(.*)" /});
+my $css_file = $1;
+
+$mech->get_ok("$URL/__jifty/css/$css_file");
+$mech->content_contains('End of combobox.css', 'squished');
+

Added: jifty/branches/virtual-models/t/TestApp/t/18-test-www-declare.t
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/t/TestApp/t/18-test-www-declare.t	Thu Oct  4 09:22:57 2007
@@ -0,0 +1,23 @@
+#!/usr/bin/env perl
+use warnings;
+use strict;
+
+use lib 't/lib';
+use Jifty::SubTest;
+
+use Jifty::Test::WWW::Declare tests => 2;
+
+# this is a duplication of t/TestApp/t/17-template-region-internal-redirect.t
+# if the user sees failures here, then he either saw failures in t/17 OR
+# J:T:W:D is broken
+
+session user => run {
+    flow "region with internal redirects" => check {
+        get "region-with-internal-redirect";
+        content should match qr/redirected ok/;
+        content should match qr/other region/;
+        content should match qr/still going/;
+        content shouldnt match qr/sorry/;
+    };
+};
+


More information about the Jifty-commit mailing list