[LON-CAPA-cvs] cvs: loncom /interface loncommon.pm lonhtmlcommon.pm lonmainmenu.pm lonmenu.pm

raeburn raeburn at source.lon-capa.org
Mon Mar 24 21:02:59 EDT 2025


raeburn		Tue Mar 25 01:02:59 2025 EDT

  Modified files:              
    /loncom/interface	lonmainmenu.pm lonmenu.pm loncommon.pm 
                     	lonhtmlcommon.pm 
  Log:
  - WCAG 2 compliance. 
    Replace layout table with divs. Eliminate duplicate links for icon and 
    text for each menu link. Customize  &generate_menu() already used for
    "Sub Menu" pages to also create "Main Menu" page.
  
  
-------------- next part --------------
Index: loncom/interface/lonmainmenu.pm
diff -u loncom/interface/lonmainmenu.pm:1.13 loncom/interface/lonmainmenu.pm:1.14
--- loncom/interface/lonmainmenu.pm:1.13	Mon Jun  7 06:05:49 2021
+++ loncom/interface/lonmainmenu.pm	Tue Mar 25 01:02:59 2025
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # displays the main menu
 #
-# $Id: lonmainmenu.pm,v 1.13 2021/06/07 06:05:49 raeburn Exp $
+# $Id: lonmainmenu.pm,v 1.14 2025/03/25 01:02:59 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -44,7 +44,7 @@
 sub handler {
     my $r = shift;
 
-    # Check for critical messages and redirect if present.  
+    # Check for critical messages and redirect if present.
     my ($redirect,$url) = &Apache::loncommon::critical_redirect(300,'menu');
     if ($redirect) {
         &Apache::loncommon::content_type($r,'text/html');
@@ -62,32 +62,71 @@
 # the main menu
     $env{'browser.interface'}='faketextual';
 
-    $r->print(&Apache::loncommon::start_page( 'Main Menu',
-                                               undef,
-                                              {'bread_crumbs' => 1}));
 #
-# If menu collection is in effect in course context, and Main Menu is 
-# not included, display message in place of usual menu items.
+# If menu collection is in effect in course context, determine if Main Menu
+# will be shown.
 #
+    my $showmenu = 1;
+    my $deeplinkmenu;
     if ($env{'request.course.id'}) {
-        my ($menucoll,$deeplinkmenu,$menuref) =
+        (my $menucoll,$deeplinkmenu,my $menuref) =
             &Apache::loncommon::menucoll_in_effect();
-        if ($menucoll) {
-            if (ref($menuref) eq 'HASH') {
-                if ($menuref->{'main'} eq 'n') {
-                    $r->print('<h3>'.&mt('Main Menu unavailable').'</h3>');
-                    unless ($deeplinkmenu) {
-                        my $crstype = &Apache::loncommon::course_type();
-                        $r->print('<p>'.&mt("Main Menu page is unavailable in this $crstype").'</p>');
-                    }
-                    $r->print(&Apache::loncommon::end_page());
-                    return OK;
-                }
+        if (($menucoll) && (ref($menuref) eq 'HASH')) {
+            if ($menuref->{'main'} eq 'n') {
+                $showmenu = 0;
+            }
+        }
+    }
+    my $js;
+    my $args = { 'bread_crumbs' => 1 };
+    if ($showmenu) {
+        $js = <<"END";
+<script type="text/javascript">
+// <![CDATA[
+function formatMenuText() {
+    var textArray = document.getElementsByClassName("LC_menu_text");
+    if (textArray.length > 0) {
+        var singleLineHeight = textArray[0].offsetHeight;
+        for (var i=1; i<textArray.length; i++) {
+            if (textArray[i].offsetHeight > singleLineHeight) {
+                var el = textArray[i].previousElementSibling;
+                el.style.cssFloat = "left";
+                el.style.marginRight = "5px";
             }
         }
     }
-    $r->print(&Apache::lonmenu::inlinemenu());
-    $r->print(&Apache::loncommon::end_page());
+}
+// ]]>
+</script>
+END
+        $args->{'add_entries'} = { 'onload' => 'javascript:formatMenuText();' };
+    }
+
+    $r->print(&Apache::loncommon::start_page( 'Main Menu',$js,$args).
+              '<div class="LC_landmark" role="main">');
+#
+# If menu collection is in effect in course context, and Main Menu is 
+# not included, display message in place of usual menu items.
+#
+    unless ($showmenu) {
+        my $nomenumsg;
+        my $crstype = &Apache::loncommon::course_type();
+        if ($deeplinkmenu) {
+            $nomenumsg = &mt('Page unavailable');
+        } else {
+            $nomenumsg = &mt("Main Menu page is unavailable in this $crstype");
+        }
+        $r->print('<h1 class="LC_heading_3">'.$nomenumsg.'</h1>'.
+                  '</div>'.&Apache::loncommon::end_page());
+        return OK;
+    }
+#
+# A span with class of LC_menu_text needs to be first item with that class.
+# It will be used by formatMenuText() to determine the offsetHeight for a single line.
+#
+    $r->print('<span class="LC_menu_text"> </span>'.
+              &Apache::lonmenu::inlinemenu().
+              '</div>'.&Apache::loncommon::end_page());
     return OK;
 }
 
Index: loncom/interface/lonmenu.pm
diff -u loncom/interface/lonmenu.pm:1.561 loncom/interface/lonmenu.pm:1.562
--- loncom/interface/lonmenu.pm:1.561	Fri Feb 21 04:29:26 2025
+++ loncom/interface/lonmenu.pm	Tue Mar 25 01:02:59 2025
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the menu
 #
-# $Id: lonmenu.pm,v 1.561 2025/02/21 04:29:26 raeburn Exp $
+# $Id: lonmenu.pm,v 1.562 2025/03/25 01:02:59 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1168,7 +1168,7 @@
                 $domselector = &Apache::loncommon::select_dom_form($defdom,'vudom','','','',
                                                                    \@possdoms,'','','vudom').
                                '<span class="LC_visually_hidden"><label for="vudom">'.
-                               &mt("user's domain").'</label></span>';                
+                               &mt("user's domain").'</label></span>';
             } elsif (($possdomstr ne '') && (&Apache::lonnet::domain($possdomstr) ne '')) {
                 if ($env{'request.user_in_effect'} =~ /^$match_username:($match_domain)$/) {
                     $defdom = $1;
@@ -1956,7 +1956,16 @@
     my ($text,$alttext);
     $text=&mt($top).' '.&mt($bot);
     $text=~s/\s*\-\s*//gs;
-    if ($top) {
+    if ($top && $bot) {
+        if ($top =~ /\-\[_\d+\]$/) {
+            $top =~ s/(\-\[_\d+\])//;
+            $alttext = &mt($top.$bot.' icon');
+        } elsif (($top =~ /^\w+\s\w+\[_\d+\]$/) && ($bot =~ /^\w{8}\[_\d+\]$/)) {
+            $alttext = &mt($top.$bot.' icon');
+        } else {
+            $alttext = &mt("$top $bot icon");
+        }
+    } elsif ($top) {
         $alttext = &mt("$top icon");
     } elsif ($bot) {
         $alttext = &mt("$bot icon");
@@ -1974,23 +1983,14 @@
 	   '" align="'.($nobreak==3?'right':'left').'" class="LC_icon" />';
     if ($env{'browser.interface'} eq 'faketextual') {
 # Main Menu
-	   if ($nobreak==3) {
-	       $inlineremote[$idx]="\n".
-		   '<th class="LC_menubuttons_text" align="right">'.$text.
-		   '</th><td align="left">'.
-		   '<a href="javascript:'.$act.';">'.$pic.'</a></td></tr>';
-	   } elsif ($nobreak) {
-	       $inlineremote[$idx]="\n<tr>".
-		   '<th align="left">'.
-		   '<a href="javascript:'.$act.';">'.$pic.'</a></th>
-                    <td class="LC_menubuttons_text" align="left"><a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$text.'</span></a></td>';
-	   } else {
-	       $inlineremote[$idx]="\n<tr>".
-		   '<th align="left">'.
-		   '<a href="javascript:'.$act.';">'.$pic.
-		   '</a></th><td class="LC_menubuttons_text" colspan="3">'.
-		   '<a class="LC_menubuttons_link" href="javascript:'.$act.';"><span class="LC_menubuttons_inline_text">'.$desc.'</span></a></td></tr>';
-	   }
+        $inlineremote[$idx] = {
+                                linktext => $desc,
+                                url => 'javascript:'.$act,
+                                permission => 'F',
+                                icon => $img,
+                                alttext => $alttext,
+                                linktitle => '',
+                              };
     } else {
 # Inline Menu
         my @tools = (93,91,81,82,83);
@@ -2031,32 +2031,33 @@
     undef(%category_members);
 # calling rawconfig with "1" will evaluate mydesk.tab, even if there is no active remote control
     &rawconfig(1);
-    my $output='<div class="LC_landmark" role="main">'."\n";
+    my $output;
     for (my $col=1; $col<=2; $col++) {
         $output .= '<div class="LC_mainmenu">'."\n";
         for (my $row=1; $row<=8; $row++) {
             foreach my $cat (keys(%category_members)) {
-               if ($category_positions{$cat} ne "$col,$row") { next; }
-               #$output.='<table><tr><td colspan="4" class="LC_menubuttons_category">'.&mt($category_names{$cat}).'</td></tr>';
-               $output.='<div class="LC_Box LC_400Box">';
-	       $output.='<h2 class="LC_hcell LC_heading_2">'.&mt($category_names{$cat}).'</h2>';
-               $output.='<table>';
-               my %active=();
-               foreach my $menu_item (split(/\:/,$category_members{$cat})) {
-                  if ($inlineremote[$menu_item]) {
-                     $active{$menu_item}=1;
-                  }
-               }  
-               foreach my $item (sort(keys(%active))) {
-                  $output.=$inlineremote[$item];
-               }
-               $output.='</table>';
-               $output.='</div>';
+                my @menu =  ({ categorytitle=>&mt($category_names{$cat}),
+                               listclass=>'LC_ListStyleMainMenu',
+                               boxclass=>'LC_MainMenu_Box',
+                               items        =>[],});
+                if ($category_positions{$cat} ne "$col,$row") { next; }
+                my %active=();
+                foreach my $menu_item (split(/\:/,$category_members{$cat})) {
+                    if ($inlineremote[$menu_item]) {
+                        $active{$menu_item}=1;
+                    }
+                }
+                foreach my $item (sort(keys(%active))) {
+                    push(@{ $menu[0]->{items} }, $inlineremote[$item]);
+                }
+                if (@{$menu[0]->{items}} > 0) {
+                    $output .= &Apache::lonhtmlcommon::generate_menu(@menu);
+                }
             }
-         }
-         $output.="</div>";
+        }
+        $output.="</div>";
     }
-    $output .= '<div style="clear:both"></div></div>'."\n";
+    $output .= '<div style="clear:both"></div>'."\n";
     return $output;
 }
 
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1475 loncom/interface/loncommon.pm:1.1476
--- loncom/interface/loncommon.pm:1.1475	Mon Mar 24 17:05:59 2025
+++ loncom/interface/loncommon.pm	Tue Mar 25 01:02:59 2025
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1475 2025/03/24 17:05:59 raeburn Exp $
+# $Id: loncommon.pm,v 1.1476 2025/03/25 01:02:59 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -7685,6 +7685,10 @@
   text-decoration: none;
 }
 
+.LC_menubuttons_link img {
+  vertical-align: middle;
+}
+
 .LC_menubuttons_category {
   color: $font;
   background: $pgbg;
@@ -7692,7 +7696,9 @@
   font-weight: bold;
 }
 
-td.LC_menubuttons_text {
+.LC_menu_text {
+  clear: left;
+  text-align: left;
   color: $font;
 }
 
@@ -8703,6 +8709,7 @@
   border-bottom:solid 1px $lg_border_color;
 }
 
+.LC_MainMenu_Box > .LC_hcell,
 .LC_Box > .LC_hcell {
   margin: 0 -10px 10px -10px;
 }
@@ -9155,6 +9162,11 @@
   padding: 0 0 10px 10px;
 }
 
+.LC_MainMenu_Box {
+  border: solid 1px $lg_border_color;
+  padding: 0 10px 0 10px;
+}
+
 .LC_AboutMe_Image {
   float:left;
   margin-right:10px;
@@ -9176,6 +9188,7 @@
 .LC_ListStyleClean,
 .LC_ListStyleSimple,
 .LC_ListStyleNormal,
+.LC_ListStyleMainMenu,
 .LC_ListStyleSpecial {
   /* display:block; */
   list-style-position: inside;
@@ -9213,6 +9226,12 @@
   margin-bottom: 4px;
 }
 
+.LC_ListStyleMainMenu li {
+  margin: 0;
+  padding: 2px 5px 2px 10px;
+  clear: both;
+}
+
 table.LC_SimpleTable {
   margin:5px;
   border:solid 1px $lg_border_color;
Index: loncom/interface/lonhtmlcommon.pm
diff -u loncom/interface/lonhtmlcommon.pm:1.421 loncom/interface/lonhtmlcommon.pm:1.422
--- loncom/interface/lonhtmlcommon.pm:1.421	Thu Mar  6 16:51:36 2025
+++ loncom/interface/lonhtmlcommon.pm	Tue Mar 25 01:02:59 2025
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common html routines
 #
-# $Id: lonhtmlcommon.pm,v 1.421 2025/03/06 16:51:36 raeburn Exp $
+# $Id: lonhtmlcommon.pm,v 1.422 2025/03/25 01:02:59 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -3964,6 +3964,8 @@
 # Inputs:
 # An array of following structure:
 #   ({	categorytitle => 'Categorytitle',
+#       listclass=>'class to use for <ul> tag for listed items in category (optional)
+#       boxclass=>'a class to use for the div which provides the box for the category (optional),
 #	items => [
 #		    {	
 #           linktext    =>	'Text to be displayed',
@@ -3981,13 +3983,15 @@
 #   ...
 #   )
 #
+# if listclass is not provided, LC_ListStyleNormal will be used.  
+# if box class is not provided, LC_Box will be used.
 # Outputs: A scalar containing the html markup for the menu.
 
 sub generate_menu {
     my @menu = @_;
     # subs for specific html elements
-    my ($h2, $div, $ul, $li, $a, $img) = inittags( qw(h2 div ul li a img) );
-    
+    my ($h2, $div, $ul, $li, $a, $img, $span) = inittags( qw(h2 div ul li a img span) );
+
     my @categories; # each element represents the entire markup for a category
    
     foreach my $category (@menu) {
@@ -4009,7 +4013,8 @@
                                 src   => $src,
                                 alt   => mt(defined($$link{alttext}) ?
                                 $$link{alttext} : $$link{linktext})
-                            }).mt($$link{linktext}), {
+                            }).$span->(mt($$link{linktext}), {
+                                       class => "LC_menu_text",}), {
                             href  => $$link{url},
                             title => mt($$link{linktitle}),
                             class => "LC_menubuttons_link"
@@ -4018,6 +4023,14 @@
                          Apache::loncommon::help_open_topic($$link{help}) : ''),
                          {class => "LC_menubuttons_inline_text"}));
         }
+        my $ulclass = 'LC_ListStyleNormal';
+        if ($category->{'listclass'} ne '') {
+            $ulclass = $category->{'listclass'};
+        }
+        my $boxclass = 'LC_Box';
+        if ($category->{'boxclass'} ne '') {
+            $boxclass = $category->{'boxclass'};
+        }
 
         # wrap categorytitle in <h2>, concatenate with 
         # joined and in <ul> tags wrapped @links
@@ -4028,8 +4041,8 @@
         # the category won't be added if there aren't any links
         push(@categories, 
             $div->($h2->(mt($$category{categorytitle}), {class=>'LC_hcell LC_heading_2'}).
-            $ul->(join('' , at links),  {class =>"LC_ListStyleNormal" }),
-            {class=>"LC_Box LC_400Box"})) if scalar(@links);
+            $ul->(join('' , at links),  {class =>"$ulclass" }),
+            {class=>"$boxclass LC_400Box"})) if scalar(@links);
     }
 
     # wrap the joined @categories in another <div> (column layout)


More information about the LON-CAPA-cvs mailing list