File Coverage

blib/lib/Tree/Simple/View/DHTML.pm
Criterion Covered Total %
statement 148 149 99.3
branch 47 48 97.9
condition 6 6 100.0
subroutine 25 25 100.0
pod 4 4 100.0
total 230 232 99.1


line stmt bran cond sub pod time code
1              
2             package Tree::Simple::View::DHTML;
3              
4 1     1   13270 use strict;
  1         1  
  1         23  
5 1     1   3 use warnings;
  1         1  
  1         31  
6              
7             our $VERSION = '0.19';
8              
9 1     1   331 use parent 'Tree::Simple::View::HTML';
  1         226  
  1         4  
10              
11 1     1   32 use Tree::Simple::View::Exceptions;
  1         1  
  1         15  
12              
13 1     1   2 use constant OPEN_TAG => 1;
  1         1  
  1         681  
14 1     1   4 use constant CLOSE_TAG => 2;
  1         0  
  1         35  
15 1     1   3 use constant EXPANDED => 3;
  1         1  
  1         870  
16              
17             ## private methods
18              
19             sub _init {
20 17     17   25 my ($self, @args) = @_;
21 17         38 $self->SUPER::_init(@args);
22 17         17 $self->{list_counter_id} = 0;
23 17         105 ($self->{obj_id}) = ("$self" =~ /\((.*?)\)$/);
24             }
25              
26             sub _createUID {
27 85     85   73 my ($self, $tree) = @_;
28 85 100       122 return $tree->getUID() if $self->{config}->{use_tree_uids};
29 84         64 $self->{list_counter_id}++;
30 84         140 return join "_" => ($self->{obj_id}, $self->{list_counter_id});
31             }
32              
33             ## public methods
34              
35             sub expandPathSimple {
36 3     3 1 4 my ($self, $tree, $current_path, @path) = @_;
37 3         4 my @results = ("
    ");
38 3         6 my $root_depth = $tree->getDepth() + 1;
39 3         6 my $last_depth = -1;
40             my $traversal_sub = sub {
41 46     46   346 my ($t) = @_;
42 46         32 my $display_style = "none";
43 46 100 100     79 if (defined $current_path && $self->_compareNodeToPath($current_path, $t)) {
44 5         22 $display_style = "block";
45 5         5 $current_path = shift @path;
46             }
47 46         60 my $current_depth = $t->getDepth();
48 46 100       104 push @results => ("" x ($last_depth - $current_depth)) if ($last_depth > $current_depth);
49 46 100       53 unless ($t->isLeaf()) {
50 16         61 my $uid = $self->_createUID($t);
51 16         28 push @results => ("
  • " .
  • 52             $t->getNodeValue() . "");
    53 16         51 push @results => "
      ";
    54             }
    55             else {
    56 30         102 push @results => ("
  • " . $t->getNodeValue() . "
  • ");
    57             }
    58 46         103 $last_depth = $current_depth;
    59 3         13 };
    60 3 100       10 $traversal_sub->($self->{tree}) if $self->{include_trunk};
    61 3         7 $self->{tree}->traverse($traversal_sub);
    62 3         23 $last_depth -= $root_depth;
    63 3 100       7 $last_depth++ if $self->{include_trunk};
    64 3         6 push @results => ("" x ($last_depth + 1));
    65              
    66 3         30 return (join "\n" => @results);
    67             }
    68              
    69             sub expandPathComplex {
    70 5     5 1 7 my ($self, $tree, $config, $current_path, @path) = @_;
    71              
    72 5         11 my ($list_func, $list_item_func) = $self->_processConfig($config);
    73              
    74 5         89 my @results = $list_func->(OPEN_TAG);
    75 5         11 my $root_depth = $tree->getDepth() + 1;
    76 5         14 my $last_depth = -1;
    77             my $traversal_sub = sub {
    78 76     76   614 my ($t) = @_;
    79 76         48 my $display_style = "none";
    80 76 100 100     136 if (defined $current_path && $self->_compareNodeToPath($current_path, $t)) {
    81 9         42 $display_style = "block";
    82 9         10 $current_path = shift @path;
    83             }
    84 76         140 my $current_depth = $t->getDepth();
    85 76 100       454 push @results => ($list_func->(CLOSE_TAG) x ($last_depth - $current_depth)) if ($last_depth > $current_depth);
    86 76 100       95 unless ($t->isLeaf()) {
    87 26         110 my $uid = $self->_createUID($t);
    88 26         454 push @results => ($list_item_func->($t, EXPANDED, $uid));
    89 26         496 push @results => $list_func->(OPEN_TAG, $uid, $display_style);
    90             }
    91             else {
    92 50         943 push @results => ($list_item_func->($t));
    93             }
    94 76         213 $last_depth = $current_depth;
    95 5         15 };
    96 5 100       11 $traversal_sub->($self->{tree}) if $self->{include_trunk};
    97 5         11 $self->{tree}->traverse($traversal_sub);
    98 5         39 $last_depth -= $root_depth;
    99 5 100       9 $last_depth++ if $self->{include_trunk};
    100 5         80 push @results => ($list_func->(CLOSE_TAG) x ($last_depth + 1));
    101 5         201 return (join "\n" => @results);
    102             }
    103              
    104             sub expandAllSimple {
    105 2     2 1 2 my ($self) = @_;
    106 2         4 my @results = ("
      ");
    107 2         5 my $root_depth = $self->{tree}->getDepth() + 1;
    108 2         4 my $last_depth = -1;
    109             my $traversal_sub = sub {
    110 31     31   251 my ($t) = @_;
    111 31         34 my $current_depth = $t->getDepth();
    112 31 100       73 push @results => ("" x ($last_depth - $current_depth)) if ($last_depth > $current_depth);
    113 31 100       37 unless ($t->isLeaf()) {
    114 11         46 my $uid = $self->_createUID($t);
    115 11         25 push @results => ("
  • " .
  • 116             $t->getNodeValue() . "");
    117 11         31 push @results => "
      ";
    118             }
    119             else {
    120 20         72 push @results => ("
  • " . $t->getNodeValue() . "
  • ");
    121             }
    122 31         60 $last_depth = $current_depth;
    123 2         8 };
    124 2 100       5 $traversal_sub->($self->{tree}) if $self->{include_trunk};
    125 2         4 $self->{tree}->traverse($traversal_sub);
    126 2         15 $last_depth -= $root_depth;
    127 2 100       4 $last_depth++ if $self->{include_trunk};
    128 2         5 push @results => ("" x ($last_depth + 1));
    129 2         18 return (join "\n" => @results);
    130             }
    131              
    132             sub expandAllComplex {
    133 7     7 1 7 my ($self, $config) = @_;
    134              
    135 7         18 my ($list_func, $list_item_func) = $self->_processConfig($config);
    136              
    137 7         136 my @results = $list_func->(OPEN_TAG);
    138 7         20 my $root_depth = $self->{tree}->getDepth() + 1;
    139 7         15 my $last_depth = -1;
    140             my $traversal_sub = sub {
    141 94     94   739 my ($t) = @_;
    142 94         119 my $current_depth = $t->getDepth();
    143 94 100       589 push @results => ($list_func->(CLOSE_TAG) x ($last_depth - $current_depth)) if ($last_depth > $current_depth);
    144 94 100       119 unless ($t->isLeaf()) {
    145 32         137 my $uid = $self->_createUID($t);
    146 32         530 push @results => ($list_item_func->($t, EXPANDED, $uid));
    147 32         755 push @results => $list_func->(OPEN_TAG, $uid);
    148             }
    149             else {
    150 62         1209 push @results => ($list_item_func->($t));
    151             }
    152 94         637 $last_depth = $current_depth;
    153 7         26 };
    154 7 100       13 $traversal_sub->($self->{tree}) if $self->{include_trunk};
    155 7         15 $self->{tree}->traverse($traversal_sub);
    156 7         59 $last_depth -= $root_depth;
    157 7 100       13 $last_depth++ if $self->{include_trunk};
    158 7         111 push @results => ($list_func->(CLOSE_TAG) x ($last_depth + 1));
    159 7         252 return (join "\n" => @results);
    160             }
    161              
    162             # code strings
    163              
    164 1         274 use constant LIST_FUNCTION_CODE_STRING => q|
    165             sub {
    166             my ($tag_type, $list_id, $display_style) = @_;
    167             # allow this to be found quickly
    168             return "" if ($tag_type == CLOSE_TAG);
    169             # test the most functional first
    170             if ($tag_type == OPEN_TAG && $list_id && $display_style) {
    171             my $temp_list_css;
    172             if ($list_css && $list_css !~ /CLASS/) {
    173             # in case someone has already set the list_css
    174             # property, we need to add out display property
    175             # to it, so we need to do a little text mangling
    176             $temp_list_css = $list_css;
    177             chop($temp_list_css);
    178             $temp_list_css .= " display: $display_style;'";
    179             }
    180             elsif ($list_css) {
    181             $temp_list_css = "${list_css} STYLE='display: $display_style;'"
    182             }
    183             else {
    184             $temp_list_css = " STYLE='display: $display_style;'"
    185             }
    186             return "<${list_type}${temp_list_css} ID='${list_id}'>"
    187             }
    188             # next...
    189             return "<${list_type}${list_css} ID='${list_id}'>"
    190             if ($tag_type == OPEN_TAG && $list_id);
    191             # and finally, something that does nothing really
    192             return "<${list_type}${list_css}>" if ($tag_type == OPEN_TAG);
    193             }
    194 1     1   4 |;
      1         1  
    195              
    196             sub _buildListItemFunction {
    197 12     12   23 my ($self, %config) = @_;
    198             # process the configuration directives
    199 12         30 my ($list_item_css, $expanded_item_css, $node_formatter) = $self->_processListItemConfig(%config);
    200              
    201 12         15 my $link_css = "";
    202 12 100       24 if (exists $config{link_css}) {
        100          
    203 2         3 $link_css = " STYLE='" . $config{link_css}. "'";
    204             }
    205             elsif (exists $config{link_css_class}) {
    206 3         4 $link_css = " CLASS='" . $config{link_css_class} . "'";
    207             }
    208              
    209 12         9 my $form_element_formatter;
    210 12 50       14 if (exists $config{form_element_formatter}) {
    211 0         0 $form_element_formatter = $config{form_element_formatter};
    212             }
    213             else {
    214 12 100       20 if (exists $config{radio_button}) {
        100          
    215 1         4 $form_element_formatter = $self->_makeRadioButtonFormatter($config{radio_button});
    216             }
    217             elsif (exists $config{checkbox}) {
    218 1         3 $form_element_formatter = $self->_makeCheckBoxFormatter($config{checkbox});
    219             }
    220             }
    221              
    222             # now compile the subroutine in the current environment
    223 12         1659 return eval $self->LIST_ITEM_FUNCTION_CODE_STRING;
    224             }
    225              
    226             sub _makeRadioButtonFormatter {
    227 1     1   1 my ($self, $radio_button_id) = @_;
    228             return sub {
    229 15     15   10 my ($t) = @_;
    230 15         31 return "";
    231             }
    232 1         3 }
    233              
    234             sub _makeCheckBoxFormatter {
    235 1     1   2 my ($self, $checkbox_id) = @_;
    236             return sub {
    237 15     15   9 my ($t) = @_;
    238 15         25 return "";
    239             }
    240 1         3 }
    241              
    242 1         42 use constant LIST_ITEM_FUNCTION_CODE_STRING => q|;
    243             sub {
    244             my ($t, $is_expanded, $tree_id) = @_;
    245             my $item_css = $list_item_css;
    246             if ($is_expanded) {
    247             $item_css = $expanded_item_css if $expanded_item_css;
    248             return "" .
    249             (($form_element_formatter) ? $form_element_formatter->($t) : "") .
    250             "" .
    251             (($node_formatter) ? $node_formatter->($t) : $t->getNodeValue()) .
    252             "";
    253             }
    254             return "" .
    255             (($form_element_formatter) ? $form_element_formatter->($t) : "") .
    256             (($node_formatter) ? $node_formatter->($t) : $t->getNodeValue()) .
    257             "";
    258             }
    259 1     1   4 |;
      1         1  
    260              
    261 1         39 use constant javascript => q|
    262            
    275 1     1   3 |;
      1         1  
    276              
    277             1;
    278              
    279             __END__