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 |
