Mercurial > pub > Impl
diff Lib/DOM/Page.pm @ 49:16ada169ca75
migrating to the Eclipse IDE
author | wizard@linux-odin.local |
---|---|
date | Fri, 26 Feb 2010 10:49:21 +0300 |
parents | 03e58a454b20 |
children |
line wrap: on
line diff
--- a/Lib/DOM/Page.pm Fri Feb 26 01:43:42 2010 +0300 +++ b/Lib/DOM/Page.pm Fri Feb 26 10:49:21 2010 +0300 @@ -1,241 +1,241 @@ -package DOM::Page; -use Common; -use Template::Context; -use strict; - -our @ISA = qw(Object); -our $AUTOLOAD; - -BEGIN { - DeclareProperty(Title => ACCESS_ALL); - DeclareProperty(NavChain => ACCESS_READ); - DeclareProperty(Menus => ACCESS_READ); - DeclareProperty(Properties => ACCESS_READ); - DeclareProperty(Template => ACCESS_READ); - DeclareProperty(TemplatesProvider => ACCESS_NONE); - DeclareProperty(Site => ACCESS_READ); -} - -sub CTOR { - my ($this,%args) = @_; - $this->{$Site} = $args{'Site'}; - $this->{$TemplatesProvider} = $args{'TemplatesProvider'}; - $this->{$Properties} = $args{'Properties'} || {}; - $this->{$Title} = $args{'Template'}->Title() || $args{'Properties'}->{'Title'}; - $this->{$Template} = $args{'Template'}; - $this->{$NavChain} = $args{'NavChain'}; - $this->{$Menus} = $args{'Menus'}; -} - -sub Render { - my ($this,$hOut) = @_; - - my $context = new Template::Context({ - VARIABLES => $this->{$Site}->Objects(), - LOAD_TEMPLATES => $this->{$TemplatesProvider} - }); - - print $hOut $this->{$Template}->process($context); -} - -sub Dispose { - my ($this) = @_; - - undef %$this; - - $this->SUPER::Dispose; -} - -sub Container { - my ($this) = @_; - my $nav = $this->{$NavChain}; - return $nav->[@{$nav}-1]; -} - -sub AUTOLOAD { - my $this = shift; - - my $name = $AUTOLOAD; - $name =~ s/.*://; - - return $this->{$Properties}->{$name}; -} - -=pod -Меню - [ - Элемент меню - { - Key => Ключ пункта меню, для быстрого обращения к элементу и слиянии меню - Name => Имя пункта меню, которое будет видель пользователь - Expand => флаг того, что меню выбрано - Value => {[ элемент меню ...] | что-то еще, обычно урл} - } - ] -=cut - -package DOM::PageMenu; -use Common; - -our @ISA = qw(Object); - -BEGIN { - DeclareProperty('Items'); # массив - DeclareProperty('Keys'); # ключи для пунктов меню, если таковые имеются -} - -sub CTOR { - my ($this,%args) = @_; - if (ref $args{'DATA'} eq 'ARRAY') { - foreach my $item (@{$args{'DATA'}}) { - if (ref $item eq 'HASH') { - $this->Append($item->{'Name'},_ProcessData($item->{'Value'}), Expand => $item->{'Expand'}, Key => $item->{'Key'}, Url => $item->{'Url'}); - } elsif (ref $item eq 'ARRAY') { - $this->Append($item->[0],_ProcessData($item->[1]), Expand => $item->[2], Key => $item->[3], Url => $item->[4]); - } - } - } -} - -sub Item { - my ($this,$index) = @_; - - return $this->{$Items}[$index]; -} - -sub ItemByKey { - my ($this,$key) = @_; - - return $this->{$Keys}->{$key}; -} - -sub InsertBefore { - my ($this,$index,$name,$data,%options) = @_; - - my $item = {Name => $name, Value => _ProcessData($data), %options}; - splice @{$this->{$Items}},$index,0,$item; - - if ($options{'Key'}) { - $this->{$Keys}->{$options{'Key'}} = $item; - } -} - -sub Append { - my ($this,$name,$data,%options) = @_; - - my $item = {Name => $name, Value => _ProcessData($data), %options}; - - push @{$this->{$Items}},$item; - - if ($options{'Key'}) { - $this->{$Keys}->{$options{'Key'}} = $item; - } -} - -sub SubMenu { - my ($this,$path) = @_; - my $item = $this; - foreach my $key ( split /\/+/,$path ) { - $item = $item->{$Keys}->{$key}; - if (not $item ) { - die new Exception('Item does\'t exist', $path, $key); - } - $item = $item->{Value}; - if (not UNIVERSAL::isa($item,'DOM::PageMenu')) { - $item = ($this->{$Keys}->{$key}->{Value} = new DOM::PageMenu()); - } - } - - return $item; -} - -sub Dump { - use Data::Dumper; - - return Dumper(shift); -} - -sub AppendItem { - my ($this,$item) = @_; - - push @{$this->{$Items}},$item; - - if ($item->{'Key'}) { - $this->{$Keys}->{$item->{'Key'}} = $item; - } -} - -sub RemoveAt { - my ($this,$index) = @_; - - my $item = splice @{$this->{$Items}},$index,1; - - if ($item->{'Key'}) { - delete $this->{$Keys}->{$item->{'Key'}}; - } - - return 1; -} - -sub ItemsCount { - my $this = shift; - return scalar(@{$this->{$Items}}); -} - -sub Sort { - my $this = shift; - - $this->{$Items} = \sort { $a->{'Name'} <=> $b->{'Name'} } @{$this->{$Items}}; - - return 1; -} - -sub as_list { - my $this = shift; - return $this->{$Items} || []; -} - -sub Merge { - my ($this,$that) = @_; - - foreach my $itemThat ($that->Items) { - my $itemThis = $itemThat->{'Key'} ? $this->{$Keys}->{$itemThat->{'Key'}} : undef; - if ($itemThis) { - $this->MergeItems($itemThis,$itemThat); - } else { - $this->AppendItem($itemThat); - } - } -} - -sub MergeItems { - my ($this,$itemLeft,$itemRight) = @_; - - while (my ($prop,$value) = each %{$itemRight}) { - if ($prop eq 'Value') { - if (UNIVERSAL::isa($itemLeft->{$prop},__PACKAGE__) && UNIVERSAL::isa($value,__PACKAGE__)) { - $itemLeft->{$prop}->Merge($value); - } else { - $itemLeft->{$prop} = $value if defined $value; - } - } else { - $itemLeft->{$prop} = $value if defined $value; - } - } - - return 1; -} - -sub _ProcessData { - my $refData = shift; - - if (ref $refData eq 'ARRAY') { - return new DOM::PageMenu(DATA => $refData); - } else { - return $refData; - } -} - - - -1; +package DOM::Page; +use Common; +use Template::Context; +use strict; + +our @ISA = qw(Object); +our $AUTOLOAD; + +BEGIN { + DeclareProperty(Title => ACCESS_ALL); + DeclareProperty(NavChain => ACCESS_READ); + DeclareProperty(Menus => ACCESS_READ); + DeclareProperty(Properties => ACCESS_READ); + DeclareProperty(Template => ACCESS_READ); + DeclareProperty(TemplatesProvider => ACCESS_NONE); + DeclareProperty(Site => ACCESS_READ); +} + +sub CTOR { + my ($this,%args) = @_; + $this->{$Site} = $args{'Site'}; + $this->{$TemplatesProvider} = $args{'TemplatesProvider'}; + $this->{$Properties} = $args{'Properties'} || {}; + $this->{$Title} = $args{'Template'}->Title() || $args{'Properties'}->{'Title'}; + $this->{$Template} = $args{'Template'}; + $this->{$NavChain} = $args{'NavChain'}; + $this->{$Menus} = $args{'Menus'}; +} + +sub Render { + my ($this,$hOut) = @_; + + my $context = new Template::Context({ + VARIABLES => $this->{$Site}->Objects(), + LOAD_TEMPLATES => $this->{$TemplatesProvider} + }); + + print $hOut $this->{$Template}->process($context); +} + +sub Dispose { + my ($this) = @_; + + undef %$this; + + $this->SUPER::Dispose; +} + +sub Container { + my ($this) = @_; + my $nav = $this->{$NavChain}; + return $nav->[@{$nav}-1]; +} + +sub AUTOLOAD { + my $this = shift; + + my $name = $AUTOLOAD; + $name =~ s/.*://; + + return $this->{$Properties}->{$name}; +} + +=pod +Меню + [ + Элемент меню + { + Key => Ключ пункта меню, для быстрого обращения к элементу и слиянии меню + Name => Имя пункта меню, которое будет видель пользователь + Expand => флаг того, что меню выбрано + Value => {[ элемент меню ...] | что-то еще, обычно урл} + } + ] +=cut + +package DOM::PageMenu; +use Common; + +our @ISA = qw(Object); + +BEGIN { + DeclareProperty('Items'); # массив + DeclareProperty('Keys'); # ключи для пунктов меню, если таковые имеются +} + +sub CTOR { + my ($this,%args) = @_; + if (ref $args{'DATA'} eq 'ARRAY') { + foreach my $item (@{$args{'DATA'}}) { + if (ref $item eq 'HASH') { + $this->Append($item->{'Name'},_ProcessData($item->{'Value'}), Expand => $item->{'Expand'}, Key => $item->{'Key'}, Url => $item->{'Url'}); + } elsif (ref $item eq 'ARRAY') { + $this->Append($item->[0],_ProcessData($item->[1]), Expand => $item->[2], Key => $item->[3], Url => $item->[4]); + } + } + } +} + +sub Item { + my ($this,$index) = @_; + + return $this->{$Items}[$index]; +} + +sub ItemByKey { + my ($this,$key) = @_; + + return $this->{$Keys}->{$key}; +} + +sub InsertBefore { + my ($this,$index,$name,$data,%options) = @_; + + my $item = {Name => $name, Value => _ProcessData($data), %options}; + splice @{$this->{$Items}},$index,0,$item; + + if ($options{'Key'}) { + $this->{$Keys}->{$options{'Key'}} = $item; + } +} + +sub Append { + my ($this,$name,$data,%options) = @_; + + my $item = {Name => $name, Value => _ProcessData($data), %options}; + + push @{$this->{$Items}},$item; + + if ($options{'Key'}) { + $this->{$Keys}->{$options{'Key'}} = $item; + } +} + +sub SubMenu { + my ($this,$path) = @_; + my $item = $this; + foreach my $key ( split /\/+/,$path ) { + $item = $item->{$Keys}->{$key}; + if (not $item ) { + die new Exception('Item does\'t exist', $path, $key); + } + $item = $item->{Value}; + if (not UNIVERSAL::isa($item,'DOM::PageMenu')) { + $item = ($this->{$Keys}->{$key}->{Value} = new DOM::PageMenu()); + } + } + + return $item; +} + +sub Dump { + use Data::Dumper; + + return Dumper(shift); +} + +sub AppendItem { + my ($this,$item) = @_; + + push @{$this->{$Items}},$item; + + if ($item->{'Key'}) { + $this->{$Keys}->{$item->{'Key'}} = $item; + } +} + +sub RemoveAt { + my ($this,$index) = @_; + + my $item = splice @{$this->{$Items}},$index,1; + + if ($item->{'Key'}) { + delete $this->{$Keys}->{$item->{'Key'}}; + } + + return 1; +} + +sub ItemsCount { + my $this = shift; + return scalar(@{$this->{$Items}}); +} + +sub Sort { + my $this = shift; + + $this->{$Items} = \sort { $a->{'Name'} <=> $b->{'Name'} } @{$this->{$Items}}; + + return 1; +} + +sub as_list { + my $this = shift; + return $this->{$Items} || []; +} + +sub Merge { + my ($this,$that) = @_; + + foreach my $itemThat ($that->Items) { + my $itemThis = $itemThat->{'Key'} ? $this->{$Keys}->{$itemThat->{'Key'}} : undef; + if ($itemThis) { + $this->MergeItems($itemThis,$itemThat); + } else { + $this->AppendItem($itemThat); + } + } +} + +sub MergeItems { + my ($this,$itemLeft,$itemRight) = @_; + + while (my ($prop,$value) = each %{$itemRight}) { + if ($prop eq 'Value') { + if (UNIVERSAL::isa($itemLeft->{$prop},__PACKAGE__) && UNIVERSAL::isa($value,__PACKAGE__)) { + $itemLeft->{$prop}->Merge($value); + } else { + $itemLeft->{$prop} = $value if defined $value; + } + } else { + $itemLeft->{$prop} = $value if defined $value; + } + } + + return 1; +} + +sub _ProcessData { + my $refData = shift; + + if (ref $refData eq 'ARRAY') { + return new DOM::PageMenu(DATA => $refData); + } else { + return $refData; + } +} + + + +1;