| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Template::Lace::Renderer; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
726
|
use Moo; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
10
|
|
|
4
|
1
|
|
|
1
|
|
545
|
use Scalar::Util; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
1361
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
has [qw(model dom components)] => (is=>'ro', required=>1); |
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
sub call { |
|
9
|
4
|
|
|
4
|
1
|
24
|
my ($self, $proto, @args) = @_; |
|
10
|
4
|
100
|
100
|
|
|
32
|
if(ref($proto)||'' eq 'CODE') { |
|
|
|
50
|
|
|
|
|
|
|
11
|
1
|
|
|
|
|
9
|
return $proto->($self->model, $self->dom, @args); |
|
12
|
|
|
|
|
|
|
} elsif($proto) { |
|
13
|
3
|
|
|
|
|
21
|
return $self->model->$proto($self->dom, @args); |
|
14
|
|
|
|
|
|
|
} |
|
15
|
|
|
|
|
|
|
} |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
sub call_at { |
|
18
|
0
|
|
|
0
|
1
|
0
|
my ($self, $css, $proto, @args) = @_; |
|
19
|
0
|
|
|
|
|
0
|
my $dom = $self->dom->at($css); |
|
20
|
0
|
0
|
0
|
|
|
0
|
if(ref($proto)||'' eq 'CODE') { |
|
|
|
0
|
|
|
|
|
|
|
21
|
0
|
|
|
|
|
0
|
return $proto->($self->model, $dom, @args); |
|
22
|
|
|
|
|
|
|
} elsif($proto) { |
|
23
|
0
|
|
|
|
|
0
|
return $self->model->$proto($dom, @args); |
|
24
|
|
|
|
|
|
|
} |
|
25
|
|
|
|
|
|
|
} |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
sub render { |
|
28
|
2
|
|
|
2
|
0
|
10
|
my $self = shift; |
|
29
|
2
|
|
|
|
|
11
|
my $rendered_dom = $self->get_processed_dom |
|
30
|
|
|
|
|
|
|
->to_string; |
|
31
|
2
|
|
|
|
|
1362
|
return $rendered_dom; |
|
32
|
|
|
|
|
|
|
} |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub get_processed_dom { |
|
35
|
6
|
|
|
6
|
0
|
15
|
my $self = shift; |
|
36
|
6
|
|
|
|
|
22
|
my $dom = $self->dom; |
|
37
|
6
|
|
|
|
|
31
|
$self->process_components($dom); |
|
38
|
6
|
100
|
|
|
|
1252
|
$self->model->process_dom($dom) |
|
39
|
|
|
|
|
|
|
if $self->model->can('process_dom'); |
|
40
|
6
|
|
|
|
|
20328
|
return $dom; |
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
sub process_components { |
|
44
|
6
|
|
|
6
|
0
|
18
|
my ($self, $dom) = @_; |
|
45
|
6
|
|
|
|
|
13
|
my @ordered_keys = @{$self->components->ordered_component_keys}; |
|
|
6
|
|
|
|
|
32
|
|
|
46
|
6
|
|
|
|
|
18
|
my %constructed_components = (); |
|
47
|
6
|
|
|
|
|
16
|
foreach my $id(@ordered_keys) { |
|
48
|
6
|
50
|
|
|
|
1495
|
next unless $self->components->handlers->{$id}; # might skip if 'static' handler |
|
49
|
6
|
100
|
|
|
|
33
|
next unless my $local_dom = $dom->at("[uuid='$id']"); |
|
50
|
|
|
|
|
|
|
my $constructed_component = $self->process_component( |
|
51
|
|
|
|
|
|
|
$local_dom, |
|
52
|
|
|
|
|
|
|
$self->components->handlers->{$id}, |
|
53
|
|
|
|
|
|
|
\%constructed_components, |
|
54
|
5
|
|
|
|
|
4108
|
%{$self->components->component_info->{$id}}); |
|
|
5
|
|
|
|
|
43
|
|
|
55
|
5
|
50
|
|
|
|
31
|
$constructed_components{$id} = $constructed_component |
|
56
|
|
|
|
|
|
|
if $constructed_component; |
|
57
|
|
|
|
|
|
|
} |
|
58
|
|
|
|
|
|
|
# Now post process.. We do this so that parents can have access to |
|
59
|
|
|
|
|
|
|
# children for transforming dom. |
|
60
|
6
|
|
|
|
|
19
|
foreach my $id(@ordered_keys) { |
|
61
|
6
|
100
|
|
|
|
6811
|
next unless $constructed_components{$id}; |
|
62
|
5
|
|
|
|
|
25
|
my $processed_component = $constructed_components{$id}->get_processed_dom; |
|
63
|
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
#=head1 comment |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# Move all the scripts, styles and links to the head area |
|
67
|
|
|
|
|
|
|
# TODO this probably doesn't work if the stuff is in a component |
|
68
|
|
|
|
|
|
|
# inside a component. |
|
69
|
|
|
|
|
|
|
$processed_component->find('link:not(head link)')->each(sub { |
|
70
|
0
|
0
|
0
|
0
|
|
0
|
return unless $_->attr('id') || $_->attr('href'); |
|
71
|
0
|
|
|
|
|
0
|
$dom->append_link_uniquely($_); |
|
72
|
0
|
|
|
|
|
0
|
$_->remove; |
|
73
|
5
|
|
|
|
|
188
|
}); # href |
|
74
|
|
|
|
|
|
|
$processed_component->find('style:not(head style)')->each(sub { |
|
75
|
3
|
50
|
|
3
|
|
1163
|
return unless $_->attr('id'); |
|
76
|
3
|
|
|
|
|
64
|
$dom->append_style_uniquely($_); |
|
77
|
3
|
|
|
|
|
18
|
$_->remove; |
|
78
|
5
|
|
|
|
|
1824
|
}); #id |
|
79
|
|
|
|
|
|
|
$processed_component->find('script:not(head script)')->each(sub { |
|
80
|
0
|
|
|
0
|
|
0
|
my ($e, $num) = @_; |
|
81
|
0
|
0
|
0
|
|
|
0
|
return unless $e->attr('id') || $e->attr('src'); |
|
82
|
0
|
|
|
|
|
0
|
$dom->append_script_uniquely($e); |
|
83
|
0
|
|
|
|
|
0
|
$_->remove; |
|
84
|
5
|
|
|
|
|
1162
|
}); #id or src |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
#=cut |
|
87
|
|
|
|
|
|
|
|
|
88
|
5
|
|
|
|
|
1504
|
$dom->at("[uuid='$id']")->replace($processed_component); |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub prepare_component_attrs { |
|
93
|
5
|
|
|
5
|
0
|
23
|
my ($self, $dom, $model, %component_info) = @_; |
|
94
|
|
|
|
|
|
|
my %attrs = ( |
|
95
|
5
|
|
|
|
|
12
|
$self->process_attrs($model, $dom, %{$component_info{attrs}}), |
|
|
5
|
|
|
|
|
26
|
|
|
96
|
|
|
|
|
|
|
content=>$dom->content, |
|
97
|
|
|
|
|
|
|
model=>$model); |
|
98
|
5
|
|
|
|
|
769
|
return %attrs; |
|
99
|
|
|
|
|
|
|
} |
|
100
|
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
sub process_component { |
|
102
|
5
|
|
|
5
|
0
|
31
|
my ($self, $dom, $component, $constructed_components, %component_info) = @_; |
|
103
|
5
|
|
|
|
|
28
|
my %attrs = $self->prepare_component_attrs($dom, $self->model, %component_info); |
|
104
|
5
|
50
|
|
|
|
23
|
if(my $container_id = $component_info{current_container_id}) { |
|
105
|
|
|
|
|
|
|
# Its possible if the compoent was a 'on_component_add' type that |
|
106
|
|
|
|
|
|
|
# its been removed from the DOM and a Child might still have it as |
|
107
|
|
|
|
|
|
|
# a container by mistake. Possible a TODO to have a better idea. |
|
108
|
|
|
|
|
|
|
$attrs{container} = $constructed_components->{$container_id}->model |
|
109
|
5
|
100
|
|
|
|
25
|
if $constructed_components->{$container_id}; |
|
110
|
|
|
|
|
|
|
} |
|
111
|
|
|
|
|
|
|
|
|
112
|
5
|
50
|
|
|
|
26
|
if(Scalar::Util::blessed $component) { |
|
|
|
0
|
|
|
|
|
|
|
113
|
5
|
|
|
|
|
10
|
my $constructed_component; |
|
114
|
5
|
100
|
|
|
|
13
|
if($attrs{container}) { |
|
115
|
2
|
50
|
|
|
|
17
|
if($attrs{container}->can('create_child')) { |
|
116
|
0
|
|
|
|
|
0
|
$constructed_component = $attrs{container}->create_child($component, %attrs); |
|
117
|
|
|
|
|
|
|
} else { |
|
118
|
2
|
|
|
|
|
12
|
$constructed_component = $component->create(%attrs); |
|
119
|
|
|
|
|
|
|
$attrs{container}->add_child($constructed_component) if |
|
120
|
2
|
50
|
|
|
|
23
|
$attrs{container}->can('add_child'); |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
} else { |
|
123
|
3
|
|
|
|
|
19
|
$constructed_component = $component->create(%attrs); |
|
124
|
|
|
|
|
|
|
} |
|
125
|
5
|
|
|
|
|
25
|
return $constructed_component; |
|
126
|
|
|
|
|
|
|
} elsif(ref($component) eq 'CODE') { |
|
127
|
0
|
|
|
|
|
0
|
die "Component not an object"; |
|
128
|
|
|
|
|
|
|
#my $new_dom = $component->($dom->content, %attrs); |
|
129
|
|
|
|
|
|
|
#warn $new_dom; |
|
130
|
|
|
|
|
|
|
#$dom->replace($new_dom); |
|
131
|
|
|
|
|
|
|
#warn $dom; |
|
132
|
|
|
|
|
|
|
#return; |
|
133
|
|
|
|
|
|
|
} |
|
134
|
|
|
|
|
|
|
} |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
sub process_attrs { |
|
137
|
6
|
|
|
6
|
0
|
36
|
my ($self, $ctx, $dom, %attrs) = @_; |
|
138
|
|
|
|
|
|
|
return map { |
|
139
|
6
|
|
|
|
|
22
|
my $proto = $attrs{$_}; |
|
|
23
|
|
|
|
|
57
|
|
|
140
|
23
|
100
|
|
|
|
73
|
my $value = ref($proto) ? $proto->($ctx, $dom) : $proto; |
|
141
|
23
|
|
|
|
|
2351
|
$_ => $value; |
|
142
|
|
|
|
|
|
|
} keys %attrs; |
|
143
|
|
|
|
|
|
|
} |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
1; |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=head1 NAME |
|
148
|
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
Template::Lace::Renderer |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
TBD |
|
154
|
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
Renderer for the model. Not really end user aimed. See L<Template::Lace> |
|
158
|
|
|
|
|
|
|
for main overview. |
|
159
|
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=head1 METHODS |
|
161
|
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
This class defines the following public methods |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=head2 call |
|
165
|
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
Allows you to have the renderer 'call' a method into the model, with the current |
|
167
|
|
|
|
|
|
|
DOM. Takes either a coderef or a string (that must be the name of a method in the |
|
168
|
|
|
|
|
|
|
model. Example: |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
$renderer->call(sub { |
|
171
|
|
|
|
|
|
|
my ($model, $dom) = @_; |
|
172
|
|
|
|
|
|
|
$model->add_debug($dom); |
|
173
|
|
|
|
|
|
|
}, @args); |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
$renderer->call('add_debug', @args); |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
Are both the same as |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
$renderer |
|
180
|
|
|
|
|
|
|
->model |
|
181
|
|
|
|
|
|
|
->add_debug($renderer->dom, @args); |
|
182
|
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
You might find this is a useful shortcut (or not). |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=head2 call_at |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
Basically similar to L</call> except allows you to specify a CSS match to |
|
188
|
|
|
|
|
|
|
set the DOM. |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
$renderer->call_at('#debug','add_debug', @args); |
|
191
|
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
Is basically a shortcut for: |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
my $dom = $renderer->dom->at('#debug); |
|
195
|
|
|
|
|
|
|
$renderer->model->add_debug($dom, @args); |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
L<Template::Lace>. |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=head1 AUTHOR |
|
202
|
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
Please See L<Template::Lace> for authorship and contributor information. |
|
204
|
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
Please see L<Template::Lace> for copyright and license information. |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=cut |