Mercurial > pub > Impl
comparison Lib/IMPL/Web/TT/Document.pm @ 108:c6fb6964de4c
Removed absolute modules
Updated DOM model, selectNodes can now select a complex path
Web DOM model release candidate
author | wizard |
---|---|
date | Fri, 14 May 2010 16:06:06 +0400 |
parents | 0e72ad99eef7 |
children | ddf0f037d460 |
comparison
equal
deleted
inserted
replaced
107:0e72ad99eef7 | 108:c6fb6964de4c |
---|---|
14 BEGIN { | 14 BEGIN { |
15 private property _provider => prop_all; | 15 private property _provider => prop_all; |
16 private property _context => prop_all; | 16 private property _context => prop_all; |
17 public property template => prop_get | owner_set; | 17 public property template => prop_get | owner_set; |
18 public property presenter => prop_all, { validate => \&_validatePresenter }; | 18 public property presenter => prop_all, { validate => \&_validatePresenter }; |
19 public property controls => { get => \&_getControls }; | 19 private property _controlClassMap => prop_all; |
20 } | 20 } |
21 | 21 |
22 our %CTOR = ( | 22 our %CTOR = ( |
23 'IMPL::DOM::Document' => sub { nodeName => 'document' } | 23 'IMPL::DOM::Document' => sub { nodeName => 'document' } |
24 ); | 24 ); |
25 | 25 |
26 sub CTOR { | 26 sub CTOR { |
27 my ($this) = @_; | 27 my ($this) = @_; |
28 | 28 |
29 $this->appendChild( | 29 $this->_controlClassMap({}); |
30 $this->Create( | 30 $this->registerControlClass( Control => 'IMPL::Web::TT::Control' ); |
31 controls => 'IMPL::Web::TT::Collection' | 31 $this->appendChild( $this->Create(body => 'IMPL::Web::TT::Collection') ); |
32 ) | 32 $this->appendChild( $this->Create(head => 'IMPL::Web::TT::Collection') ); |
33 ) | 33 } |
34 | |
35 sub CreateControl { | |
36 my ($this,$name,$class,$args) = @_; | |
37 | |
38 $args = {} unless ref $args eq 'HASH'; | |
39 | |
40 if (my $info = $this->_controlClassMap->{$class}) { | |
41 my %nodeArgs = (%{$info->{args}},%$args); | |
42 $nodeArgs{controlClass} = $class; | |
43 | |
44 return $this->Create($name,$info->{type},\%nodeArgs); | |
45 } else { | |
46 die new IMPL::Exception('A control is\'t registered', $class, $name); | |
47 } | |
34 } | 48 } |
35 | 49 |
36 sub provider { | 50 sub provider { |
37 my ($this,%args) = @_; | 51 my ($this,%args) = @_; |
38 | 52 |
56 VARIABLES => { | 70 VARIABLES => { |
57 document => $this, | 71 document => $this, |
58 this => $this, | 72 this => $this, |
59 render => sub { | 73 render => sub { |
60 $this->_process(@_); | 74 $this->_process(@_); |
61 }, | 75 } |
62 controls => $this->controls | |
63 }, | 76 }, |
64 TRIM => 1, | 77 TRIM => 1, |
65 RECURSION => 1, | 78 RECURSION => 1, |
66 LOAD_TEMPLATES => [$this->provider] | 79 LOAD_TEMPLATES => [$this->provider] |
67 ) | 80 ) |
68 ) | 81 ) |
69 } | 82 } |
70 } | 83 } |
71 | 84 |
72 sub createControl { | 85 sub registerControlClass { |
73 my ($this,$name,$args) = @_; | 86 my ($this, $controlClass, $type, $args) = @_; |
74 | 87 |
75 my $node = $this->Create($name,'IMPL::Web::TT::Control',$args); | 88 $type ||= 'IMPL::Web::TT::Control'; |
76 $this->controls->appendChild($node); | 89 |
90 die new IMPL::InvalidArgumentException("A controlClass must be a single word",$controlClass) unless $controlClass =~ /^\w+$/; | |
91 | |
92 eval "require $type; 1;" or die new IMPL::Exception("Failed to load a module",$type,"$@") unless ref $type or $INC{$type}; | |
93 | |
94 die new IMPL::InvalidArgumentException("A type must be subclass of IMPL::DOM::Node",$type) unless $type->isa('IMPL::DOM::Node'); | |
95 | |
96 $this->_controlClassMap->{$controlClass} = { | |
97 controlClass => $controlClass, | |
98 type => $type, | |
99 args => ref $args eq 'HASH' ? $args : {} | |
100 }; | |
77 } | 101 } |
78 | 102 |
79 sub _getControls { | 103 sub _getControls { |
80 my ($this) = @_; | 104 my ($this) = @_; |
81 | 105 |
151 } | 175 } |
152 | 176 |
153 return join '',@result; | 177 return join '',@result; |
154 } | 178 } |
155 | 179 |
180 our $AUTOLOAD; | |
181 sub AUTOLOAD { | |
182 my $this = shift; | |
183 my ($method) = ($AUTOLOAD =~ /(\w+)$/); | |
184 | |
185 if($method =~ /^create(\w+)/) { | |
186 my ($name,$args) = @_; | |
187 return $this->CreateControl($name,$1,$args); | |
188 } | |
189 | |
190 my @result = $this->selectNodes($method); | |
191 | |
192 return $result[0] if @result; | |
193 return; | |
194 } | |
195 | |
196 sub as_list { | |
197 $_[0]->childNodes; | |
198 } | |
199 | |
156 sub Dispose { | 200 sub Dispose { |
157 my ($this) = @_; | 201 my ($this) = @_; |
158 | 202 |
159 $this->template(undef); | 203 $this->template(undef); |
160 $this->_context(undef); | 204 $this->_context(undef); |
161 $this->_provider(undef); | 205 $this->_provider(undef); |
162 | 206 |
163 $this->SUPER::Dispose(); | 207 $this->supercall::Dispose(); |
164 } | 208 } |
165 | 209 |
166 1; | 210 1; |
167 __END__ | 211 __END__ |
168 =pod | 212 =pod |
221 | 265 |
222 =back | 266 =back |
223 | 267 |
224 =head1 DOM | 268 =head1 DOM |
225 | 269 |
270 Документ представляет собой DOM документ, состоящий из узлов, которые представляют собой данные | |
271 для отображения. Для форматированого вывода используется C<template>. | |
272 | |
273 В качестве элементов документа могут присутсвовать специальные объекты C<IMPL::Web::TT::Control>, | |
274 которые внутри содержат шаблон для форматирования собственного содержимого. | |
275 | |
276 | |
277 | |
278 Документ предоставляет ряд фнукций для работы с элементами управления. | |
279 | |
280 =head1 TEMPLATE | |
281 | |
226 =begin code html | 282 =begin code html |
227 | 283 |
228 [% table = document.Create('env','table') %] | 284 [% CALL document.registerClass( 'Table', 'My::TableClass', template => 'tables/pretty.tt' ) %] |
285 [% CALL document.registerClass( 'Form' )%] | |
286 | |
287 [% table = document.сreateTable('env') %] | |
229 | 288 |
230 [% FOEACH item in document.result %] | 289 [% FOEACH item in document.result %] |
231 [% table.rows.Add( item.get('name','value') ) %] | 290 [% table.rows.Add( item.get('name','value') ) %] |
232 [% END %] | 291 [% END %] |
233 | 292 |
234 [% form = document.Create('login','form') %] | 293 [% form = document.createForm('login') %] |
235 | |
236 | |
237 [% form.template = 'LOGIN_FORM'%] | 294 [% form.template = 'LOGIN_FORM'%] |
238 | 295 |
239 [% FOREACH item IN document.childNodes %] | 296 [% FOREACH item IN document.childNodes %] |
240 [%render(item)%] | 297 [%render(item)%] |
241 [% END %] | 298 [% END %] |
246 </form> | 303 </form> |
247 [% END %] | 304 [% END %] |
248 | 305 |
249 =end code html | 306 =end code html |
250 | 307 |
251 | |
252 =cut | 308 =cut |