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