changeset 289:85572f512abc

*TTView refactoring
author cin
date Wed, 20 Feb 2013 02:25:30 +0400
parents 3a9cfea098dd
children 7b0dad6117d5
files Lib/IMPL/Web/View/TTDocument.pm Lib/IMPL/Web/View/TTFactory.pm Lib/IMPL/Web/View/TTLoader.pm _test/Test/Web/View.pm
diffstat 4 files changed, 39 insertions(+), 120 deletions(-) [+]
line wrap: on
line diff
--- a/Lib/IMPL/Web/View/TTDocument.pm	Tue Feb 19 19:58:27 2013 +0400
+++ b/Lib/IMPL/Web/View/TTDocument.pm	Wed Feb 20 02:25:30 2013 +0400
@@ -23,7 +23,6 @@
     props => [
         layout => PROP_RW,
         loader => PROP_RW,
-        controls => PROP_RO,
     ]
 };
 
@@ -41,59 +40,14 @@
     $this->InitInstance();
 }
 
-sub templateVars {
-    my $this = shift;
-    my $name = shift;
-    if (@_) {
-        return $this->context->stash->set($name, shift);        
-    } else {
-        return $this->context->stash->get($name);
-    }
-}
-
-sub RequireControl {
-    my ($this, $control, $ctx) = @_;
-    
-    $ctx ||= $this->context;
-    
-    if (my $factory = $this->controls->{$control}) {
-        return $factory;
-    } else {
-        my $path = $control;
-        
-        if ( my $template = $this->loader->template($path) ) {
-           
-            $factory = new IMPL::Web::View::TTFactory(
-                $template->class || TTControl,
-                $template,
-                $ctx,
-                join( '/', splice( @{[split(/\//,$path)]}, 0, -1 ) )
-            );
-            
-            if ($template->class) {
-                Loader->safe->Require($template->class);
-            }
-            
-            $this->controls->{$control} = $factory;
-                        
-            return $factory;
-
-        } else {
-            die new IMPL::KeyNotFoundException($control);
-        }
-    }
-}
-
 sub Render {
     my ($this,$args) = @_;
 
     $args ||= {};
 
-    $this->context->localise();
-    
-    my $documentContext;
     my %controls;
     my $require;
+    my $documentContext;
     $require = sub {
         my $control = shift;
         if (my $factory = $controls{$control}) {
@@ -125,9 +79,13 @@
         }
     };
     
+    $this->context->localise();
+    $documentContext = _clone_context( $this->context );
+    my $self = $this;
+    weaken($self);
     $this->context->stash->set(require => $require);
-    $this->context->stash->set(document => $this);
-    $documentContext = Template::Context->new( { %{$this->context} } );
+    #$this->context->stash->set(document => sub { $self });
+    
     
     my $text = eval {
     
@@ -158,8 +116,12 @@
 	        return $this->next::method($args);
 	    }
     };
+
+    undef $require;
+    undef $documentContext;    
+    undef %controls;
+    $this->context->delocalise();
     
-    $this->context->delocalise();
     
     my $e = $@;
     if ($e) {
@@ -171,6 +133,13 @@
     
 }
 
+sub _clone_context {
+    my $args = { %{shift || {}} };
+    delete $args->{CONFIG};
+    
+    return Template::Context->new($args);
+}
+
 1;
 
 __END__
--- a/Lib/IMPL/Web/View/TTFactory.pm	Tue Feb 19 19:58:27 2013 +0400
+++ b/Lib/IMPL/Web/View/TTFactory.pm	Wed Feb 20 02:25:30 2013 +0400
@@ -49,13 +49,13 @@
     
     $this->context->localise();
     
-    my $ctx = new Template::Context({ %{$this->context} });
+    my $ctx = _clone_context($this->context);
     
     $this->context->delocalise();
     
     my $stash = $ctx->stash;
     my $require = $this->require;
-
+    
     $stash->update({
         require => sub {
             my ($module) = @_;
@@ -65,7 +65,7 @@
         }        
     });
     
-    return ($name, $this->template, $ctx, hashApply({ factory => $this },$refProps));
+    return ($name, $this->template, $ctx, $refProps);
 }
 
 sub CreateObject {
@@ -90,6 +90,13 @@
     return $instance;
 }
 
+sub _clone_context {
+    my $args = { %{shift || {}} };
+    delete $args->{CONFIG};
+    
+    return Template::Context->new($args);
+}
+
 sub save {
     die new IMPL::NotImplementedException("This class doesn't support serialization");
 }
--- a/Lib/IMPL/Web/View/TTLoader.pm	Tue Feb 19 19:58:27 2013 +0400
+++ b/Lib/IMPL/Web/View/TTLoader.pm	Wed Feb 20 02:25:30 2013 +0400
@@ -78,7 +78,7 @@
     my $opts = { %{ $this->options } };
     
     $this->context->localise();
-    my $ctx = Template::Context->new( %{$this->context} );
+    my $ctx = _clone_context($this->context);
     $this->context->delocalise();
     
     return TTDocument->new( $tt, $ctx, $this, $vars );
@@ -146,6 +146,13 @@
     }
 }
 
+sub _clone_context {
+    my $args = { %{shift || {}} };
+    delete $args->{CONFIG};
+    
+    return Template::Context->new($args);
+}
+
 1;
 
 __END__
--- a/_test/Test/Web/View.pm	Tue Feb 19 19:58:27 2013 +0400
+++ b/_test/Test/Web/View.pm	Wed Feb 20 02:25:30 2013 +0400
@@ -87,7 +87,6 @@
     assert( $doc->context->stash->get('user') eq 'test_user');
     
     # document should not have 'this' template variable
-    assert( not $doc->templateVars('this') );
     
     assert( $doc->context != $loader->context); # document should have an own context
 };
@@ -108,14 +107,7 @@
     assert(not $doc->can('notexists')); # autoloaded property should be ignored
     assert(not defined $doc->notexists); # nonexisting property 
     assert($doc->template->version == 10); # static metadata
-    assert($doc->templateVars('notexists') eq ''); #nonexisting template variable
-    assert($doc->templateVars('user') eq 'test_user'); # global data
-    assert($doc->templateVars('templateVar') eq ''); # defined in CTOR block, should be local
-    assert($doc->templateVars('dynamic') eq 'this is a dynamic value');
     assert($doc->context->stash->get('user') eq 'test_user' ); # runtime context should be derived from documentContext
-    $doc->context->stash->set('user', 'nobody');
-    assert($doc->templateVars('user') eq 'test_user'); # isolated
-    $doc->context->stash->set('user', 'test_user');
     
     my $text = $doc->Render();
     my $expected = read_file($this->GetResourceFile('Resources','TTView.Output','simple.txt'), binmode => ':utf8');
@@ -124,55 +116,6 @@
     
 };
 
-test TTControlTests => sub {
-    my ($this) = @_;
-    
-    my $loader = $this->CreateLoader();
-    
-    my $doc = $loader->document('simple');
-    
-    assert(defined $doc);
-    
-    my $factory = $doc->RequireControl('My/Org/Panel');
-    
-    assert(defined $factory);
-    
-    # control factory shares document scope to perform an initialization on demand
-    assert($factory->context->stash == $doc->context->stash);
-    
-    assert($factory == $doc->RequireControl('My/Org/Panel'), "Control should be loaded only once");
-    
-    my $ctl = $factory->new('information', { visualClass => 'simple', data => ['one','two','hello world'] } );
-    
-    assert(defined $ctl);    
-    
-    assert($ctl->name eq 'information', "Created control should have a name", "Got: ".$ctl->name, "Expected: information");
-    
-    assert($ctl->GetAttribute('visualClass') eq 'simple');
-    
-    assert($factory->instances == 1);
-    
-    $doc->childNodes([$ctl]);
-    
-    assert($doc->templateVars('dojo.require'));
-    assert(ref $doc->templateVars('dojo.require') eq 'ARRAY');
-    assert($doc->templateVars('dojo.require')->[0] eq 'dijit.form.Input' );
-    
-    my $text = $ctl->Render();
-    
-    my $expected = read_file($this->GetResourceFile('Resources', 'TTView.Output', 'Panel.txt'), binmode => ':utf8');    
-    assert($text eq $expected, '$ctl->Render(): Bad output', "Got:      $text", "Expected: $expected");
-    
-    
-    my $doc2 = $loader->document('simple');
-    
-    assert( $doc2->documentContext->stash->get( ['require',['My/Org/Panel'] ] ) );
-    print Dumper($doc2->context->stash);
-    assert( $doc2->context->stash->get( ['require',['My/Org/Panel'] ] ) );
-    
-    
-};
-
 test TestDocumentLayout => sub {
     my ($this) = @_;
     
@@ -208,8 +151,6 @@
     assert(ref $loader->context->stash->get([ 'dojo', 0, 'require', 0]) eq 'ARRAY');
     assertarray($loader->context->stash->get([ 'dojo', 0, 'require', 0]),[]);
     assert($loader->context->stash != $doc->context->stash);
-    assert($loader->context->stash != $doc->documentContext->stash);
-    assert($doc->context->stash != $doc->documentContext->stash);
     
     assert(defined $doc);
     
@@ -251,21 +192,16 @@
     
     AssertMemoryLeak(sub {        
         my $doc = $loader->document('simple');
-    });
+    },'dump');
         
     AssertMemoryLeak(sub {
         my $doc = $loader->document('simple');
         $doc->Render( { self => $doc } );
-    });
+    },'dump');
     
     $loader->template('Layout/default');
     $loader->template('My/Org/Panel');
     $loader->template('My/Org/TextPreview');
-    AssertMemoryLeak(sub {
-        my $doc = $loader->document('simple');
-        my $factory = $doc->RequireControl('My/Org/Panel');
-        my $ctl = $doc->childNodes($factory->new('information', { visualClass => 'complex' }) );        
-    },'dump');
     
     $loader->template('complex');
     AssertMemoryLeak(sub {