[Jifty-commit] r590 - in jifty/trunk: lib/Jifty lib/Jifty/Web
lib/Jifty/Web/Form share/web/static/js
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Thu Feb 16 15:32:38 EST 2006
Author: alexmv
Date: Thu Feb 16 15:32:37 2006
New Revision: 590
Modified:
jifty/trunk/ (props changed)
jifty/trunk/lib/Jifty/Request.pm
jifty/trunk/lib/Jifty/Web.pm
jifty/trunk/lib/Jifty/Web/Form/Element.pm
jifty/trunk/lib/Jifty/Web/PageRegion.pm
jifty/trunk/share/web/static/js/jifty.js
Log:
r9111 at zoq-fot-pik: chmrr | 2006-02-16 15:31:18 -0500
* Fragments in JS land now know about their parents, and pass their
superstructure in the fragment request. This lets $region->parent
have full information.
* Compute replacement element earlier in js
* 'refresh => region' mode for replacement
* Better docs on region replacement
* add_* calls on Jifty::Request now return the object added, not the
request
Modified: jifty/trunk/lib/Jifty/Request.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Request.pm (original)
+++ jifty/trunk/lib/Jifty/Request.pm Thu Feb 16 15:32:37 2006
@@ -158,11 +158,20 @@
my %fragments = %{$data->{fragments} || {}};
for my $f (values %fragments) {
- $self->add_fragment(name => $f->{name},
- path => $f->{path},
- arguments => $f->{args},
- wrapper => $f->{wrapper} || 0,
- );
+ my $current = $self->add_fragment(
+ name => $f->{name},
+ path => $f->{path},
+ arguments => $f->{args},
+ wrapper => $f->{wrapper} || 0,
+ );
+ while ($f->{parent}) {
+ $f = $f->{parent};
+ $current = $current->parent(Jifty::Request::Fragment->new({
+ name => $f->{name},
+ path => $f->{path},
+ arguments => $f->{args},
+ }));
+ }
}
return $self;
@@ -468,7 +477,8 @@
=head2 add_state_variable PARAMHASH
Adds a state variable to this request's internal representation.
-Takes a C<key> and a C<value>.
+Takes a C<key> and a C<value>; returns the newly-added
+L<Jifty::Request::StateVariable>.
=cut
@@ -485,6 +495,8 @@
$state_var->$k($args{$k}) if defined $args{$k};
}
$self->{'state_variables'}{$args{'key'}} = $state_var;
+
+ return $state_var;
}
=head2 remove_state_variable KEY
@@ -533,10 +545,12 @@
Optional arguments: C<class>, C<order>, C<active>, C<arguments>.
Adds a L<Jifty::Request::Action> with the given
-L<moniker|Jifty::Manual::Glossary/moniker> to the request. If the request
-already contains an action with that moniker, it merges it in,
+L<moniker|Jifty::Manual::Glossary/moniker> to the request. If the
+request already contains an action with that moniker, it merges it in,
overriding the implementation class, active state, and B<individual>
-arguments. See L<Jifty::Action>.
+arguments. Returns the newly added L<Jifty::Request::Action>.
+
+See L<Jifty::Action>.
=cut
@@ -592,6 +606,18 @@
return values %{$self->{'fragments'}}
}
+=head2 fragment NAME
+
+Returns the requested fragment with that name
+
+=cut
+
+sub fragment {
+ my $self = shift;
+ my $name = shift;
+ return $self->{'fragments'}{$name};
+}
+
=head2 add_fragment PARAMHASH
Required arguments: C<name>, C<path>
@@ -600,7 +626,9 @@
Adds a L<Jifty::Request::Fragment> with the given name to the request.
If the request already contains a fragment with that name, it merges
-it in. See L<Jifty::PageRegion>.
+it in. Returns the newly added L<Jifty::Request::Fragment>.
+
+See L<Jifty::PageRegion>.
=cut
@@ -717,7 +745,7 @@
package Jifty::Request::Fragment;
use base 'Class::Accessor';
-__PACKAGE__->mk_accessors( qw/name path wrapper arguments/ );
+__PACKAGE__->mk_accessors( qw/name path wrapper arguments parent/ );
=head2 Jifty::Request::Fragment
Modified: jifty/trunk/lib/Jifty/Web.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web.pm (original)
+++ jifty/trunk/lib/Jifty/Web.pm Thu Feb 16 15:32:37 2006
@@ -1090,30 +1090,27 @@
$writer->xmlDecl( "UTF-8", "yes" );
$writer->startTag("response");
for my $f ( $self->request->fragments ) {
- $writer->startTag( "fragment", id => $f->name );
- my @names = split '-', $f->name;
-
# Set up the region stack
local Jifty->web->{'region_stack'} = [];
- while ( my $region = shift @names ) {
- my $new = @names
- ? Jifty::Web::PageRegion->new(
- name => $region,
- _bootstrap => 1,
- parent => Jifty->web->current_region
- )
- : Jifty::Web::PageRegion->new(
- name => $region,
+ my @regions;
+ do {
+ push @regions, $f;
+ } while ($f = $f->parent);
+
+ for $f (reverse @regions) {
+ my $new = Jifty::Web::PageRegion->new(
+ name => $f->name,
path => $f->path,
region_wrapper => $f->wrapper,
parent => Jifty->web->current_region,
defaults => $f->arguments,
- );
+ );
push @{ Jifty->web->{'region_stack'} }, $new;
$new->enter;
}
# Stuff the rendered region into the XML
+ $writer->startTag( "fragment", id => Jifty->web->current_region->qualified_name );
$writer->cdata( Jifty->web->current_region->render );
$writer->endTag();
}
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 Thu Feb 16 15:32:37 2006
@@ -16,29 +16,78 @@
the name of the javascript event handler, such as C<onclick>, with a
set of arguments.
-The format of the arguments passed to C<onclick> (or any similar method)
-is a hash reference, with the following possible keys:
+The format of the arguments passed to C<onclick> (or any similar
+method) is a hash reference. It takes a number of possible keys. The
+most important is the mode of the fragment replacement, if any; it is
+specified by providing at most one of the following keys:
=over
-=item submit (optional)
+=item append => PATH
-An action (or moniker of an action) to be submitted when the event is fired.
+Add the given C<PATH> as a new fragment, just before the close of the
+CSS selector given by C<element>, which defaults to the end of the
+current region.
-=item region (optional)
+=item prepend => PATH
+
+Add the given C<PATH> as a new fragment, just aftger the start of the
+CSS selector given by C<element>, which defaults to the start of the
+current region.
+
+=item replace_with => PATH
+
+Replaces the region specified by the C<region> parameter (which
+defaults to the current region) with the fragment located at the given
+C<PATH>.
+
+=item refresh => REGION
+
+Refreshes the given C<REGION>, which should be a
+L<Jifty::Web::PageRegion> object, or the fully qualified name of such.
+
+=item refresh_self => 1
+
+Refreshes the current region; this is the default action, if C<args>
+are supplied, but no other mode is given.
+
+=back
+
+The following options are also supported:
+
+=over
+
+=item region => REGION
The region that should be updated. This defaults to the current
region.
-=item args (optional)
+=item element => CSS SELECTOR
+
+A css selector specifying where the new region should be placed; used
+with C<append> and C<prepend>, above. The
+L<Jifty::Web::PageRegion/get_element> method may be useful in
+specifying elements of parent page regions.
+
+=item submit => MONIKER
+
+An action, moniker of an action, or array reference to such; these
+actions are submitted when the event is fired.
+
+=item args => HASHREF
-Arguments to the region. These will override the default arguments to
-the region.
+Arguments to the region. These will override the arguments to the
+region that the region was given when it was last rendered.
-=item fragment (optional)
+=item effect => STRING
-The fragment that should go into the region. The default is whatever
-fragment the region was originally rendered with.
+The Prototype visual effect to use when updating or creating the
+fragment.
+
+=item effect_args => HASHREF
+
+A hashref of arguments to pass to the effect when it is creted. These
+can be used to change the duration of the effect, for instance.
=back
@@ -92,27 +141,34 @@
push @actions, map { ref $_ ? $_->moniker : $_ } @{ $hook->{submit} };
}
+ $hook->{region} ||= Jifty->web->qualified_region;
+
# Placement
- if (exists $hook->{replace_with}) {
- @args{qw/mode path/} = ('Replace', $hook->{replace_with});
- } elsif (exists $hook->{append}) {
+ if (exists $hook->{append}) {
@args{qw/mode path/} = ('Bottom', $hook->{append});
+ $hook->{element} ||= "#region-".$hook->{region};
} elsif (exists $hook->{prepend}) {
@args{qw/mode path/} = ('Top', $hook->{prepend});
+ $hook->{element} ||= "#region-".$hook->{region};
+ } elsif (exists $hook->{replace_with}) {
+ @args{qw/mode path region/} = ('Replace', $hook->{replace_with}, $hook->{region});
+ } elsif (exists $hook->{refresh}) {
+ @args{qw/mode path region/} = ('Replace', $hook->{refresh}->path, $hook->{refresh});
} elsif ((exists $hook->{refresh_self} and Jifty->web->current_region) or $hook->{args}) {
# If we just pass arguments, treat as a refresh_self
- @args{qw/mode path/} = ('Replace', Jifty->web->current_region->path);
+ @args{qw/mode path region/} = ('Replace', Jifty->web->current_region->path, Jifty->web->current_region);
} else {
# If we're not doing any of the above, skip this one
next;
}
+ # Qualified name if we have a ref
+ $args{region} = $args{region}->qualified_name if ref $args{region};
+
# What element we're replacing.
if ($hook->{element}) {
- $args{element} = $hook->{element};
+ $args{element} = ref $hook->{element} ? "#region-".$hook->{element}->qualified_name : $hook->{element};
$args{region} = $args{element} =~ /^#region-(\S+)/ ? "$1-".Jifty->web->serial : Jifty->web->serial;
- } else {
- $args{region} = $hook->{region} || Jifty->web->qualified_region;
}
# Arguments
Modified: jifty/trunk/lib/Jifty/Web/PageRegion.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/PageRegion.pm (original)
+++ jifty/trunk/lib/Jifty/Web/PageRegion.pm Thu Feb 16 15:32:37 2006
@@ -230,9 +230,11 @@
# We only render the region wrapper if we're asked to (which is true by default)
if ($self->region_wrapper) {
$result .= qq|<script type="text/javascript">\n|;
- $result .= qq|new Region('|. $self->qualified_name .qq|',|;
- $result .= Jifty::JSON::objToJson(\%arguments, {singlequote => 1});
- $result .= qq|,'|. $self->path . qq|');\n|;
+ $result .= qq|new Region('|. $self->qualified_name . qq|',|;
+ $result .= Jifty::JSON::objToJson(\%arguments, {singlequote => 1}) . qq|,|;
+ $result .= qq|'| . $self->path . qq|',|;
+ $result .= $self->parent ? qq|'| . $self->parent->qualified_name . qq|'| : q|null|;
+ $result .= qq|);\n|;
$result .= qq|</script>|;
$result .= qq|<div id="region-| . $self->qualified_name . qq|">|;
}
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 Thu Feb 16 15:32:37 2006
@@ -241,10 +241,11 @@
var Region = Class.create();
Region.prototype = {
- initialize: function(name, args, path) {
+ initialize: function(name, args, path, parent) {
this.name = name;
this.args = $H(args);
this.path = path;
+ this.parent = parent ? fragments[parent] : null;
if (fragments[name]) {
// If this fragment already existed, we want to wipe out
// whatever evil lies we might have said earlier; do this
@@ -311,10 +312,24 @@
},
data_structure: function(path, args) {
+ // Set the path and args, if given
+ if (path)
+ this.setPath(path);
+ if (args)
+ this.setArgs(args);
+
+ // If we have a parent, find our not-qualified name
+ var shortname = this.name;
+ if (this.parent) {
+ shortname = this.name.substr(this.parent.name.length + 1);
+ }
+
+ // Return a nummy data structure
return {
- name: this.name,
- path: this.setPath(path),
- args: this.setArgs(args)
+ name: shortname,
+ path: this.path,
+ args: this.args,
+ parent: this.parent ? this.parent.data_structure(null,null) : null
}
}
};
@@ -357,17 +372,44 @@
var f = named_args['fragments'][i];
var name = f['region'];
+
+ // Find where we are going to go
+ var element = $('region-' + f['region']);
+ if (f['element']) {
+ var possible = document.getElementsBySelector(f['element']);
+ if (possible.length == 0)
+ element = null;
+ else
+ element = possible[0];
+ }
+ f['element'] = element;
+
+ // If we can't find out where we're going, bail
+ if (element == null)
+ continue;
+
f['is_new'] = (fragments[name] ? false : true);
-
// If it's new, we need to create it so we can dump it
- if (f['is_new'])
- new Region(name, f['args'], f['path']);
+ if (f['is_new']) {
+ // Find what region we're inside
+ f['parent'] = null;
+ if (f['mode'] && ((f['mode'] == "Before") || (f['mode'] == "After")))
+ element = element.parentNode;
+ while ((element != null) && (f['parent'] == null)) {
+ if (/^region-/.test(element.getAttribute("id")))
+ f['parent'] = element.getAttribute("id").replace(/^region-/,"");
+ element = element.parentNode;
+ }
+
+ // Make the region (for now)
+ new Region(name, f['args'], f['path'], f['parent']);
+ }
// Update with all new values
var fragment_request = fragments[name].data_structure(f['path'], f['args']);
- // Ask for the wrapper if we are making a new region
if (f['is_new'])
+ // Ask for the wrapper if we are making a new region
fragment_request['wrapper'] = 1;
// Push it onto the request stack
@@ -384,54 +426,43 @@
// For each fragment we requested
for (var i = 0; i < named_args['fragments'].length; i++) {
var f = named_args['fragments'][i];
+ var element = f['element'];
- // Find the element that is getting dealt with
- var element = $('region-' + f['region']);
- if (f['element']) {
- var possible = document.getElementsBySelector(f['element']);
- if (possible.length == 0)
- element = null;
- else
- element = possible[0];
- }
// Change insertion mode if need be
var insertion = null;
if (f['mode'] && (f['mode'] != 'Replace')) {
insertion = eval('Insertion.'+f['mode']);
}
- // If we found something to replace
- if (element) {
- // Loop through the result looking for it
- for (var response_fragment = response.firstChild;
- response_fragment != null;
- response_fragment = response_fragment.nextSibling) {
- if (response_fragment.getAttribute("id") == f['region']) {
- var textContent;
- if (response_fragment.textContent) {
- textContent = response_fragment.textContent;
- } else {
- textContent = response_fragment.firstChild.nodeValue;
- }
- // Once we find it, do the insertion
- if (insertion) {
- new insertion(element, textContent.stripScripts());
- } else {
- Element.update(element, textContent.stripScripts());
- }
- // We need to give the browser some "settle" time before we eval scripts in the body
- setTimeout((function() { this.evalScripts() }).bind(textContent), 10);
+ // Loop through the result looking for it
+ for (var response_fragment = response.firstChild;
+ response_fragment != null;
+ response_fragment = response_fragment.nextSibling) {
+ if (response_fragment.getAttribute("id") == f['region']) {
+ var textContent;
+ if (response_fragment.textContent) {
+ textContent = response_fragment.textContent;
+ } else {
+ textContent = response_fragment.firstChild.nodeValue;
}
+ // Once we find it, do the insertion
+ if (insertion) {
+ new insertion(element, textContent.stripScripts());
+ } else {
+ Element.update(element, textContent.stripScripts());
+ }
+ // We need to give the browser some "settle" time before we eval scripts in the body
+ setTimeout((function() { this.evalScripts() }).bind(textContent), 10);
}
+ }
- // Also, set us up the effect
- if (f['effect']) {
- var effect = eval('Effect.'+f['effect']);
- var effect_args = f['effect_args'] || {};
- if (f['is_new'])
- Element.hide($('region-'+f['region']));
- (effect)($('region-'+f['region']), effect_args);
- }
+ // Also, set us up the effect
+ if (f['effect']) {
+ var effect = eval('Effect.'+f['effect']);
+ var effect_args = f['effect_args'] || {};
+ if (f['is_new'])
+ Element.hide($('region-'+f['region']));
+ (effect)($('region-'+f['region']), effect_args);
}
}
} finally {
More information about the Jifty-commit
mailing list