Show
Ignore:
Timestamp:
08/25/08 23:05:34 (15 months ago)
Author:
bchoate
Message:

MT::Template::Node refactoring from Hirotaka-san. BugId:79926

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/lib/MT/Template.pm

    r2882 r2973  
    1111use MT::Util qw( weaken ); 
    1212 
     13use MT::Template::Node; 
    1314sub NODE () { 'MT::Template::Node' } 
    14  
    15 sub NODE_TEXT ()     { 1 } 
    16 sub NODE_BLOCK ()    { 2 } 
    17 sub NODE_FUNCTION () { 3 } 
    1815 
    1916my $resync_to_db; 
     
    188185    my $str = ''; 
    189186    foreach my $token (@$tokens) { 
    190         if ($token->[0] eq 'TEXT') { 
    191             $str .= $token->[1]; 
     187        my $tag = $token->tag; 
     188        if ($tag eq 'TEXT') { 
     189            $str .= $token->nodeValue; 
    192190        } else { 
    193             my $tag = $token->[0]; 
    194191            $str .= '<mt' . $tag; 
    195             if (my $attrs = $token->[4]) { 
    196                 my $attrh = $token->[1]; 
     192            if (my $attrs = $token->attribute_list) { 
     193                my $attrh = $token->attributes; 
    197194                foreach my $a (@$attrs) { 
    198195                    delete $attrh->{$a->[0]}; 
     
    208205            } 
    209206            $str .= '>'; 
    210             if ($token->[2]) { 
     207            if (my $childNodes = $token->childNodes) { 
    211208                # container tag 
    212                 $str .= $tmpl->reflow( $token->[2] ); 
     209                $str .= $tmpl->reflow($childNodes); 
    213210                $str .= '</mt' . $tag . '>'; 
    214211            } 
     
    552549    return unless $tokens; 
    553550    foreach my $t (@$tokens) { 
    554         if ($t->[0] ne 'TEXT') { 
    555             if ($t->[1]->{id}) { 
     551        if ($t->tag ne 'TEXT') { 
     552            if (my $id = $t->getAttribute('id')) { 
    556553                my $ids = $tmpl->{__ids} ||= {}; 
    557                 $ids->{lc $t->[1]->{id}} = $t; 
     554                $ids->{lc $id} = $t; 
    558555            } 
    559             elsif ($t->[1]->{class}) { 
     556            elsif (my $class = $t->getAttribute('class')) { 
    560557                my $classes = $tmpl->{__classes} ||= {}; 
    561                 push @{ $classes->{lc $t->[1]->{class}} ||= [] }, $t; 
     558                push @{ $classes->{lc $class} ||= [] }, $t; 
    562559            } 
    563             $tmpl->rescan($t->[2]) if $t->[2]; 
     560            if (my $childNodes = $t->childNodes) { 
     561                $tmpl->rescan($childNodes); 
     562            } 
    564563        } 
    565564    } 
     
    712711    my ($id) = @_; 
    713712    if (my $node = $tmpl->token_ids->{$id}) { 
    714         return bless $node, NODE; 
     713        return $node; 
    715714    } 
    716715    undef; 
     
    720719    my $tmpl = shift; 
    721720    my ($tag, $attr) = @_; 
    722     my $node = bless [ $tag, $attr, undef, undef, undef, undef, $tmpl ], NODE; 
    723     weaken($node->[6]); 
    724     return $node; 
     721    return NODE->new(tag => $tag, attributes => $attr, template => $tmpl); 
    725722} 
    726723 
     
    728725    my $tmpl = shift; 
    729726    my ($text) = @_; 
    730     my $node = bless [ 'TEXT', $text, undef, undef, undef, undef, $tmpl ], NODE; 
    731     weaken($node->[6]); 
    732     return $node; 
     727    return NODE->new(tag => 'TEXT', nodeValue => $text, template => $tmpl); 
    733728} 
    734729 
     
    809804 
    810805use strict; 
    811 sub NODE_TEXT ()     { 1 } 
    812 sub NODE_BLOCK ()    { 2 } 
    813 sub NODE_FUNCTION () { 3 } 
    814806 
    815807sub getElementsByTagName { 
     
    818810    $name = lc $name; 
    819811    foreach my $t (@$tokens) { 
    820         if (lc $t->[0] eq $name) { 
     812        if (lc $t->tag eq $name) { 
    821813            push @list, $t; 
    822814        } 
    823         if ($t->[2]) { 
    824             my $subt = getElementsByTagName($t->[2], $name); 
     815        if (my $childNodes = $t->childNodes) { 
     816            my $subt = getElementsByTagName($childNodes, $name); 
    825817            push @list, @$subt if $subt; 
    826818        } 
     
    834826    $name = lc $name; 
    835827    foreach my $t (@$tokens) { 
    836         if ((ref($t->[1]) eq 'HASH') && (lc ($t->[1]{'name'} || '') eq $name)) { 
     828        if (lc ($t->getAttribute('name') || '') eq $name) { 
    837829            push @list, $t; 
    838830        } 
    839         if ($t->[2]) { 
    840             my $subt = getElementsByName($t->[2], $name); 
     831        if (my $childNodes = $t->childNodes) { 
     832            my $subt = getElementsByName($childNodes, $name); 
    841833            push @list, @$subt if $subt; 
    842834        } 
     
    844836    scalar @list ? \@list : undef; 
    845837} 
    846  
    847 package MT::Template::Node; 
    848  
    849 use strict; 
    850 use MT::Util qw( weaken ); 
    851  
    852 sub setAttribute { 
    853     my $node = shift; 
    854     my ($attr, $val) = @_; 
    855     if ($attr eq 'id') { 
    856         # assign into ids 
    857         my $tmpl = $node->template; 
    858         my $ids = $tmpl->token_ids; 
    859         my $old_id = $node->getAttribute("id"); 
    860         if ($old_id && $ids) { 
    861             delete $ids->{$old_id}; 
    862         } 
    863     } 
    864     elsif ($attr eq 'class') { 
    865         # assign into classes 
    866         my $tmpl = $node->template; 
    867         my $classes = $tmpl->token_classes; 
    868         my $old_class = $node->getAttribute("class"); 
    869         if ($old_class && $classes->{$old_class}) { 
    870             @{$classes->{$old_class}} = grep { $_ != $node } 
    871                 @{$classes->{$old_class}}; 
    872         } 
    873         push @{$classes->{$val} ||= []}, $node; 
    874     } 
    875     ($node->[1] ||= {})->{$attr} = $val; 
    876 } 
    877  
    878 sub template { 
    879     my $node = shift; 
    880     return $node->[6]; 
    881 } 
    882  
    883 sub getAttribute { 
    884     my $node = shift; 
    885     my ($attr) = @_; 
    886     ($node->[1] || {})->{$attr}; 
    887 } 
    888  
    889 # sub attributes { 
    890 #     my $node = shift; 
    891 #     return $node->[1] ||= {}; 
    892 # } 
    893  
    894 sub nextSibling { 
    895     my $node = shift; 
    896     my $parent = $node->parentNode->childNodes; 
    897     my $max = (scalar @$parent) - 1; 
    898     return undef unless $max; 
    899     my $last = $parent->[0]; 
    900     foreach my $n ($parent->[1..$max]) { 
    901         return $n if $node == $last; 
    902         $last = $n; 
    903     } 
    904     return $parent->[$max] if $node == $last; 
    905     return undef; 
    906 } 
    907  
    908 sub lastChild { 
    909     my $node = shift; 
    910     my $children = $node->childNodes or return undef; 
    911     @$children ? $children->[scalar @$children - 1] : undef; 
    912 } 
    913  
    914 sub firstChild { 
    915     my $node = shift; 
    916     my $children = $node->[2] or return undef; 
    917     @$children ? $children->[0] : undef; 
    918 } 
    919  
    920 sub previousSibling { 
    921     my $node = shift; 
    922     my $parent = $node->parentNode->childNodes; 
    923     my $last; 
    924     foreach my $n (@$parent) { 
    925         return $last if $node == $n; 
    926         $last = $n; 
    927     } 
    928     return undef; 
    929 } 
    930  
    931 sub parentNode { 
    932     my $node = shift; 
    933     weaken($node->[5] = shift) if @_; 
    934     $node->[5]; 
    935 } 
    936  
    937 sub childNodes { 
    938     my $node = shift; 
    939     $node->[2] = shift if @_; 
    940     $node->[2]; 
    941 } 
    942  
    943 sub ownerDocument { #template 
    944     my $node = shift; 
    945     return $node->template; 
    946 } 
    947  
    948 sub hasChildNodes { 
    949     my $node = shift; 
    950     $node->[2] && (@{$node->[2]}) ? 1 : 0; 
    951 } 
    952  
    953 sub nodeType { 
    954     my $node = shift; 
    955     if ($node->[0] eq 'TEXT') { 
    956         return NODE_TEXT(); 
    957     } elsif (defined $node->[2]) { 
    958         return NODE_BLOCK(); 
    959     } else { 
    960         return NODE_FUNCTION(); 
    961     } 
    962 } 
    963  
    964 sub nodeName { 
    965     my $node = shift; 
    966     if ($node->[0] eq 'TEXT') { 
    967         return undef; 
    968     } 
    969     # normalize: 
    970     #    MTEntry => mt:entry 
    971     #    MTAPP:WIDGET => mtapp:widget 
    972     my $tag = lc $node->[0]; 
    973     if (($tag !~ m/:/) && ($tag =~ m/^mt/)) { 
    974         $tag =~ s/^mt/mt:/; 
    975     } 
    976     return $tag; 
    977 } 
    978  
    979 # Returns text of a text node; inner text for a block tag, or undef 
    980 # for a function tag. 
    981 sub nodeValue { 
    982     my $node = shift; 
    983     if ($node->[0] eq 'TEXT') { 
    984         return $node->[1]; 
    985     } else { 
    986         if (defined $node->[3]) { 
    987             return $node->[3]; 
    988         } 
    989     } 
    990     return undef; 
    991 } 
    992  
    993 sub innerHTML { 
    994     my $node = shift; 
    995     if (@_) { 
    996         my ($text) = @_; 
    997         $node->[3] = $text; 
    998         my $builder = new MT::Builder; 
    999         my $ctx = MT::Template::Context->new; 
    1000         $node->[2] = $builder->compile($ctx, $text); 
    1001         my $tmpl = $node->ownerDocument; 
    1002         if ($tmpl) { 
    1003             $tmpl->reset_markers; 
    1004             $tmpl->{reflow_flag} = 1; 
    1005         } 
    1006     } 
    1007     return $node->[3]; 
    1008 } 
    1009  
    1010 # TBD: what about new nodes that are added with id elements? 
    1011 sub appendChild { 
    1012     my $node = shift; 
    1013     my ($new_node) = @_; 
    1014     my $nodes = $node->childNodes; 
    1015     push @$nodes, $new_node; 
    1016     my $tmpl = $node->ownerDocument; 
    1017     if ($tmpl) { 
    1018         $tmpl->{reflow_flag} = 1; 
    1019     } 
    1020 } 
    1021  
    1022 sub removeChild { 
    1023     my $node = shift; 
    1024 } 
    1025  
    1026 *inner_html = \&innerHTML; 
    1027 *append_child = \&appendChild; 
    1028 *insert_before = \&insertBefore; 
    1029 *remove_child = \&removeChild; 
    1030838 
    1031839# trans('Index')