line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# |
2
|
|
|
|
|
|
|
# This file is part of WebDyne. |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# This software is Copyright (c) 2017 by Andrew Speer . |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# This is free software, licensed under: |
7
|
|
|
|
|
|
|
# |
8
|
|
|
|
|
|
|
# The GNU General Public License, Version 2, June 1991 |
9
|
|
|
|
|
|
|
# |
10
|
|
|
|
|
|
|
# Full license text is available at: |
11
|
|
|
|
|
|
|
# |
12
|
|
|
|
|
|
|
# |
13
|
|
|
|
|
|
|
# |
14
|
|
|
|
|
|
|
package WebDyne::Compile; |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# Packace init, attempt to load optional Time::HiRes module |
18
|
|
|
|
|
|
|
# |
19
|
|
|
|
|
|
|
sub BEGIN { |
20
|
1
|
|
|
1
|
|
10
|
local $SIG{__DIE__}; |
21
|
1
|
|
|
|
|
3
|
$^W=0; |
22
|
1
|
50
|
|
1
|
|
73
|
eval("use Time::HiRes qw(time)") || eval {undef}; |
|
1
|
|
|
|
|
181
|
|
|
1
|
|
|
|
|
8
|
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
16
|
|
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# Pragma |
27
|
|
|
|
|
|
|
# |
28
|
1
|
|
|
1
|
|
7
|
use strict qw(vars); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
35
|
|
29
|
1
|
|
|
1
|
|
4
|
use vars qw($VERSION %CGI_TAG_WEBDYNE %CGI_TAG_IMPLICIT); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
63
|
|
30
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
39
|
|
31
|
1
|
|
|
1
|
|
4
|
no warnings qw(uninitialized redefine once); |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
61
|
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# External Modules |
35
|
|
|
|
|
|
|
# |
36
|
1
|
|
|
1
|
|
9
|
use WebDyne; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
33
|
|
37
|
1
|
|
|
1
|
|
533
|
use WebDyne::HTML::TreeBuilder; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
6
|
|
38
|
1
|
|
|
1
|
|
36
|
use Storable; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
71
|
|
39
|
1
|
|
|
1
|
|
9
|
use IO::File; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
192
|
|
40
|
1
|
|
|
1
|
|
7
|
use CGI qw(-no_xhtml); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
9
|
|
41
|
1
|
|
|
1
|
|
130
|
use CGI::Util; |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
98
|
|
42
|
1
|
|
|
1
|
|
31
|
use Data::Dumper; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
40
|
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# WebDyne Modules |
46
|
|
|
|
|
|
|
# |
47
|
1
|
|
|
1
|
|
9
|
use WebDyne::Constant; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
306
|
|
48
|
1
|
|
|
1
|
|
6
|
use WebDyne::Base; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
3
|
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# Version information |
52
|
|
|
|
|
|
|
# |
53
|
|
|
|
|
|
|
$VERSION='1.247'; |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# Debug load |
57
|
|
|
|
|
|
|
# |
58
|
|
|
|
|
|
|
0 && debug("Loading %s version $VERSION", __PACKAGE__); |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
# Tags that are case sensitive |
62
|
|
|
|
|
|
|
# |
63
|
|
|
|
|
|
|
our %CGI_Tag_Ucase=map {$_ => ucfirst($_)} ( |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
qw(select tr link delete accept sub) |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
); |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
# Extend CGI with missing tags |
71
|
|
|
|
|
|
|
# |
72
|
|
|
|
|
|
|
our @CGI_Tag_Extend=( |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
qw(Header) |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
); |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# Get WebDyne and CGI tags from TreeBuilder module |
80
|
|
|
|
|
|
|
# |
81
|
|
|
|
|
|
|
*CGI_TAG_WEBDYNE=\%WebDyne::CGI_TAG_WEBDYNE; |
82
|
|
|
|
|
|
|
*CGI_TAG_IMPLICIT=\%WebDyne::HTML::TreeBuilder::CGI_TAG_IMPLICIT; |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
# Need the start/end_html code ref for later on |
86
|
|
|
|
|
|
|
# |
87
|
|
|
|
|
|
|
my $CGI_start_html_cr=UNIVERSAL::can(CGI, 'start_html'); |
88
|
|
|
|
|
|
|
my $CGI_end_html_cr=UNIVERSAL::can(CGI, 'end_html'); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# Var to hold package wide hash, for data shared across package |
92
|
|
|
|
|
|
|
# |
93
|
|
|
|
|
|
|
my %Package; |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# All done. Positive return |
97
|
|
|
|
|
|
|
# |
98
|
|
|
|
|
|
|
1; |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
#================================================================================================== |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub new { |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
# Only used when debugging from outside apache, eg test script. If so, user |
108
|
|
|
|
|
|
|
# must create new object ref, then run the compile. See wdcompile script for |
109
|
|
|
|
|
|
|
# example. wdcompile is only used for debugging - we do some q&d stuff here |
110
|
|
|
|
|
|
|
# to make it work |
111
|
|
|
|
|
|
|
# |
112
|
0
|
|
|
0
|
0
|
0
|
my $class=shift(); |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
# Init WebDyne module |
116
|
|
|
|
|
|
|
# |
117
|
0
|
|
|
|
|
0
|
WebDyne->init_class(); |
118
|
0
|
|
|
|
|
0
|
require WebDyne::Request::Fake; |
119
|
0
|
|
|
|
|
0
|
my $r=WebDyne::Request::Fake->new(); |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
# New self ref |
123
|
|
|
|
|
|
|
# |
124
|
0
|
|
|
|
|
0
|
my %self=( |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
_r => $r, |
127
|
|
|
|
|
|
|
_CGI => CGI->new(), |
128
|
|
|
|
|
|
|
_time => time() |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
); |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# And return blessed ref |
134
|
|
|
|
|
|
|
# |
135
|
0
|
|
|
|
|
0
|
return bless \%self, 'WebDyne'; |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub compile { |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
# Compile HTML file into Storable structure |
145
|
|
|
|
|
|
|
# |
146
|
14
|
|
|
14
|
0
|
42
|
my ($self, $param_hr)=@_; |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
# Start timer so we can log how long it takes us to compile a file |
150
|
|
|
|
|
|
|
# |
151
|
14
|
|
|
|
|
44
|
my $time=time(); |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Init class if not yet done |
155
|
|
|
|
|
|
|
# |
156
|
14
|
|
66
|
|
|
112
|
(ref($self))->{_compile_init} ||= do { |
157
|
1
|
50
|
|
|
|
4
|
$self->compile_init() || return err () |
158
|
|
|
|
|
|
|
}; |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# Debug |
162
|
|
|
|
|
|
|
# |
163
|
14
|
|
|
|
|
41
|
0 && debug('compile %s', Dumper($param_hr)); |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
# Get srce and dest |
167
|
|
|
|
|
|
|
# |
168
|
14
|
|
|
|
|
31
|
my ($html_cn, $dest_cn)=@{$param_hr}{qw(srce dest)}; |
|
14
|
|
|
|
|
51
|
|
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# Need request object ref |
172
|
|
|
|
|
|
|
# |
173
|
14
|
|
50
|
|
|
58
|
my $r=$self->{'_r'} || $self->r() || return err (); |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
# Get CGI ref |
177
|
|
|
|
|
|
|
# |
178
|
14
|
|
50
|
|
|
124
|
my $cgi_or=$self->{'_CGI'} || $self->CGI() || return err (); |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
# Turn off xhtml in CGI - should work in pragma, seems dodgy - seems like |
182
|
|
|
|
|
|
|
# we must do every time we compile a page |
183
|
|
|
|
|
|
|
# |
184
|
14
|
|
|
|
|
32
|
$CGI::XHTML=0; |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# Nostick |
188
|
|
|
|
|
|
|
# |
189
|
14
|
|
|
|
|
20
|
$CGI::NOSTICKY=1; |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
# Open the file |
193
|
|
|
|
|
|
|
# |
194
|
14
|
|
50
|
|
|
140
|
my $html_fh=IO::File->new($html_cn, O_RDONLY) || |
195
|
|
|
|
|
|
|
return err ("unable to open file $html_cn, $!"); |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
# Get new TreeBuilder object |
199
|
|
|
|
|
|
|
# |
200
|
14
|
|
50
|
|
|
1676
|
my $html_ox=WebDyne::HTML::TreeBuilder->new( |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
api_version => 3, |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
) || return err ('unable to create HTML::TreeBuilder object'); |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
# Tell HTML::TreeBuilder we do *not* want to ignore tags it |
208
|
|
|
|
|
|
|
# considers "unknown". Since we use and tags, |
209
|
|
|
|
|
|
|
# amongst other things, we need these to be in the tree |
210
|
|
|
|
|
|
|
# |
211
|
14
|
|
|
|
|
4281
|
$html_ox->ignore_unknown(0); |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
# Tell it if we also want to see comments, use XML mode |
215
|
|
|
|
|
|
|
# |
216
|
14
|
|
|
|
|
187
|
$html_ox->store_comments($WEBDYNE_STORE_COMMENTS); |
217
|
14
|
|
|
|
|
147
|
$html_ox->xml_mode(1); |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# No space compacting ? |
221
|
|
|
|
|
|
|
# |
222
|
14
|
|
|
|
|
58
|
$html_ox->ignore_ignorable_whitespace($WEBDYNE_COMPILE_IGNORE_WHITESPACE); |
223
|
14
|
|
|
|
|
141
|
$html_ox->no_space_compacting($WEBDYNE_COMPILE_NO_SPACE_COMPACTING); |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# Get code ref closure of file to be parsed |
227
|
|
|
|
|
|
|
# |
228
|
14
|
|
50
|
|
|
160
|
my $parse_cr=$html_ox->parse_fh($html_fh) || |
229
|
|
|
|
|
|
|
return err (); |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# Muck around with strictness of P tags |
233
|
|
|
|
|
|
|
# |
234
|
|
|
|
|
|
|
#$html_ox->implicit_tags(0); |
235
|
14
|
|
|
|
|
64
|
$html_ox->p_strict(1); |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
# Now parse through the file, running eof at end as per HTML::TreeBuilder |
239
|
|
|
|
|
|
|
# man page. |
240
|
|
|
|
|
|
|
# |
241
|
14
|
|
|
|
|
166
|
$html_ox->parse($parse_cr); |
242
|
14
|
|
|
|
|
96
|
$html_ox->eof(); |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# And close the file handle |
246
|
|
|
|
|
|
|
# |
247
|
14
|
|
|
|
|
3888
|
$html_fh->close(); |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
# Now start iterating through the treebuilder object, creating |
251
|
|
|
|
|
|
|
# our own array tree structure. Do this in a separate method that |
252
|
|
|
|
|
|
|
# is rentrant as the tree is descended |
253
|
|
|
|
|
|
|
# |
254
|
14
|
|
|
|
|
240
|
my %meta=( |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
manifest => [\$html_cn] |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
); |
259
|
14
|
|
33
|
|
|
83
|
my $data_ar=$self->parse($html_ox, \%meta) || do { |
260
|
|
|
|
|
|
|
$html_ox->delete; |
261
|
|
|
|
|
|
|
undef $html_ox; |
262
|
|
|
|
|
|
|
return err (); |
263
|
|
|
|
|
|
|
}; |
264
|
14
|
|
|
|
|
34
|
0 && debug("meta after parse %s", Dumper(\%meta)); |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
# Now destroy the HTML::Treebuilder object, or else mem leak occurs |
268
|
|
|
|
|
|
|
# |
269
|
14
|
|
|
|
|
46
|
$html_ox=$html_ox->delete; |
270
|
14
|
|
|
|
|
2519
|
undef $html_ox; |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
# Meta block |
274
|
|
|
|
|
|
|
# |
275
|
14
|
|
50
|
|
|
148
|
my $head_ar=$self->find_node( |
276
|
|
|
|
|
|
|
{ |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
data_ar => $data_ar, |
279
|
|
|
|
|
|
|
tag => 'head', |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
}) || return err (); |
282
|
14
|
|
50
|
|
|
103
|
my $meta_ar=$self->find_node( |
283
|
|
|
|
|
|
|
{ |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
data_ar => $head_ar->[0], |
286
|
|
|
|
|
|
|
tag => 'meta', |
287
|
|
|
|
|
|
|
all_fg => 1, |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
}) || return err (); |
290
|
14
|
|
|
|
|
28
|
foreach my $tag_ar (@{$meta_ar}) { |
|
14
|
|
|
|
|
40
|
|
291
|
2
|
|
50
|
|
|
12
|
my $attr_hr=$tag_ar->[$WEBDYNE_NODE_ATTR_IX] || next; |
292
|
2
|
50
|
|
|
|
8
|
if ($attr_hr->{'name'} eq 'WebDyne') { |
293
|
0
|
|
|
|
|
0
|
my @meta=split(/;/, $attr_hr->{'content'}); |
294
|
0
|
|
|
|
|
0
|
0 && debug('meta %s', Dumper(\@meta)); |
295
|
0
|
|
|
|
|
0
|
foreach my $meta (@meta) { |
296
|
0
|
|
|
|
|
0
|
my ($name, $value)=split(/[=:]/, $meta, 2); |
297
|
0
|
0
|
|
|
|
0
|
defined($value) || ($value=1); |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
# Eval any meta attrs like @{}, %{}.. |
300
|
0
|
|
0
|
|
|
0
|
my $hr=$self->subst_attr(undef, {$name => $value}) || |
301
|
|
|
|
|
|
|
return err (); |
302
|
0
|
|
|
|
|
0
|
$meta{$name}=$hr->{$name}; |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
# Do not want anymore |
306
|
|
|
|
|
|
|
$self->delete_node( |
307
|
|
|
|
|
|
|
{ |
308
|
|
|
|
|
|
|
|
309
|
0
|
0
|
|
|
|
0
|
data_ar => $data_ar, |
310
|
|
|
|
|
|
|
node_ar => $tag_ar |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
}) || return err (); |
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
# Construct final webdyne container |
317
|
|
|
|
|
|
|
# |
318
|
14
|
50
|
|
|
|
56
|
my @container=(keys %meta ? \%meta : undef, $data_ar); |
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
# Quit if user wants to see tree at this stage |
322
|
|
|
|
|
|
|
# |
323
|
14
|
100
|
|
|
|
71
|
$param_hr->{'stage0'} && (return \@container); |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
# Store meta information for this instance so that when perl_init (or code running under perl_init) |
327
|
|
|
|
|
|
|
# runs it can access meta data via $self->meta(); |
328
|
|
|
|
|
|
|
# |
329
|
12
|
50
|
|
|
|
43
|
$self->{'_meta_hr'}=\%meta if keys %meta; |
330
|
12
|
100
|
66
|
|
|
65
|
if ((my $perl_ar=$meta{'perl'}) && !$param_hr->{'noperl'}) { |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# This is inline __PERL__ perl. Must be executed before filter so any filters added by the __PERL__ |
333
|
|
|
|
|
|
|
# block are seen |
334
|
|
|
|
|
|
|
# |
335
|
9
|
|
|
|
|
15
|
my $perl_debug_ar=$meta{'perl_debug'}; |
336
|
9
|
50
|
|
|
|
49
|
$self->perl_init($perl_ar, $perl_debug_ar) || return err (); |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
# Quit if user wants to see tree at this stage |
343
|
|
|
|
|
|
|
# |
344
|
12
|
100
|
|
|
|
102
|
$param_hr->{'stage1'} && (return \@container); |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
# Filter ? |
348
|
|
|
|
|
|
|
# |
349
|
10
|
|
|
|
|
17
|
my @filter=@{$meta{'webdynefilter'}}; |
|
10
|
|
|
|
|
25
|
|
350
|
10
|
50
|
|
|
|
31
|
unless (@filter) { |
351
|
10
|
|
33
|
|
|
89
|
my $filter=$self->{'_filter'} || $r->dir_config('WebDyneFilter'); |
352
|
10
|
50
|
|
|
|
37
|
@filter=split(/\s+/, $filter) if $filter; |
353
|
|
|
|
|
|
|
} |
354
|
10
|
|
|
|
|
19
|
0 && debug('filter %s', Dumper(\@filter)); |
355
|
10
|
50
|
33
|
|
|
35
|
if ((@filter) && !$param_hr->{'nofilter'}) { |
356
|
0
|
|
|
|
|
0
|
local $SIG{'__DIE__'}; |
357
|
0
|
|
|
|
|
0
|
foreach my $filter (@filter) { |
358
|
0
|
|
|
|
|
0
|
$filter=~s/::filter$//; |
359
|
0
|
0
|
|
|
|
0
|
eval("require $filter") || |
360
|
|
|
|
|
|
|
return err ("unable to load filter $filter, " . lcfirst($@)); |
361
|
0
|
0
|
|
|
|
0
|
UNIVERSAL::can($filter, 'filter') || |
362
|
|
|
|
|
|
|
return err ("custom filter '$filter' does not seem to have a 'filter' method to call"); |
363
|
0
|
|
|
|
|
0
|
$filter.='::filter'; |
364
|
0
|
|
0
|
|
|
0
|
$data_ar=$self->$filter($data_ar, \%meta) || return err (); |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
# Optimise tree, first step |
370
|
|
|
|
|
|
|
# |
371
|
10
|
|
50
|
|
|
82
|
$data_ar=$self->optimise_one($data_ar) || return err (); |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
|
374
|
|
|
|
|
|
|
# Quit if user wants to see tree at this stage |
375
|
|
|
|
|
|
|
# |
376
|
10
|
50
|
|
|
|
26
|
$param_hr->{'stage2'} && (return \@container); |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
# Optimise tree, second step |
380
|
|
|
|
|
|
|
# |
381
|
10
|
|
50
|
|
|
48
|
$data_ar=$self->optimise_two($data_ar) || |
382
|
|
|
|
|
|
|
return err (); |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
# Quit if user wants to see tree at this stage |
386
|
|
|
|
|
|
|
# |
387
|
10
|
50
|
|
|
|
32
|
$param_hr->{'stage3'} && (return \@container); |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
# Is there any dynamic data ? If not, set meta html flag to indicate |
391
|
|
|
|
|
|
|
# document is complete HTML |
392
|
|
|
|
|
|
|
# |
393
|
10
|
100
|
|
|
|
15
|
unless (grep {ref($_)} @{$data_ar}) { |
|
99
|
|
|
|
|
145
|
|
|
10
|
|
|
|
|
23
|
|
394
|
1
|
|
|
|
|
3
|
$meta{'html'}=1; |
395
|
|
|
|
|
|
|
} |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
# Construct final webdyne container |
399
|
|
|
|
|
|
|
# |
400
|
10
|
50
|
|
|
|
48
|
@container=(keys %meta ? \%meta : undef, $data_ar); |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
# Quit if user wants to final container |
404
|
|
|
|
|
|
|
# |
405
|
10
|
50
|
|
|
|
36
|
$param_hr->{'stage4'} && (return \@container); |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
# Save compiled object. Can't store code based cache refs, will be |
409
|
|
|
|
|
|
|
# recreated anyway (when reloaded), so delete, save, then restore |
410
|
|
|
|
|
|
|
# |
411
|
10
|
|
|
|
|
16
|
my $cache_cr; |
412
|
10
|
50
|
|
|
|
28
|
if (ref($meta{'cache'}) eq 'CODE') {$cache_cr=delete $meta{'cache'}} |
|
0
|
|
|
|
|
0
|
|
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
# Store to cache file if dest filename given |
416
|
|
|
|
|
|
|
# |
417
|
10
|
50
|
|
|
|
29
|
if ($dest_cn) { |
418
|
0
|
|
|
|
|
0
|
0 && debug("attempting to cache to dest $dest_cn"); |
419
|
0
|
|
|
|
|
0
|
local $SIG{'__DIE__'}; |
420
|
0
|
0
|
|
|
|
0
|
eval {Storable::lock_store(\@container, $dest_cn)} || do { |
|
0
|
|
|
|
|
0
|
|
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
# This used to be fatal |
423
|
|
|
|
|
|
|
# |
424
|
|
|
|
|
|
|
#return err("error storing compiled $html_cn to dest $dest_cn, $@"); |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
# No more, just log warning and continue - no point crashing an otherwise |
428
|
|
|
|
|
|
|
# perfectly good app because we can't write to a directory |
429
|
|
|
|
|
|
|
# |
430
|
|
|
|
|
|
|
$r->log_error( |
431
|
|
|
|
|
|
|
"error storing compiled $html_cn to dest $dest_cn, $@ - " . |
432
|
|
|
|
|
|
|
'please ensure destination directory is writeable.' |
433
|
|
|
|
|
|
|
) |
434
|
0
|
0
|
|
|
|
0
|
unless $Package{'warn_write'}++; |
435
|
0
|
|
|
|
|
0
|
0 && debug("caching FAILED to $dest_cn"); |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
}; |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
else { |
440
|
10
|
|
|
|
|
12
|
0 && debug('no destination file for compile - not caching'); |
441
|
|
|
|
|
|
|
} |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
# Put the cache code ref back again now we have finished storing. |
445
|
|
|
|
|
|
|
# |
446
|
10
|
50
|
|
|
|
23
|
$cache_cr && ($meta{'cache'}=$cache_cr); |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
# Work out the page compile time, log |
450
|
|
|
|
|
|
|
# |
451
|
10
|
|
|
|
|
158
|
my $time_render=sprintf('%0.4f', time()-$time); |
452
|
10
|
|
|
|
|
18
|
0 && debug("form $html_cn compile time $time_render"); |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
# Destroy self |
456
|
|
|
|
|
|
|
# |
457
|
10
|
|
|
|
|
17
|
undef $self; |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
# Done |
461
|
|
|
|
|
|
|
# |
462
|
10
|
|
|
|
|
211
|
return \@container; |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
} |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
sub compile_init { |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
# Used to init package, move ugliness out of handler |
471
|
|
|
|
|
|
|
# |
472
|
1
|
|
|
1
|
0
|
1
|
my $class=shift(); |
473
|
1
|
|
|
|
|
2
|
0 && debug("in compile_init class $class"); |
474
|
|
|
|
|
|
|
|
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
# Init some CGI custom routines we need for correct compilation etc. |
477
|
|
|
|
|
|
|
# |
478
|
1
|
|
|
0
|
|
3
|
*{'CGI::~comment'}=sub {sprintf('', $_[1]->{'text'})}; |
|
1
|
|
|
|
|
10
|
|
|
0
|
|
|
|
|
0
|
|
479
|
1
|
|
|
|
|
3
|
$CGI::XHTML=0; |
480
|
1
|
|
|
|
|
1
|
$CGI::NOSTICKY=1; |
481
|
1
|
|
|
|
|
2
|
*CGI::start_html_cgi=$CGI_start_html_cr; |
482
|
1
|
|
|
|
|
1
|
*CGI::end_html_cgi=$CGI_end_html_cr; |
483
|
|
|
|
|
|
|
*CGI::start_html=sub { |
484
|
10
|
|
|
10
|
|
28
|
my ($self, $attr_hr)=@_; |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
#CORE::print Data::Dumper::Dumper($attr_hr); |
487
|
10
|
50
|
|
|
|
23
|
keys %{$attr_hr} || ($attr_hr=$WEBDYNE_HTML_PARAM); |
|
10
|
|
|
|
|
27
|
|
488
|
10
|
|
|
|
|
23
|
my $html_attr=join(' ', map {qq($_="$attr_hr->{$_}")} keys %{$attr_hr}); |
|
10
|
|
|
|
|
64
|
|
|
10
|
|
|
|
|
22
|
|
489
|
10
|
50
|
|
|
|
69
|
return $WEBDYNE_DTD . ($html_attr ? "" : ''); |
490
|
1
|
|
|
|
|
4
|
}; |
491
|
|
|
|
|
|
|
*CGI::end_html=sub { |
492
|
10
|
|
|
10
|
|
44
|
'' |
493
|
1
|
|
|
|
|
4
|
}; |
494
|
|
|
|
|
|
|
*CGI::html=sub { |
495
|
1
|
|
|
1
|
|
5
|
my ($self, $attr_hr, @html)=@_; |
496
|
1
|
|
|
|
|
7
|
return join(undef, CGI->start_html($attr_hr), @html, $self->end_html); |
497
|
1
|
|
|
|
|
14
|
}; |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
# Get rid of the simple escape routine, which mangles attribute characters we |
501
|
|
|
|
|
|
|
# want to keep |
502
|
|
|
|
|
|
|
# |
503
|
1
|
|
|
4
|
|
20
|
*CGI::Util::simple_escape=sub {shift()}; |
|
4
|
|
|
|
|
124
|
|
504
|
|
|
|
|
|
|
|
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
# Get rid of compiler warnings on start and end routines |
507
|
|
|
|
|
|
|
# |
508
|
|
|
|
|
|
|
#0 && *CGI::start_html; |
509
|
|
|
|
|
|
|
#0 && *CGI::end_html; |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
# Extend CGI with any missing tags |
513
|
|
|
|
|
|
|
# |
514
|
1
|
50
|
|
|
|
6
|
if (UNIVERSAL::can(CGI, '_tag_func')) { |
515
|
1
|
|
|
|
|
2
|
foreach my $tag (@CGI_Tag_Extend) { |
516
|
1
|
|
|
0
|
|
3
|
*{"CGI::$tag"} = sub { return &CGI::_tag_func($tag,@_); }; |
|
1
|
|
|
|
|
4
|
|
|
0
|
|
|
|
|
0
|
|
517
|
1
|
|
|
|
|
2
|
foreach my $start_end ( qw/start end/ ) { |
518
|
2
|
|
|
|
|
4
|
my $start_end_function = "${start_end}_${tag}"; |
519
|
2
|
|
|
0
|
|
4
|
*{"CGI::$start_end_function"} = sub { return &CGI::_tag_func($start_end_function,@_); }; |
|
2
|
|
|
|
|
8
|
|
|
0
|
|
|
|
|
0
|
|
520
|
|
|
|
|
|
|
} |
521
|
|
|
|
|
|
|
} |
522
|
|
|
|
|
|
|
} |
523
|
|
|
|
|
|
|
|
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
# All done |
526
|
|
|
|
|
|
|
# |
527
|
1
|
|
|
|
|
6
|
return \undef; |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
} |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
sub optimise_one { |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
|
536
|
|
|
|
|
|
|
# Optimise a data tree |
537
|
|
|
|
|
|
|
# |
538
|
12
|
|
|
12
|
0
|
38
|
my ($self, $data_ar)=@_; |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
# Debug |
542
|
|
|
|
|
|
|
# |
543
|
12
|
|
|
|
|
19
|
0 && debug('optimise stage one'); |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
# Get CGI object |
547
|
|
|
|
|
|
|
# |
548
|
12
|
|
50
|
|
|
43
|
my $cgi_or=$self->{'_CGI'} || |
549
|
|
|
|
|
|
|
return err ("unable to get CGI object from self ref"); |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
# Recursive anon sub to do the render |
553
|
|
|
|
|
|
|
# |
554
|
|
|
|
|
|
|
my $compile_cr=sub { |
555
|
|
|
|
|
|
|
|
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
# Get self ref, node array |
558
|
|
|
|
|
|
|
# |
559
|
176
|
|
|
176
|
|
274
|
my ($compile_cr, $data_ar)=@_; |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
# Only do if we have children, if we do a foreach over nonexistent child node |
563
|
|
|
|
|
|
|
# it will spring into existance as empty array ref, which we then have to |
564
|
|
|
|
|
|
|
# wastefully store |
565
|
|
|
|
|
|
|
# |
566
|
176
|
100
|
|
|
|
302
|
if ($data_ar->[$WEBDYNE_NODE_CHLD_IX]) { |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
# Process sub nodes to get child html data |
570
|
|
|
|
|
|
|
# |
571
|
132
|
|
|
|
|
162
|
foreach my $data_chld_ix (0..$#{$data_ar->[$WEBDYNE_NODE_CHLD_IX]}) { |
|
132
|
|
|
|
|
267
|
|
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
# Get data child |
575
|
|
|
|
|
|
|
# |
576
|
219
|
|
|
|
|
357
|
my $data_chld_ar=$data_ar->[$WEBDYNE_NODE_CHLD_IX][$data_chld_ix]; |
577
|
219
|
|
|
|
|
256
|
0 && debug("data_chld_ar $data_chld_ar"); |
578
|
|
|
|
|
|
|
|
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
# If ref, recursivly run through compile process |
581
|
|
|
|
|
|
|
# |
582
|
219
|
100
|
|
|
|
388
|
ref($data_chld_ar) && do { |
583
|
|
|
|
|
|
|
|
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
# Run through compile sub-process |
586
|
|
|
|
|
|
|
# |
587
|
164
|
|
50
|
|
|
380
|
my $data_chld_xv=$compile_cr->($compile_cr, $data_chld_ar) || |
588
|
|
|
|
|
|
|
return err (); |
589
|
164
|
100
|
|
|
|
335
|
if (ref($data_chld_xv) eq 'SCALAR') { |
590
|
42
|
|
|
|
|
49
|
$data_chld_xv=${$data_chld_xv} |
|
42
|
|
|
|
|
69
|
|
591
|
|
|
|
|
|
|
} |
592
|
|
|
|
|
|
|
|
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
# Replace in tree |
595
|
|
|
|
|
|
|
# |
596
|
164
|
|
|
|
|
338
|
$data_ar->[$WEBDYNE_NODE_CHLD_IX][$data_chld_ix]=$data_chld_xv; |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
} |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
} |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
# Get this node tag and attrs |
606
|
|
|
|
|
|
|
# |
607
|
|
|
|
|
|
|
my ($html_tag, $attr_hr)= |
608
|
176
|
|
|
|
|
219
|
@{$data_ar}[$WEBDYNE_NODE_NAME_IX, $WEBDYNE_NODE_ATTR_IX]; |
|
176
|
|
|
|
|
320
|
|
609
|
176
|
|
|
|
|
239
|
0 && debug("tag $html_tag, attr %s", Dumper($attr_hr)); |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
# Store data block as hint to error handler should something go wrong |
612
|
|
|
|
|
|
|
# |
613
|
176
|
|
|
|
|
284
|
$self->{'_data_ar'}=$data_ar; |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
# Check to see if any of the attributes will require a subst to be carried out |
617
|
|
|
|
|
|
|
# |
618
|
176
|
|
|
|
|
215
|
my @subst_oper; |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
#my $subst_fg=grep { $_=~/([$|@|%|!|+|^|*]{1})\{([$|@|%|!|+|^|*]?)(.*?)\2\}/s && push (@subst_oper, $1) } values %{$attr_hr}; |
621
|
|
|
|
|
|
|
#my $subst_fg=grep { $_=~/([\$@%!+*^]){1}{(\1?)(.*?)\2}/ && push (@subst_oper, $1) } values %{$attr_hr}; |
622
|
|
|
|
|
|
|
my $subst_fg=$data_ar->[$WEBDYNE_NODE_SBST_IX] || delete $attr_hr->{'subst'} || |
623
|
176
|
|
66
|
|
|
560
|
grep {$_=~/([\$@%!+*^]){1}{(\1?)(.*?)\2}/ && push(@subst_oper, $1)} values %{$attr_hr}; |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
# Do not subst comments |
627
|
|
|
|
|
|
|
# |
628
|
176
|
50
|
|
|
|
320
|
($html_tag=~/~comment$/) && ($subst_fg=undef); |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
# If subst_fg present, means we must do a subst on attr vars. Flag |
632
|
|
|
|
|
|
|
# |
633
|
176
|
100
|
|
|
|
309
|
$subst_fg && ($data_ar->[$WEBDYNE_NODE_SBST_IX]=1); |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
# A CGI tag can be marked static, means that we can pre-render it for efficieny |
637
|
|
|
|
|
|
|
# |
638
|
176
|
|
|
|
|
220
|
my $static_fg=$attr_hr->{'static'}; |
639
|
176
|
|
|
|
|
194
|
0 && debug("tag $html_tag, static_fg $static_fg, subst_fg $subst_fg, subst_oper %s", Dumper(\@subst_oper)); |
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
# If static, but subst requires an eval, we can do now *only* if @ or % tags though, |
643
|
|
|
|
|
|
|
# and some !'s that do not need request object etc. Cannot do on $ |
644
|
|
|
|
|
|
|
# |
645
|
176
|
50
|
33
|
|
|
279
|
if ($static_fg && $subst_fg) { |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
# Cannot optimes subst values with ${value}, must do later |
649
|
|
|
|
|
|
|
# |
650
|
0
|
0
|
|
|
|
0
|
(grep {$_ eq '$'} @subst_oper) && return $data_ar; |
|
0
|
|
|
|
|
0
|
|
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
# Do it |
654
|
|
|
|
|
|
|
# |
655
|
0
|
|
0
|
|
|
0
|
$attr_hr=$self->WebDyne::subst_attr(undef, $attr_hr) || |
656
|
|
|
|
|
|
|
return err (); |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
} |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
# If not special WebDyne tag, see if we can render node |
662
|
|
|
|
|
|
|
# |
663
|
|
|
|
|
|
|
#if ((!$CGI_TAG_WEBDYNE{$html_tag} && !$CGI_TAG_IMPLICIT{$html_tag} && !$subst_fg) || $static_fg) { |
664
|
176
|
100
|
100
|
|
|
606
|
if ((!$CGI_TAG_WEBDYNE{$html_tag} && !$subst_fg) || $static_fg) { |
|
|
|
66
|
|
|
|
|
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
|
667
|
|
|
|
|
|
|
# Check all child nodes to see if ref or scalar |
668
|
|
|
|
|
|
|
# |
669
|
|
|
|
|
|
|
my $ref_fv=$data_ar->[$WEBDYNE_NODE_CHLD_IX] && |
670
|
105
|
|
100
|
|
|
202
|
grep {ref($_)} @{$data_ar->[$WEBDYNE_NODE_CHLD_IX]}; |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
|
673
|
|
|
|
|
|
|
# If all scalars (ie no refs found)t, we can simply pre render all child nodes |
674
|
|
|
|
|
|
|
# |
675
|
105
|
100
|
|
|
|
197
|
unless ($ref_fv) { |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
# Done with static tag, delete so not rendered |
679
|
|
|
|
|
|
|
# |
680
|
45
|
|
|
|
|
63
|
delete $attr_hr->{'static'}; |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
# Special case. If WebDyne tag and static, render now via WebDyne. Experimental |
684
|
|
|
|
|
|
|
# |
685
|
45
|
50
|
|
|
|
91
|
if ($CGI_TAG_WEBDYNE{$html_tag}) { |
686
|
|
|
|
|
|
|
|
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
# Render via WebDyne |
689
|
|
|
|
|
|
|
# |
690
|
0
|
|
|
|
|
0
|
0 && debug("about to render tag $html_tag, attr %s", Dumper($attr_hr)); |
691
|
0
|
|
0
|
|
|
0
|
my $html_sr=$self->$html_tag($data_ar, $attr_hr) || |
692
|
|
|
|
|
|
|
return err (); |
693
|
0
|
|
|
|
|
0
|
0 && debug("html *$html_sr*, *${$html_sr}*"); |
694
|
0
|
|
|
|
|
0
|
return $html_sr; |
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
} |
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
# Wrap up in our HTML tag. Do in eval so we can catch errors from invalid tags etc |
701
|
|
|
|
|
|
|
# |
702
|
45
|
100
|
|
|
|
93
|
my @data_child_ar=$data_ar->[$WEBDYNE_NODE_CHLD_IX] ? @{$data_ar->[$WEBDYNE_NODE_CHLD_IX]} : undef; |
|
29
|
|
|
|
|
66
|
|
703
|
45
|
|
50
|
|
|
66
|
my $html=eval { |
704
|
|
|
|
|
|
|
$cgi_or->$html_tag(grep {$_} $attr_hr, join(undef, @data_child_ar)) |
705
|
|
|
|
|
|
|
} || |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
# Use errsubst as CGI may have DIEd during eval and be caught by WebDyne SIG handler |
708
|
|
|
|
|
|
|
return errsubst( |
709
|
|
|
|
|
|
|
"CGI tag '<$html_tag>': %s", |
710
|
|
|
|
|
|
|
$@ || "undefined error rendering tag '$html_tag'" |
711
|
|
|
|
|
|
|
); |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
# Debug |
715
|
|
|
|
|
|
|
# |
716
|
|
|
|
|
|
|
#0 && debug("html *$html*"); |
717
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
# Done |
720
|
|
|
|
|
|
|
# |
721
|
45
|
|
|
|
|
2721
|
return \$html; |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
} |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
} |
726
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
# Return current node, perhaps now somewhat optimised |
729
|
|
|
|
|
|
|
# |
730
|
|
|
|
|
|
|
$data_ar |
731
|
|
|
|
|
|
|
|
732
|
12
|
|
|
|
|
129
|
}; |
|
131
|
|
|
|
|
387
|
|
733
|
|
|
|
|
|
|
|
734
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
# Run it |
736
|
|
|
|
|
|
|
# |
737
|
12
|
|
50
|
|
|
39
|
$data_ar=$compile_cr->($compile_cr, $data_ar) || return err (); |
738
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
# If scalar ref returned it is all HTML - return as plain scalar |
741
|
|
|
|
|
|
|
# |
742
|
12
|
100
|
|
|
|
35
|
if (ref($data_ar) eq 'SCALAR') { |
743
|
3
|
|
|
|
|
6
|
$data_ar=${$data_ar} |
|
3
|
|
|
|
|
7
|
|
744
|
|
|
|
|
|
|
} |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
# Done |
748
|
|
|
|
|
|
|
# |
749
|
12
|
|
|
|
|
215
|
$data_ar; |
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
} |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
sub optimise_two { |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
# Optimise a data tree |
758
|
|
|
|
|
|
|
# |
759
|
12
|
|
|
12
|
0
|
25
|
my ($self, $data_ar)=@_; |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
# Debug |
763
|
|
|
|
|
|
|
# |
764
|
12
|
|
|
|
|
16
|
0 && debug('optimise stage two'); |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
# Get CGI object |
768
|
|
|
|
|
|
|
# |
769
|
12
|
|
50
|
|
|
38
|
my $cgi_or=$self->{'_CGI'} || |
770
|
|
|
|
|
|
|
return err ("unable to get CGI object from self ref"); |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
# Recursive anon sub to do the render |
774
|
|
|
|
|
|
|
# |
775
|
|
|
|
|
|
|
my $compile_cr=sub { |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
# Get self ref, node array |
779
|
|
|
|
|
|
|
# |
780
|
133
|
|
|
133
|
|
213
|
my ($compile_cr, $data_ar, $data_uppr_ar)=@_; |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
# Only do if we have children, if do a foreach over nonexistent child node |
784
|
|
|
|
|
|
|
# it will spring into existance as empty array ref, which we then have to |
785
|
|
|
|
|
|
|
# wastefully store |
786
|
|
|
|
|
|
|
# |
787
|
133
|
100
|
|
|
|
241
|
if ($data_ar->[$WEBDYNE_NODE_CHLD_IX]) { |
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
# Process sub nodes to get child html data |
791
|
|
|
|
|
|
|
# |
792
|
|
|
|
|
|
|
my @data_child_ar=$data_ar->[$WEBDYNE_NODE_CHLD_IX] |
793
|
|
|
|
|
|
|
? |
794
|
105
|
50
|
|
|
|
169
|
@{$data_ar->[$WEBDYNE_NODE_CHLD_IX]} |
|
105
|
|
|
|
|
193
|
|
795
|
|
|
|
|
|
|
: undef; |
796
|
105
|
|
|
|
|
143
|
foreach my $data_chld_ar (@data_child_ar) { |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
# Debug |
800
|
|
|
|
|
|
|
# |
801
|
|
|
|
|
|
|
#0 && debug("found child node $data_chld_ar"); |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
# If ref, run through compile process recursively |
805
|
|
|
|
|
|
|
# |
806
|
188
|
100
|
|
|
|
315
|
ref($data_chld_ar) && do { |
807
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
# Run through compile sub-process |
810
|
|
|
|
|
|
|
# |
811
|
122
|
|
50
|
|
|
349
|
$data_ar=$compile_cr->($compile_cr, $data_chld_ar, $data_ar) || |
812
|
|
|
|
|
|
|
return err (); |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
} |
815
|
|
|
|
|
|
|
|
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
} |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
} |
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
# Get this tag and attrs |
823
|
|
|
|
|
|
|
# |
824
|
|
|
|
|
|
|
my ($html_tag, $attr_hr)= |
825
|
133
|
|
|
|
|
189
|
@{$data_ar}[$WEBDYNE_NODE_NAME_IX, $WEBDYNE_NODE_ATTR_IX]; |
|
133
|
|
|
|
|
251
|
|
826
|
133
|
|
|
|
|
178
|
0 && debug("tag $html_tag"); |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
# Store data block as hint to error handler should something go wrong |
830
|
|
|
|
|
|
|
# |
831
|
133
|
|
|
|
|
189
|
$self->{'_data_ar'}=$data_ar; |
832
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
# Check if this tag attributes will need substitution (eg ${foo}); |
835
|
|
|
|
|
|
|
# |
836
|
|
|
|
|
|
|
#my $subst_fg=grep { $_=~/([$|@|%|!|+|^|*]{1})\{([$|@|%|!|+|^|*]?)(.*?)\2\}/s } values %{$attr_hr}; |
837
|
|
|
|
|
|
|
my $subst_fg=$data_ar->[$WEBDYNE_NODE_SBST_IX] || delete $attr_hr->{'subst'} || |
838
|
133
|
|
33
|
|
|
399
|
grep {$_=~/([\$@%!+*^]){1}{(\1?)(.*?)\2}/so} values %{$attr_hr}; |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
# If subst_fg present, means we must do a subst on attr vars. Flag, also get static flag |
842
|
|
|
|
|
|
|
# |
843
|
133
|
100
|
|
|
|
238
|
$subst_fg && ($data_ar->[$WEBDYNE_NODE_SBST_IX]=1); |
844
|
133
|
|
|
|
|
179
|
my $static_fg=delete $attr_hr->{'static'}; |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
# If not special WebDyne tag, and no dynamic params we can render this node into |
848
|
|
|
|
|
|
|
# its final HTML format |
849
|
|
|
|
|
|
|
# |
850
|
133
|
100
|
100
|
|
|
811
|
if (!$CGI_TAG_WEBDYNE{$html_tag} && !$CGI_TAG_IMPLICIT{$html_tag} && $data_uppr_ar && !$subst_fg) { |
|
|
50
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
# Get nodes into array now, removes risk of iterating over shifting ground |
854
|
|
|
|
|
|
|
# |
855
|
|
|
|
|
|
|
my @data_child_ar=$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX] |
856
|
|
|
|
|
|
|
? |
857
|
51
|
50
|
|
|
|
89
|
@{$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX]} |
|
51
|
|
|
|
|
120
|
|
858
|
|
|
|
|
|
|
: undef; |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
# Get uppr node |
862
|
|
|
|
|
|
|
# |
863
|
51
|
|
|
|
|
101
|
foreach my $data_chld_ix (0..$#data_child_ar) { |
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
# Get node, skip unless ref |
867
|
|
|
|
|
|
|
# |
868
|
297
|
|
|
|
|
345
|
my $data_chld_ar=$data_child_ar[$data_chld_ix]; |
869
|
297
|
100
|
|
|
|
451
|
ref($data_chld_ar) || next; |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
# Debug |
873
|
|
|
|
|
|
|
# |
874
|
|
|
|
|
|
|
#0 && debug("looking at node $data_chld_ix, $data_chld_ar vs $data_ar"); |
875
|
|
|
|
|
|
|
|
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
# Skip unless eq us |
878
|
|
|
|
|
|
|
# |
879
|
159
|
100
|
|
|
|
300
|
next unless ($data_chld_ar eq $data_ar); |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
# Get start and end tag methods |
883
|
|
|
|
|
|
|
# |
884
|
51
|
|
|
|
|
118
|
my ($html_tag_start, $html_tag_end)= |
885
|
|
|
|
|
|
|
("start_${html_tag}", "end_${html_tag}"); |
886
|
|
|
|
|
|
|
|
887
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
# Translate tags into HTML |
889
|
|
|
|
|
|
|
# |
890
|
|
|
|
|
|
|
my ($html_start, $html_end)=map { |
891
|
51
|
50
|
0
|
|
|
90
|
eval { |
|
102
|
|
|
|
|
2175
|
|
892
|
102
|
|
|
|
|
137
|
$cgi_or->$_(grep {$_} $attr_hr) |
|
102
|
|
|
|
|
385
|
|
893
|
|
|
|
|
|
|
} || |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
# Use errsubst as CGI may have DIEd during eval and be caught by WebDyne SIG handler |
896
|
|
|
|
|
|
|
return errsubst( |
897
|
|
|
|
|
|
|
"CGI tag '<$_>' error- %s", |
898
|
|
|
|
|
|
|
$@ || "undefined error rendering tag '$_'" |
899
|
|
|
|
|
|
|
); |
900
|
|
|
|
|
|
|
} ($html_tag_start, $html_tag_end); |
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
# Splice start and end tags for this HTML into appropriate place |
904
|
|
|
|
|
|
|
# |
905
|
51
|
|
|
|
|
94
|
splice @{$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX]}, $data_chld_ix, 1, |
906
|
|
|
|
|
|
|
$html_start, |
907
|
51
|
|
|
|
|
1744
|
@{$data_ar->[$WEBDYNE_NODE_CHLD_IX]}, |
|
51
|
|
|
|
|
186
|
|
908
|
|
|
|
|
|
|
$html_end; |
909
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
# Done, no need to iterate any more |
911
|
|
|
|
|
|
|
# |
912
|
51
|
|
|
|
|
104
|
last; |
913
|
|
|
|
|
|
|
|
914
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
} |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
# Concatenate all non ref values in the parent. Var to hold results |
919
|
|
|
|
|
|
|
# |
920
|
51
|
|
|
|
|
66
|
my @data_uppr; |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
# Repopulate data child array, as probably changed in above foreach |
924
|
|
|
|
|
|
|
# block. |
925
|
|
|
|
|
|
|
# |
926
|
|
|
|
|
|
|
@data_child_ar=$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX] |
927
|
|
|
|
|
|
|
? |
928
|
51
|
50
|
|
|
|
95
|
@{$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX]} |
|
51
|
|
|
|
|
221
|
|
929
|
|
|
|
|
|
|
: undef; |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
#@data_child_ar=@{$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX]}; |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
# Begin concatenation |
935
|
|
|
|
|
|
|
# |
936
|
51
|
|
|
|
|
120
|
foreach my $data_chld_ix (0..$#data_child_ar) { |
937
|
|
|
|
|
|
|
|
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
# Get child |
940
|
|
|
|
|
|
|
# |
941
|
627
|
|
|
|
|
786
|
my $data_chld_ar=$data_child_ar[$data_chld_ix]; |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
# Can we concatenate with above node |
945
|
|
|
|
|
|
|
# |
946
|
627
|
100
|
100
|
|
|
1762
|
if (@data_uppr && !ref($data_chld_ar) && !ref($data_uppr[$#data_uppr])) { |
|
|
|
100
|
|
|
|
|
947
|
|
|
|
|
|
|
|
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
# Yes, concatentate |
950
|
|
|
|
|
|
|
# |
951
|
79
|
|
|
|
|
157
|
$data_uppr[$#data_uppr].=$data_chld_ar; |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
} |
954
|
|
|
|
|
|
|
else { |
955
|
|
|
|
|
|
|
|
956
|
|
|
|
|
|
|
# No, push onto new data_uppr array |
957
|
|
|
|
|
|
|
# |
958
|
548
|
|
|
|
|
942
|
push @data_uppr, $data_chld_ar; |
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
} |
961
|
|
|
|
|
|
|
} |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
# Replace with new optimised array |
965
|
|
|
|
|
|
|
# |
966
|
51
|
|
|
|
|
156
|
$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX]=\@data_uppr; |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
} |
970
|
|
|
|
|
|
|
elsif ($CGI_TAG_WEBDYNE{$html_tag} && $data_uppr_ar && $static_fg) { |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
|
973
|
|
|
|
|
|
|
# Now render to make HTML and modify the data arrat above us with the rendered code |
974
|
|
|
|
|
|
|
# |
975
|
0
|
|
0
|
|
|
0
|
my $html_sr=$self->render( |
976
|
|
|
|
|
|
|
{ |
977
|
|
|
|
|
|
|
data => [$data_ar], |
978
|
|
|
|
|
|
|
}) || return err (); |
979
|
|
|
|
|
|
|
my @data_child_ar=$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX] |
980
|
|
|
|
|
|
|
? |
981
|
0
|
0
|
|
|
|
0
|
@{$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX]} |
|
0
|
|
|
|
|
0
|
|
982
|
|
|
|
|
|
|
: undef; |
983
|
0
|
|
|
|
|
0
|
foreach my $ix (0..$#data_child_ar) { |
984
|
0
|
0
|
|
|
|
0
|
if ($data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX][$ix] eq $data_ar) { |
985
|
0
|
|
|
|
|
0
|
$data_uppr_ar->[$WEBDYNE_NODE_CHLD_IX][$ix]=${$html_sr}; |
|
0
|
|
|
|
|
0
|
|
986
|
0
|
|
|
|
|
0
|
last; |
987
|
|
|
|
|
|
|
} |
988
|
|
|
|
|
|
|
} |
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
} |
992
|
|
|
|
|
|
|
elsif (!$data_uppr_ar) { |
993
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
|
995
|
|
|
|
|
|
|
# Must be at top node, as nothing above us, |
996
|
|
|
|
|
|
|
# get start and end tag methods |
997
|
|
|
|
|
|
|
# |
998
|
11
|
|
|
|
|
45
|
my ($html_tag_start, $html_tag_end)= |
999
|
|
|
|
|
|
|
("start_${html_tag}", "end_${html_tag}"); |
1000
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
# Get resulting start and ending HTML |
1003
|
|
|
|
|
|
|
# |
1004
|
|
|
|
|
|
|
my ($html_start, $html_end)=map { |
1005
|
11
|
50
|
0
|
|
|
26
|
eval { |
|
22
|
|
|
|
|
107
|
|
1006
|
22
|
|
|
|
|
32
|
$cgi_or->$_(grep {$_} $attr_hr) |
|
22
|
|
|
|
|
107
|
|
1007
|
|
|
|
|
|
|
} || |
1008
|
|
|
|
|
|
|
return errsubst( |
1009
|
|
|
|
|
|
|
"CGI tag '<$_>': %s", |
1010
|
|
|
|
|
|
|
$@ || "undefined error rendering tag '$_'" |
1011
|
|
|
|
|
|
|
); |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
#return err("$@" || "no html returned from tag $_") |
1014
|
|
|
|
|
|
|
} ($html_tag_start, $html_tag_end); |
1015
|
|
|
|
|
|
|
my @data_child_ar=$data_ar->[$WEBDYNE_NODE_CHLD_IX] |
1016
|
|
|
|
|
|
|
? |
1017
|
11
|
50
|
|
|
|
90
|
@{$data_ar->[$WEBDYNE_NODE_CHLD_IX]} |
|
11
|
|
|
|
|
37
|
|
1018
|
|
|
|
|
|
|
: undef; |
1019
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
# Place start and end tags for this HTML into appropriate place |
1021
|
|
|
|
|
|
|
# |
1022
|
11
|
|
|
|
|
33
|
my @data=( |
1023
|
|
|
|
|
|
|
$html_start, |
1024
|
|
|
|
|
|
|
@data_child_ar, |
1025
|
|
|
|
|
|
|
$html_end |
1026
|
|
|
|
|
|
|
); |
1027
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
|
1029
|
|
|
|
|
|
|
# Concatenate all non ref vals |
1030
|
|
|
|
|
|
|
# |
1031
|
11
|
|
|
|
|
14
|
my @data_new; |
1032
|
11
|
|
|
|
|
49
|
foreach my $data_chld_ix (0..$#data) { |
1033
|
|
|
|
|
|
|
|
1034
|
121
|
100
|
100
|
|
|
380
|
if ($data_chld_ix && !ref($data[$data_chld_ix]) && !(ref($data[$data_chld_ix-1]))) { |
|
|
|
100
|
|
|
|
|
1035
|
21
|
|
|
|
|
51
|
$data_new[$#data_new].=$data[$data_chld_ix]; |
1036
|
|
|
|
|
|
|
} |
1037
|
|
|
|
|
|
|
else { |
1038
|
100
|
|
|
|
|
168
|
push @data_new, $data[$data_chld_ix] |
1039
|
|
|
|
|
|
|
} |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
} |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
|
1044
|
|
|
|
|
|
|
# Return completed array |
1045
|
|
|
|
|
|
|
# |
1046
|
11
|
|
|
|
|
29
|
$data_uppr_ar=\@data_new; |
1047
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
|
1049
|
|
|
|
|
|
|
} |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
# Return current node |
1053
|
|
|
|
|
|
|
# |
1054
|
133
|
|
|
|
|
691
|
return $data_uppr_ar; |
1055
|
|
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
|
1057
|
12
|
|
|
|
|
124
|
}; |
1058
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
# Run it, return whatever it does, allowing for the special case that first stage |
1061
|
|
|
|
|
|
|
# optimisation found no special tags, and precompiled the whole array into a |
1062
|
|
|
|
|
|
|
# single HTML string. In which case return as array ref to allow for correct storage |
1063
|
|
|
|
|
|
|
# and rendering. |
1064
|
|
|
|
|
|
|
# |
1065
|
12
|
100
|
33
|
|
|
70
|
return ref($data_ar) |
1066
|
|
|
|
|
|
|
? |
1067
|
|
|
|
|
|
|
$compile_cr->($compile_cr, $data_ar, undef) || err () |
1068
|
|
|
|
|
|
|
: |
1069
|
|
|
|
|
|
|
[$data_ar]; |
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
} |
1073
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
sub parse { |
1076
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
|
1078
|
|
|
|
|
|
|
# A recusively called method to parse a HTML::Treebuilder tree. content is an |
1079
|
|
|
|
|
|
|
# array ref of the HTML entity contents, return custom array tree from that |
1080
|
|
|
|
|
|
|
# structure |
1081
|
|
|
|
|
|
|
# |
1082
|
213
|
|
|
213
|
0
|
333
|
my ($self, $html_or, $meta_hr)=@_; |
1083
|
213
|
|
|
|
|
241
|
my ($line_no, $line_no_tag_end)=@{$html_or}{'_line_no', '_line_no_tag_end'}; |
|
213
|
|
|
|
|
350
|
|
1084
|
213
|
|
|
|
|
297
|
my $html_fn_sr=$meta_hr->{'manifest'}[0]; |
1085
|
213
|
|
|
|
|
240
|
0 && debug("parse $self, $html_or line_no $line_no line_no_tag_end $line_no_tag_end"); |
1086
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
#0 && debug("parse $html_or, %s", Dumper($html_or)); |
1088
|
|
|
|
|
|
|
|
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
# Create array to hold this data node |
1091
|
|
|
|
|
|
|
# |
1092
|
213
|
|
|
|
|
248
|
my @data; |
1093
|
213
|
|
|
|
|
592
|
@data[ |
1094
|
|
|
|
|
|
|
$WEBDYNE_NODE_NAME_IX, |
1095
|
|
|
|
|
|
|
$WEBDYNE_NODE_ATTR_IX, |
1096
|
|
|
|
|
|
|
$WEBDYNE_NODE_CHLD_IX, |
1097
|
|
|
|
|
|
|
$WEBDYNE_NODE_SBST_IX, |
1098
|
|
|
|
|
|
|
$WEBDYNE_NODE_LINE_IX, |
1099
|
|
|
|
|
|
|
$WEBDYNE_NODE_LINE_TAG_END_IX, |
1100
|
|
|
|
|
|
|
$WEBDYNE_NODE_SRCE_IX |
1101
|
|
|
|
|
|
|
]=( |
1102
|
|
|
|
|
|
|
#undef, undef, undef, undef, $line_no, $line_no_tag_end, $meta_hr->{'manifest'}[0] |
1103
|
|
|
|
|
|
|
undef, undef, undef, undef, $line_no, $line_no_tag_end, $html_fn_sr |
1104
|
|
|
|
|
|
|
); |
1105
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
# Get tag |
1108
|
|
|
|
|
|
|
# |
1109
|
213
|
|
|
|
|
405
|
my $html_tag=$html_or->tag(); |
1110
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
# Check special cases like tr that need to be uppercased (Tr) to work correctly |
1113
|
|
|
|
|
|
|
# in CGI |
1114
|
|
|
|
|
|
|
# |
1115
|
213
|
|
33
|
|
|
1376
|
$html_tag=$CGI_Tag_Ucase{$html_tag} || $html_tag; |
1116
|
|
|
|
|
|
|
|
1117
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
# Check valid |
1119
|
|
|
|
|
|
|
# |
1120
|
213
|
50
|
66
|
|
|
923
|
unless (UNIVERSAL::can('CGI', $html_tag) || $CGI_TAG_WEBDYNE{$html_tag}) { |
1121
|
0
|
|
|
|
|
0
|
return err ("unknown CGI/WebDyne tag: <$html_tag>, line $line_no in source file ${$html_fn_sr}") |
|
0
|
|
|
|
|
0
|
|
1122
|
|
|
|
|
|
|
} |
1123
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
|
1125
|
|
|
|
|
|
|
# Get tag attr |
1126
|
|
|
|
|
|
|
# |
1127
|
213
|
100
|
|
|
|
309
|
if (my %attr=map {$_ => $html_or->{$_}} (grep {!/^_/} keys %{$html_or})) { |
|
120
|
|
|
|
|
369
|
|
|
1406
|
|
|
|
|
2964
|
|
|
213
|
|
|
|
|
543
|
|
1128
|
|
|
|
|
|
|
|
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
# Save tagm attr into node |
1131
|
|
|
|
|
|
|
# |
1132
|
|
|
|
|
|
|
#@data[$WEBDYNE_NODE_NAME_IX, $WEBDYNE_NODE_ATTR_IX]=($html_tag, \%attr); |
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
# Is this the inline perl __PERL__ block ? |
1136
|
|
|
|
|
|
|
# |
1137
|
91
|
100
|
66
|
|
|
232
|
if ($html_or->{'_code'} && $attr{'perl'}) { |
1138
|
9
|
|
|
|
|
17
|
push @{$meta_hr->{'perl'}}, \$attr{'perl'}; |
|
9
|
|
|
|
|
23
|
|
1139
|
9
|
|
|
|
|
16
|
push @{$meta_hr->{'perl_debug'}}, [$line_no, $html_fn_sr]; |
|
9
|
|
|
|
|
28
|
|
1140
|
|
|
|
|
|
|
} |
1141
|
|
|
|
|
|
|
else { |
1142
|
82
|
|
|
|
|
165
|
@data[$WEBDYNE_NODE_NAME_IX, $WEBDYNE_NODE_ATTR_IX]=($html_tag, \%attr); |
1143
|
|
|
|
|
|
|
} |
1144
|
|
|
|
|
|
|
|
1145
|
|
|
|
|
|
|
} |
1146
|
|
|
|
|
|
|
else { |
1147
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
# No attr, just save tag |
1150
|
|
|
|
|
|
|
# |
1151
|
122
|
|
|
|
|
210
|
$data[$WEBDYNE_NODE_NAME_IX]=$html_tag; |
1152
|
|
|
|
|
|
|
|
1153
|
|
|
|
|
|
|
} |
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
|
1156
|
|
|
|
|
|
|
# Child nodes |
1157
|
|
|
|
|
|
|
# |
1158
|
213
|
|
|
|
|
299
|
my @html_child=@{$html_or->content()}; |
|
213
|
|
|
|
|
405
|
|
1159
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
|
1161
|
|
|
|
|
|
|
# Get child, parse down the tree |
1162
|
|
|
|
|
|
|
# |
1163
|
213
|
|
|
|
|
762
|
foreach my $html_child_or (@html_child) { |
1164
|
|
|
|
|
|
|
|
1165
|
303
|
|
|
|
|
303
|
0 && debug("html_child_or $html_child_or"); |
1166
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
# Ref is a sub-tag, non ref is plain text |
1169
|
|
|
|
|
|
|
# |
1170
|
303
|
100
|
|
|
|
440
|
if (ref($html_child_or)) { |
1171
|
|
|
|
|
|
|
|
1172
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
# Sub tag. Recurse down tree, updating to nearest line number |
1174
|
|
|
|
|
|
|
# |
1175
|
199
|
|
|
|
|
262
|
$line_no=$html_child_or->{'_line_no'}; |
1176
|
199
|
|
50
|
|
|
367
|
my $data_ar=$self->parse($html_child_or, $meta_hr) || |
1177
|
|
|
|
|
|
|
return err (); |
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
|
1180
|
|
|
|
|
|
|
# If no node name returned is not an error, just a no-op |
1181
|
|
|
|
|
|
|
# |
1182
|
199
|
100
|
|
|
|
354
|
if ($data_ar->[$WEBDYNE_NODE_NAME_IX]) { |
1183
|
190
|
|
|
|
|
200
|
push @{$data[$WEBDYNE_NODE_CHLD_IX]}, $data_ar; |
|
190
|
|
|
|
|
318
|
|
1184
|
|
|
|
|
|
|
} |
1185
|
|
|
|
|
|
|
|
1186
|
|
|
|
|
|
|
} |
1187
|
|
|
|
|
|
|
else { |
1188
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
# Node is just plain text. Used to not insert empty children, but this |
1190
|
|
|
|
|
|
|
# stuffed up sections that use \n for spacing/formatting. Now we |
1191
|
|
|
|
|
|
|
# are more careful |
1192
|
|
|
|
|
|
|
# |
1193
|
104
|
50
|
66
|
|
|
446
|
push(@{$data[$WEBDYNE_NODE_CHLD_IX]}, $html_child_or) |
|
65
|
|
66
|
|
|
165
|
|
|
|
|
33
|
|
|
|
|
1194
|
|
|
|
|
|
|
unless ( |
1195
|
|
|
|
|
|
|
$html_child_or=~/^\s*$/ |
1196
|
|
|
|
|
|
|
&& |
1197
|
|
|
|
|
|
|
($html_tag ne 'pre') && ($html_tag ne 'textarea') && !$WEBDYNE_COMPILE_NO_SPACE_COMPACTING |
1198
|
|
|
|
|
|
|
); |
1199
|
|
|
|
|
|
|
|
1200
|
|
|
|
|
|
|
} |
1201
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
} |
1203
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
# All done, return data node |
1206
|
|
|
|
|
|
|
# |
1207
|
213
|
|
|
|
|
490
|
return \@data; |
1208
|
|
|
|
|
|
|
|
1209
|
|
|
|
|
|
|
} |
1210
|
|
|
|
|
|
|
|