diff 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
line wrap: on
line diff
--- a/Lib/IMPL/Web/TT/Document.pm	Thu May 13 03:46:29 2010 +0400
+++ b/Lib/IMPL/Web/TT/Document.pm	Fri May 14 16:06:06 2010 +0400
@@ -16,7 +16,7 @@
     private property _context => prop_all;
     public property template => prop_get | owner_set;
     public property presenter => prop_all, { validate => \&_validatePresenter };
-    public property controls => { get => \&_getControls };
+    private property _controlClassMap => prop_all;
 }
 
 our %CTOR = (
@@ -26,11 +26,25 @@
 sub CTOR {
 	my ($this) = @_;
 	
-	$this->appendChild(
-		$this->Create(
-			controls => 'IMPL::Web::TT::Collection'
-		)
-	)
+	$this->_controlClassMap({});
+	$this->registerControlClass( Control => 'IMPL::Web::TT::Control' );
+	$this->appendChild( $this->Create(body => 'IMPL::Web::TT::Collection') );
+	$this->appendChild( $this->Create(head => 'IMPL::Web::TT::Collection') );
+}
+
+sub CreateControl {
+	my ($this,$name,$class,$args) = @_;
+	
+	$args = {} unless ref $args eq 'HASH';
+	
+	if (my $info = $this->_controlClassMap->{$class}) {
+		my %nodeArgs = (%{$info->{args}},%$args);
+		$nodeArgs{controlClass} = $class;
+		
+		return $this->Create($name,$info->{type},\%nodeArgs);
+	} else {
+		die new IMPL::Exception('A control is\'t registered', $class, $name);
+	}
 }
 
 sub provider {
@@ -58,8 +72,7 @@
                     this => $this,
                     render => sub {
                     	$this->_process(@_);
-                    },
-                    controls => $this->controls
+                    }
                 },
                 TRIM => 1,
                 RECURSION => 1,
@@ -69,11 +82,22 @@
     }
 }
 
-sub createControl {
-	my ($this,$name,$args) = @_;
+sub registerControlClass {
+	my ($this, $controlClass, $type, $args) = @_;
+	
+	$type ||= 'IMPL::Web::TT::Control';
+	
+	die new IMPL::InvalidArgumentException("A controlClass must be a single word",$controlClass) unless $controlClass =~ /^\w+$/;
 	
-	my $node = $this->Create($name,'IMPL::Web::TT::Control',$args);
-	$this->controls->appendChild($node);
+	eval "require $type; 1;" or die new IMPL::Exception("Failed to load a module",$type,"$@") unless ref $type or $INC{$type};
+	
+	die new IMPL::InvalidArgumentException("A type must be subclass of IMPL::DOM::Node",$type) unless $type->isa('IMPL::DOM::Node');
+	
+	$this->_controlClassMap->{$controlClass} = {
+		controlClass => $controlClass,
+		type => $type,
+		args => ref $args eq 'HASH' ? $args : {}
+	};
 }
 
 sub _getControls {
@@ -153,6 +177,26 @@
 	return join '',@result;
 }
 
+our $AUTOLOAD;
+sub AUTOLOAD {
+	my $this = shift;
+	my ($method) = ($AUTOLOAD =~ /(\w+)$/);
+	
+	if($method =~ /^create(\w+)/) {
+		my ($name,$args) = @_;
+		return $this->CreateControl($name,$1,$args);
+	}
+	
+	my @result = $this->selectNodes($method);
+	
+	return $result[0] if @result;
+	return;
+}
+
+sub as_list {
+	$_[0]->childNodes;
+}
+
 sub Dispose {
     my ($this) = @_;
     
@@ -160,7 +204,7 @@
     $this->_context(undef);
     $this->_provider(undef);
     
-    $this->SUPER::Dispose();
+    $this->supercall::Dispose();
 }
 
 1;
@@ -223,17 +267,30 @@
 
 =head1 DOM
 
+Документ представляет собой DOM документ, состоящий из узлов, которые представляют собой данные
+для отображения. Для форматированого вывода используется C<template>.
+
+В качестве элементов документа могут присутсвовать специальные объекты C<IMPL::Web::TT::Control>,
+которые внутри содержат шаблон для форматирования собственного содержимого.
+
+
+
+Документ предоставляет ряд фнукций для работы с элементами управления.
+
+=head1 TEMPLATE
+
 =begin code html
 
-[% table = document.Create('env','table') %]
+[% CALL document.registerClass( 'Table', 'My::TableClass', template => 'tables/pretty.tt' ) %]
+[% CALL document.registerClass( 'Form' )%]
+
+[% table = document.сreateTable('env') %]
 
 [% FOEACH item in document.result %]
 	[% table.rows.Add( item.get('name','value') ) %]
 [% END %]
 
-[% form = document.Create('login','form') %]
-
-
+[% form = document.createForm('login') %]
 [% form.template = 'LOGIN_FORM'%]
 
 [% FOREACH item IN document.childNodes %]
@@ -248,5 +305,4 @@
 
 =end code html
 
-
 =cut