[Jifty-commit] r3405 - in jifty/trunk: . lib/Jifty lib/Jifty/Plugin
lib/Jifty/Plugin/SinglePage lib/Jifty/Web share/web/static/js
share/web/templates/__jifty/webservices
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Fri Jun 8 16:46:17 EDT 2007
Author: clkao
Date: Fri Jun 8 16:46:17 2007
New Revision: 3405
Added:
jifty/trunk/lib/Jifty/Plugin/SinglePage/
jifty/trunk/lib/Jifty/Plugin/SinglePage/Dispatcher.pm
Modified:
jifty/trunk/ (props changed)
jifty/trunk/lib/Jifty/Continuation.pm
jifty/trunk/lib/Jifty/Dispatcher.pm
jifty/trunk/lib/Jifty/Plugin/SinglePage.pm
jifty/trunk/lib/Jifty/Request.pm
jifty/trunk/lib/Jifty/Web.pm
jifty/trunk/lib/Jifty/Web/Form.pm
jifty/trunk/lib/Jifty/Web/Form/Clickable.pm
jifty/trunk/lib/Jifty/Web/Form/Element.pm
jifty/trunk/lib/Jifty/Web/PageRegion.pm
jifty/trunk/share/web/static/js/jifty.js
jifty/trunk/share/web/templates/__jifty/webservices/xml
Log:
Merge from fragcont branch to include minimum support of continuation in
webservices requests to make SinglePage work.
r18076 at ubuntu (orig r3386): clkao | 2007-06-07 15:59:34 -0400
branch for supporting fragment calls with continuation.
r18077 at ubuntu (orig r3387): clkao | 2007-06-07 16:05:17 -0400
first cut of continuation serialization & calling with webservices.
r18078 at ubuntu (orig r3388): clkao | 2007-06-07 17:35:03 -0400
Have call continuation work on webservices, but not return properly yet.
r18080 at ubuntu (orig r3390): clkao | 2007-06-07 18:11:09 -0400
keeping __page's state won't get us anywhere...
r18093 at ubuntu (orig r3392): clkao | 2007-06-07 19:19:35 -0400
ditto for other implicit __page fragment to ignore region state.
r18094 at ubuntu (orig r3393): clkao | 2007-06-07 19:20:11 -0400
fallback value being array makes the crud action on server side sad.
r18110 at ubuntu (orig r3397): clkao | 2007-06-08 02:43:23 -0400
Support redirect to external url in webservices.
r18111 at ubuntu (orig r3398): clkao | 2007-06-08 03:01:27 -0400
Prevent infinite loop when unable to render mason_internal_error.
r18112 at ubuntu (orig r3399): clkao | 2007-06-08 03:15:31 -0400
Handle J:C internal redirect, which is used by error raised by dispatcher.
r18118 at ubuntu (orig r3401): clkao | 2007-06-08 13:00:58 -0400
* If we are doing external redirect, supress fragment replacement.
* fix refresh_self in submit so on failed action response we get
__page refreshed that is like page reload.
r18119 at ubuntu (orig r3402): clkao | 2007-06-08 13:13:54 -0400
On internal redirect, reset nav and page_nav.
r18120 at ubuntu (orig r3403): clkao | 2007-06-08 15:42:44 -0400
There's no point removing url in clickable and put in _orig_url anymore,
which also happens to break redirect($clickable).
r18125 at ubuntu (orig r3404): clkao | 2007-06-08 16:42:32 -0400
misc cleanups.
Modified: jifty/trunk/lib/Jifty/Continuation.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Continuation.pm (original)
+++ jifty/trunk/lib/Jifty/Continuation.pm Fri Jun 8 16:46:17 2007
@@ -156,6 +156,18 @@
sub call {
my $self = shift;
+ Jifty->log->debug("Redirect to @{[$self->request->path]} via continuation");
+ if (Jifty->web->request->argument('_webservice_redirect')) {
+ # for continuation - perform internal redirect under webservices.
+ Jifty->web->request->remove_state_variable('region-__page');
+ Jifty->web->request->add_fragment(
+ name => '__page',
+ path => $self->request->path,
+ arguments => {},
+ wrapper => 0
+ );
+ return;
+ }
# If we needed to fix up the path (it contains invalid
# characters) then warn, because this may cause infinite
# redirects
@@ -189,6 +201,7 @@
# Redirect to right page if we're not there already
Jifty->web->_redirect($next->request->path . "?J:RETURN=" . $next->id);
+ return 1;
}
=head2 return
Modified: jifty/trunk/lib/Jifty/Dispatcher.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Dispatcher.pm (original)
+++ jifty/trunk/lib/Jifty/Dispatcher.pm Fri Jun 8 16:46:17 2007
@@ -736,7 +736,7 @@
$self->_abort;
}
-sub _abort { die "ABORT" }
+sub _abort { Carp::croak "ABORT" }
=head2 _do_show [PATH]
@@ -1149,6 +1149,7 @@
my $self = shift;
my $template = shift;
my $showed = 0;
+# local $@;
eval {
foreach my $handler ( Jifty->handler->view_handlers ) {
if ( Jifty->handler->view($handler)->template_exists($template) ) {
@@ -1166,8 +1167,13 @@
my $err = $@;
# Handle parse errors
+ $self->log->fatal("view class error: $err") if $err;
if ( $err and not eval { $err->isa('HTML::Mason::Exception::Abort') } ) {
-
+ if ($template eq '/__jifty/error/mason_internal_error') {
+ $self->log->debug("can't render internal_error: $err");
+ $self->_abort;
+ return;
+ }
# Save the request away, and redirect to an error page
Jifty->web->response->error($err);
my $c = Jifty::Continuation->new(
@@ -1176,8 +1182,6 @@
parent => Jifty->web->request->continuation,
);
- warn "$err";
-
# Redirect with a continuation
Jifty->web->_redirect( "/__jifty/error/mason_internal_error?J:C=" . $c->id );
} elsif ($err) {
Modified: jifty/trunk/lib/Jifty/Plugin/SinglePage.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Plugin/SinglePage.pm (original)
+++ jifty/trunk/lib/Jifty/Plugin/SinglePage.pm Fri Jun 8 16:46:17 2007
@@ -13,34 +13,42 @@
$self->region_name($opt{region_name} || '__page');
}
+sub _push_onclick {
+ my $self = shift;
+ my $args = shift;
+ $args->{onclick} = [ $args->{onclick} ] unless ref $args->{onclick} eq 'ARRAY';
+ push @{$args->{onclick}}, @_ if @_;
+}
+
sub _sp_link {
my $self = shift;
return sub {
my ( $clickable, $args ) = @_;
my $url = $args->{'url'};
- if ( $url && $url !~ m/^#/ ) {
- delete $args->{'url'};
+ if ( $url && $url !~ m/^#/ && $url !~ m{^https?://} ) {
# XXX mind the existing onclick
- warn 'ooops got original onclick' . Dumper( $args->{onclick} )
- if $args->{onclick};
- $args->{onclick} = {
+ $self->_push_onclick($args, {
region => $self->region_name,
replace_with => $url,
- args => delete $args->{parameters}
- };
+ args => delete $args->{parameters}});
}
- elsif (exists $args->{submit}) {
- $args->{onclick} = { submit => delete $args->{submit} };
- $args->{refresh_self} = 1;
+ elsif (exists $args->{submit}) {
+ $self->_push_onclick($args, { refresh_self => 1, submit => delete $args->{submit} });
$args->{as_button} = 1;
}
+ if (my $form = delete $args->{_form}) {
+ $args->{call} = $form->call;
+ }
my $onclick = $args->{onclick};
- if ( ref($onclick) eq 'HASH' ) {
- if ( $onclick->{region} && !ref( $onclick->{region} ) ) {
- my $region = $self->region_name;
- $onclick->{region}
- = $region . '-' . $onclick->{region}
- unless $onclick->{region} eq $region or $onclick->{region} =~ m/^\Q$region\E-/;
+ if ( $args->{onclick} ) {
+ $self->_push_onclick($args); # make sure it's array
+ for my $onclick ( @{ $args->{onclick} } ) {
+ if ( $onclick->{region} && !ref( $onclick->{region} ) ) {
+ my $region = $self->region_name;
+ $onclick->{region} = $region . '-' . $onclick->{region}
+ unless $onclick->{region} eq $region
+ or $onclick->{region} =~ m/^\Q$region\E-/;
+ }
}
}
}
Added: jifty/trunk/lib/Jifty/Plugin/SinglePage/Dispatcher.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/SinglePage/Dispatcher.pm Fri Jun 8 16:46:17 2007
@@ -0,0 +1,36 @@
+package Jifty::Plugin::SinglePage::Dispatcher;
+use strict;
+use warnings;
+use Jifty::Dispatcher -base;
+
+before '__jifty/webservices/*' => run {
+ my (@actions) = grep { $_->class eq 'Jifty::Action::Redirect' } values %{ Jifty->web->request->{'actions'} };
+ $_->active(0) for @actions;
+
+ # XXX: shouldn't have multiple redirect
+ # Simply ignore Redirect from webservice if we are not in SPA
+ set '_webservice_redirect' => [map { $_->arguments->{url} } @actions]
+ if Jifty->find_plugin('Jifty::Plugin::SinglePage');
+
+};
+
+on qr{(__jifty/webservices/.*)} => run {
+ my $actions = get '_webservice_redirect';
+ Jifty->web->request->remove_state_variable('region-__page');
+ for my $act (@$actions) {
+ if ($act =~ m{^https?://}) {
+ set '_webservice_external_redirect' => $act;
+ }
+ else {
+ Jifty->web->request->add_fragment(
+ name => '__page',
+ path => $act,
+ arguments => {},
+ wrapper => 0
+ );
+ }
+ }
+ show $1;
+};
+
+1;
Modified: jifty/trunk/lib/Jifty/Request.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Request.pm (original)
+++ jifty/trunk/lib/Jifty/Request.pm Fri Jun 8 16:46:17 2007
@@ -530,8 +530,7 @@
return if $self->is_subrequest;
return unless $self->continuation_type and $self->continuation_type eq "call" and $self->continuation;
$self->log->debug("Calling continuation ".$self->continuation->id);
- $self->continuation->call;
- return 1;
+ return $self->continuation->call;
}
=head2 return_from_continuation
Modified: jifty/trunk/lib/Jifty/Web.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web.pm (original)
+++ jifty/trunk/lib/Jifty/Web.pm Fri Jun 8 16:46:17 2007
@@ -329,6 +329,17 @@
push @valid_actions, $request_action;
}
+ if ($self->request->continuation_path && Jifty->web->request->argument('_webservice_redirect')) {
+ # for continuation - perform internal redirect under webservices
+ Jifty->web->request->remove_state_variable('region-__page');
+ Jifty->web->request->add_fragment(
+ name => '__page',
+ path => $self->request->continuation_path,
+ arguments => {},
+ wrapper => 0
+ );
+ return;
+ }
$self->request->save_continuation;
unless ( $self->request->just_validating ) {
@@ -606,7 +617,7 @@
redirects to that URL rather than B<next_page>.
It creates a continuation of where you want to be, and then calls it.
-If you want to redirect to a parge with parameters, pass in a
+If you want to redirect to a page with parameters, pass in a
L<Jifty::Web::Form::Clickable> object.
=cut
@@ -636,8 +647,7 @@
# To submit a Jifty::Action::Redirect, we don't need to serialize a continuation,
# unlike any other kind of actions.
-
-
+
my $redirect_to_url = '' ;
if ( (grep { not $_->action_class->isa('Jifty::Action::Redirect') }
@@ -687,21 +697,23 @@
my $self = shift;
my ($page) = @_;
-
-
# It's an experimental feature to support redirect within a
- # region. It's currently enabled only for SPA. We should make
- # sure we understand what existing code is call this kind of replace.
- my ($spa) = Jifty->find_plugin('Jifty::Plugin::SinglePage');
-
- if ($spa && $self->current_region) {
+ # region.
+ if ($self->current_region) {
# If we're within a region stack, we don't really want to
- # redirect. We want to redispatch.
+ # redirect. We want to redispatch. Also reset the things
+ # applied on beofre.
+ local $self->{navigation} = undef;
+ local $self->{page_navigation} = undef;
$self->replace_current_region($page);
Jifty::Dispatcher::_abort;
return;
}
+ if (my $redir = Jifty->web->request->argument('_webservice_redirect')) {
+ push @$redir, $page;
+ return;
+ }
# $page can't lead with // or it assumes it's a URI scheme.
$page =~ s{^/+}{/};
Modified: jifty/trunk/lib/Jifty/Web/Form.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/Form.pm (original)
+++ jifty/trunk/lib/Jifty/Web/Form.pm Fri Jun 8 16:46:17 2007
@@ -217,8 +217,7 @@
sub submit {
my $self = shift;
-
- my $button = Jifty::Web::Form::Clickable->new(submit => undef, @_)->generate;
+ my $button = Jifty::Web::Form::Clickable->new(submit => undef, _form => $self, @_)->generate;
Jifty->web->out(qq{<div class="submit_button">});
$button->render_widget;
Jifty->web->out(qq{</div>});
Modified: jifty/trunk/lib/Jifty/Web/Form/Clickable.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/Form/Clickable.pm (original)
+++ jifty/trunk/lib/Jifty/Web/Form/Clickable.pm Fri Jun 8 16:46:17 2007
@@ -455,11 +455,25 @@
escape_label => $self->escape_label,
url => $self->complete_url,
target => $self->target,
+ continuation => $self->_continuation,
@_ }
);
return $link;
}
+sub _continuation {
+ # continuation info used by the update() call on client side
+ my $self = shift;
+ if ($self->call) {
+ return { 'type' => 'call', id => $self->call };
+ }
+ if ($self->returns) {
+ return { 'create' => $self->url };
+ }
+
+ return {};
+}
+
=head2 as_button
Returns the clickable as a L<Jifty::Web::Form::Field::InlineButton>,
@@ -476,6 +490,7 @@
my $field = Jifty::Web::Form::Field->new(
{ %$args,
type => 'InlineButton',
+ continuation => $self->_continuation,
@_ }
);
my %parameters = $self->post_parameters;
Modified: jifty/trunk/lib/Jifty/Web/Form/Element.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/Form/Element.pm (original)
+++ jifty/trunk/lib/Jifty/Web/Form/Element.pm Fri Jun 8 16:46:17 2007
@@ -149,8 +149,8 @@
=cut
-sub accessors { shift->handlers, qw(class key_binding key_binding_label id label tooltip) }
-__PACKAGE__->mk_accessors(qw(_onclick class key_binding key_binding_label id label tooltip));
+sub accessors { shift->handlers, qw(class key_binding key_binding_label id label tooltip continuation) }
+__PACKAGE__->mk_accessors(qw(_onclick class key_binding key_binding_label id label tooltip continuation));
=head2 new PARAMHASH OVERRIDE
@@ -320,7 +320,7 @@
my $string = join ";", (grep {not ref $_} (ref $value eq "ARRAY" ? @{$value} : ($value)));
if (@fragments or (!$actions || %$actions)) {
- my $update = Jifty->web->escape("update( ". Jifty::JSON::objToJson( {actions => $actions, fragments => \@fragments }, {singlequote => 1}) .", this );");
+ my $update = Jifty->web->escape("update( ". Jifty::JSON::objToJson( {actions => $actions, fragments => \@fragments, continuation => $self->continuation }, {singlequote => 1}) .", this );");
$string .= $self->javascript_preempt ? "return $update" : "$update; return true;";
}
if ($confirm) {
Modified: jifty/trunk/lib/Jifty/Web/PageRegion.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/PageRegion.pm (original)
+++ jifty/trunk/lib/Jifty/Web/PageRegion.pm Fri Jun 8 16:46:17 2007
@@ -316,6 +316,10 @@
# clone.
my ($path, $arg) = split(/\?/, $self->path, 2);
$subrequest->path( $path );
+ my %args = (map { split /=/, $_ } split /&/, $arg);
+ if ($args{'J:C'}) {
+ $subrequest->continuation($args{'J:C'});
+ }
}
# Remove all of the actions
unless ($enable_actions) {
Modified: jifty/trunk/share/web/static/js/jifty.js
==============================================================================
--- jifty/trunk/share/web/static/js/jifty.js (original)
+++ jifty/trunk/share/web/static/js/jifty.js Fri Jun 8 16:46:17 2007
@@ -121,7 +121,10 @@
a['fields'][Form.Element.getField(f)] = {};
var field = Form.Element.getField(f);
var type = Form.Element.getType(f);
-
+
+ // XXX: fallback value being an array makes server upset
+ if (type == 'fallback' && a['fields'][field][type])
+ continue
a['fields'][field][type] = this._mergeValues(a['fields'][field][type],
Form.Element.getValue(f));
}
@@ -719,7 +722,6 @@
// - 'mode' is one of 'Replace', or the name of a Prototype Insertion
// - 'effect' is the name of a Prototype Effect
function update() {
- // If we don't have XMLHttpRequest, bail and fallback on full-page
// loads
if(!Ajax.getTransport()) return true;
// XXX: prevent default behavior in IE
@@ -740,19 +742,21 @@
// Grab extra arguments (from a button)
var button_args = Form.Element.buttonFormElements(trigger);
+ var form = Form.Element.getForm(trigger);
// If the action is null, take all actions
if (named_args['actions'] == null) {
named_args['actions'] = {};
// default to disable fields
- var form = Form.Element.getForm(trigger);
if (form)
Form.getActions(form).map(function(x){
named_args['actions'][x.moniker] = 1;
});
}
+ var optional_fragments;
+ if (form && form['J:CALL'])
+ optional_fragments = [ prepare_element_for_update({'mode':'Replace','args':{},'region':'__page','path': null}) ];
// Build actions structure
request['actions'] = $H();
- var optional_fragments;
for (var moniker in named_args['actions']) {
var disable = named_args['actions'][moniker];
var a = new Action(moniker, button_args);
@@ -823,6 +827,13 @@
}
}
}
+ for (var redirect = response.firstChild;
+ redirect != null;
+ redirect = redirect.nextSibling) {
+ if (redirect.nodeName == 'redirect') {
+ document.location = redirect.getAttribute("url");
+ }
+ }
};
var onFailure = function(transport, object) {
hide_wait_message_now();
@@ -846,6 +857,9 @@
request['variables']['region-'+k] = current_args[k];
}
+ // Build continuation structure
+ request['continuation'] = named_args['continuation'];
+
// Push any state variables which we set into the forms
for (var i = 0; i < document.forms.length; i++) {
var form = document.forms[i];
Modified: jifty/trunk/share/web/templates/__jifty/webservices/xml
==============================================================================
--- jifty/trunk/share/web/templates/__jifty/webservices/xml (original)
+++ jifty/trunk/share/web/templates/__jifty/webservices/xml Fri Jun 8 16:46:17 2007
@@ -4,6 +4,12 @@
$writer->xmlDecl( "UTF-8", "yes" );
$writer->startTag("response");
+if (my $ext = Jifty->web->request->argument('_webservice_external_redirect')) {
+ $writer->startTag("redirect", url => $ext);
+ $writer->endTag();
+}
+else {
+
FRAGMENT:
for my $f ( Jifty->web->request->fragments ) {
# Set up the region stack
@@ -50,6 +56,8 @@
Jifty->web->current_region->exit while Jifty->web->current_region;
}
+}
+
my %results = Jifty->web->response->results;
for (keys %results) {
$writer->startTag("result", moniker => $_, class => $results{$_}->action_class);
More information about the Jifty-commit
mailing list