use Reaction::Class;
use Reaction::UI::Widget;
use Data::Dumper;
+use Devel::Declare;
no warnings 'once';
}, # XXX zis is not ze grand design. OBSERVABLE.
string => sub (&) { -string => [ @_ ] }, # meh (maybe &;@ later?)
wrap => sub { $self->do_wrap_sub($package, @_); }, # should have class.
+ fragment => sub (@) { }, # placeholder rewritten by do_import
+ over => sub { -over => @_ },
+ );
+ };
+
+ after do_import => sub {
+ my ($self, $pkg, $args) = @_;
+
+ Devel::Declare->install_declarator(
+ $pkg, 'fragment', DECLARE_NAME,
+ sub { },
+ sub {
+ our $FRAGMENT_CLOSURE;
+ splice(@_, 1, 1); # remove undef proto arg
+ $FRAGMENT_CLOSURE->(@_);
+ }
);
};
overrides do_class_sub => sub {
my ($self, $package, $class) = @_;
# intercepts 'foo renders ...'
- local *renders::AUTOLOAD = sub {
- our $AUTOLOAD;
- shift;
- $AUTOLOAD =~ /^renders::(.*)$/;
- $self->do_renders_meth($package, $class, $1, @_);
- };
- # intercepts 'foo over ...'
- local *over::AUTOLOAD = sub {
- our $AUTOLOAD;
- shift;
- $AUTOLOAD =~ /^over::(.*)$/;
- $self->do_over_meth($package, $class, $1, @_);
+ our $FRAGMENT_CLOSURE;
+ local $FRAGMENT_CLOSURE = sub {
+ $self->do_renders_meth($package, $class, @_);
};
# $_ returns '-topic:_', $_{foo} returns '-topic:foo'
local $_ = '-topic:_';
if (defined($args) && (ref($args) ne 'HASH'));
$sig .= '
- where content spec is [ fragment_name over func(...), \%args? ]
+where content spec is [ fragment_name => over (func(...)|$_|$_{keyname}), \%args? ]
or [ qw(list of fragment names), \%args ]'; # explain the mistake, yea
my $inner_args = ((ref($content->[-1]) eq 'HASH') ? pop(@$content) : {});
- # [ blah over func(...), { ... } ] or [ qw(foo bar), { ... } ]
+ # [ blah over (func(...)|$_|$_{keyname}), { ... } ] or [ qw(foo bar), { ... } ]
# predeclare since content_gen gets populated somewhere in an if
# and inner_args_gen wants to be closed over by content_gen
confess "Content spec invalid, ${sig}"
unless defined($content->[0]) && !ref($content->[0]);
+ # new-style over gives 'frag, -over, $func'. massage.
+
+ if (defined($content->[1]) && !ref($content->[1])
+ && ($content->[1] eq '-over')) {
+ @$content[0,1] = @$content[1,0];
+ }
+
if (my ($key) = ($content->[0] =~ /^-(.*)?/)) {
# if first content value is -foo, pull it off the front and then
# - if arrayref, render fragment per entry
# - if obj and can('next') call that until undef
# - else scream loudly
- my ($func_key, $func_meth) = @$func;
+ unless ((ref($func) eq 'ARRAY') || ($func =~ /^-topic:(.*)$/)) {
+ confess "over value wrong, should be ${sig}";
+ }
$content_gen = sub {
my ($widget, $args) = @_;
- my $topic = eval { $args->{$func_key}->$func_meth };
- confess "Error calling ${func_meth} on ${func_key} argument "
- .($args->{$func_key}||'').": $@"
- if $@;
+ my $topic;
+ if (ref($func) eq 'ARRAY') {
+ my ($func_key, $func_meth) = @$func;
+ $topic = eval { $args->{$func_key}->$func_meth };
+ confess "Error calling ${func_meth} on ${func_key} argument "
+ .($args->{$func_key}||'').": $@"
+ if $@;
+ } elsif ($func =~ /^-topic:(.*)$/) {
+ $topic = $args->{$1};
+ } else {
+ confess "Shouldn't get here";
+ }
my $iter_sub;
if (ref $topic eq 'ARRAY') {
my @copy = @$topic; # non-destructive on original data
};
};
};
-
+
# must also handle just $_ later for wrap
} else {
# unrecognised -foo
my @extra_keys = keys %args_extra;
my @extra_gen = values %args_extra;
-
+
my $meth = sub {
my ($self, $rctx, $args) = @_;
confess "No rendering context passed" unless $rctx;
@{$r_args}{@extra_keys} = map { $_->($self, $args); } @extra_gen;
$r_args->{'_'} = $content_gen->($self, $args);
#warn Dumper($r_args).' ';
- $rctx->render($fname, $r_args);
+ $rctx->render($self->layout_set, $fname, $r_args);
};
$class->meta->add_method($methname => $meth);
my $sig = 'should be: key => $_ or key => $_{name} or key => func("name", "method")';
- my (@func_to, @func_spec, @copy_from, @copy_to);
+ my (@func_to, @func_spec, @copy_from, @copy_to, @sub_spec, @sub_to);
foreach my $key (keys %$argspec) {
my $val = $argspec->{$key};
if (ref($val) eq 'ARRAY') {
my $topic_key = $1;
push(@copy_from, $topic_key);
push(@copy_to, $key);
+ } elsif (ref($val) eq 'CODE') {
+ #LOOK AT ME
+ my $sub = sub{
+ my $inner_args = shift;
+ local *_ = \%{$inner_args};
+ local $_ = $inner_args->{'_'};
+ return $val->();
+ };
+ push(@sub_spec, $sub);
+ push(@sub_to, $key);
} else {
confess "Invalid args member for ${key}, ${sig}";
}
my ($key, $meth) = @{$_};
$outer_args->{$key}->$meth; # [ 'a, 'b' ] ~~ ->{'a'}->b
} @func_spec);
+ #LOOK AT ME
+ @{$args}{@sub_to} = (map { $_->($outer_args) } @sub_spec);
#warn Dumper($args).' ';
return $args;
};
};
-
+
};
+1;
+
package Reaction::UI::WidgetClass::TopicHash;
use Tie::Hash;
1;
+__END__;
+
=head1 NAME
Reaction::UI::WidgetClass