Commits

Anonymous committed 6b4df03

Nav-Menu:

A relatively large refactoring for making sure render_tree_contents does not
calculate the host of the node. What was done was create an iterator sub-class,
that traverses the tree looking for the current node and then returns
its coordinates and marked it as currently active.

Comments (0)

Files changed (5)

 
      In create_new_nav_menu_item, and in
      render_tree_contents.
-   
+
+        - Done.
 
 Long-Term:
 ----------
 * Use HTML::Widgets::NavMenu::Tree::Node and its accessors for the rest
   of the $ptr->{text} etc. manipulations.
 
-
 * Use Build.PL instead of Makefile.PL. (?)
 
 * Make the module support URLs with CGI GET parameters properly.
 
 * In HTML::Widgets::NavMenu::Tree::Node - make sure url_type accepts only
 its enum values.
-
-
-

module/lib/HTML/Widgets/NavMenu.pm

 
 package HTML::Widgets::NavMenu;
 
-our $VERSION = '0.3.1_00';
+our $VERSION = '0.3.2_00';
 
 package HTML::Widgets::NavMenu::Error;
 
 
 1;
 
+package HTML::Widgets::NavMenu::Iterator::GetCurrentlyActive;
+
+use base 'HTML::Widgets::NavMenu::Iterator::Base';
+
+sub initialize
+{
+    my $self = shift;
+
+    my %args = (@_);
+
+    $self->SUPER::initialize(@_);
+
+    $self->{'tree'} = $args{'tree'};
+
+    $self->{'item_found'} = 0;
+    
+    return 0;
+}
+
+sub get_initial_node
+{
+    my $self = shift;
+
+    return $self->{'tree'};
+}
+
+sub item_matches
+{
+    my $self = shift;
+    my $item = $self->top();
+    my $url = $item->node()->url();
+    my $nav_menu = $self->nav_menu();
+    return
+        (
+            ($item->accum_state()->{'host'} eq $nav_menu->current_host()) &&
+            (defined($url) && ($url eq $nav_menu->path_info()))
+        );
+}
+
+sub node_start
+{
+    my $self = shift;
+
+    if ($self->item_matches())
+    {
+        my @coords = @{$self->get_coords()};
+        $self->{'ret_coords'} = [ @coords ];
+        $self->{'temp_coords'} = [ @coords, (-1) ];
+        $self->top()->node()->mark_as_current();
+        $self->{'item_found'} = 1;
+    }
+}
+
+sub node_end
+{
+    my $self = shift;
+    if ($self->{'item_found'})
+    {
+        # Skip the first node, because the coords refer
+        # to the nodes below it.
+        my $idx = pop(@{$self->{'temp_coords'}});
+        if ($idx >= 0)
+        {
+            my $node = $self->top()->node();
+            $node->update_based_on_sub(
+                $node->get_nth_sub(
+                    $idx
+                )
+            );
+        }
+    }
+}
+
+sub node_should_recurse
+{
+    my $self = shift;
+    return (! $self->{'item_found'});
+}
+
+sub get_final_coords
+{
+    my $self = shift;
+
+    return $self->{'ret_coords'};
+}
+
 package HTML::Widgets::NavMenu;
 
 use strict;
     my %args = (@_);
 
     my $sub_contents = $args{sub_contents};
-    my $coords = $args{coords};
 
     my $new_item = $self->gen_blank_nav_menu_tree_node();
 
 
     my %args = (@_);
 
-    my $path_info = $self->path_info();    
+    my $path_info = $self->path_info();
 
     my $sub_contents = $args{sub_contents};
-    my $coords = $args{coords};
-    my $host = $sub_contents->{host} || $args{host} or
-        die "Host not specified!";
-    my $current_coords_ptr = $args{current_coords_ptr};
 
     my $new_item =
         $self->create_new_nav_menu_item(
             %args,
         );
 
-    if (exists($sub_contents->{url}))
-    {
-        if (($sub_contents->{url} eq $path_info) && ($host eq $self->current_host()))
-        {
-            $$current_coords_ptr = [ @$coords ];
-            $new_item->mark_as_current();
-        }
-    }
-
     if (exists($sub_contents->{subs}))
     {
-        my $index = 0;
-        my $subs = [];
         foreach my $sub_contents_sub (@{$sub_contents->{subs}})
         {
             $new_item->add_sub(
                 $self->render_tree_contents(
                     'sub_contents' => $sub_contents_sub,
-                    'coords' => [@$coords, $index],
-                    'host' => $host,
-                    'current_coords_ptr' => $current_coords_ptr,
                 )
             );
         }
-        continue
-        {
-            $index++;
-        }
     }
     return $new_item;
 }
     if (scalar(@coords) == 0)
     {
         return undef;
-    }    
+    }
     elsif ($coords[$#coords] > 0)
     {
         # Get the previous leaf
 
     my $callback = shift;
     my $coords = shift || $self->get_current_coords();
-    
+
     my $do_once = 1;
 
     while ($do_once || $self->is_skip($coords))
 
     my $tree = 
         $self->render_tree_contents(
-            'sub_tree' => undef,
             'sub_contents' => $self->{tree_contents},
-            'coords' => [],
-            'current_coords_ptr' => \$current_coords,
             );
 
+    my $find_coords_iterator =
+        HTML::Widgets::NavMenu::Iterator::GetCurrentlyActive->new(
+            'nav_menu' => $self,
+            'tree' => $tree,
+        );
+
+    $find_coords_iterator->traverse();
+
+    $current_coords = $find_coords_iterator->get_final_coords() || [];
+
     # The root should always be expanded because:
     # 1. If one of the leafs was marked as expanded so will its ancestors
     #    and eventually the root.

module/lib/HTML/Widgets/NavMenu/Tree/Iterator.pm

 
     $self->push_into_stack('node' => $self->get_initial_node());
 
+    $self->{'coords'} = [];
+
     my $top_item;
 
     MAIN_LOOP: while ($top_item = $self->top())
 
         if (defined($sub_item))
         {
+            push @{$self->{'coords'}}, $top_item->visited_index();
             $self->push_into_stack(
                 'node' =>
                     $self->get_node_from_sub(
         {
             $self->node_end();
             $self->stack->pop();
+            pop(@{$self->{'coords'}})
         }
     }
 
     return +{ 'item' => $item, };
 }
 
+sub get_coords
+{
+    my $self = shift;
+
+    return $self->{'coords'};
+}
 1;
 

module/lib/HTML/Widgets/NavMenu/Tree/Iterator/Item.pm

     }
 }
 
+sub visited_index
+{
+    my $self = shift;
+
+    return $self->{'sub_idx'};
+}
+
 sub num_subs_to_go
 {
     my $self = shift;

module/lib/HTML/Widgets/NavMenu/Tree/Node.pm

 {
     my $self = shift;
     my $sub = shift;
+    $self->update_based_on_sub($sub);    
+}
+
+sub update_based_on_sub
+{
+    my $self = shift;
+    my $sub = shift;
     if ($sub->expanded())
     {
         $self->expand();
-    }
+    }    
 }
 
 sub add_sub
     return 0;
 }
 
+sub get_nth_sub
+{
+    my $self = shift;
+    my $idx = shift;
+    return $self->subs()->[$idx];
+}
+
 sub list_regular_keys
 {
     my $self = shift;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.