[LON-CAPA-cvs] cvs: loncom /publisher lonpubdir.pm

raeburn raeburn at source.lon-capa.org
Mon May 11 15:45:58 EDT 2026


raeburn		Mon May 11 19:45:58 2026 EDT

  Modified files:              
    /loncom/publisher	lonpubdir.pm 
  Log:
  - WCAG 2 compliance
    - Include landmark for page's main content to support "Skip to main content".
    - Include labels for form elements.
    - Use <th> tags for column headings and row headings in data table
      with scope="row" attribute for latter.
    - For form elements in data table cells use aria-labelledby to reference 
      appropriate column and row headers.
    - Satisfy minimum spacing between touch targets.
  
  
-------------- next part --------------
Index: loncom/publisher/lonpubdir.pm
diff -u loncom/publisher/lonpubdir.pm:1.184 loncom/publisher/lonpubdir.pm:1.185
--- loncom/publisher/lonpubdir.pm:1.184	Fri Aug  1 16:57:44 2025
+++ loncom/publisher/lonpubdir.pm	Mon May 11 19:45:58 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Authoring Space Directory Lister
 #
-# $Id: lonpubdir.pm,v 1.184 2025/08/01 16:57:44 raeburn Exp $
+# $Id: lonpubdir.pm,v 1.185 2026/05/11 19:45:58 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -224,8 +224,10 @@
 
     # Print column headers
     my $output = '';
+    my $colnum = 0;
     foreach my $key (@order) {
         my $idx;
+        $colnum ++;
         # Append an up or down arrow to sorted column
         if ($sortby eq $key) {
             $idx = ($columns{$key}{order} eq 'ascending') ? 0:1;
@@ -233,11 +235,11 @@
             $idx = $idx%2;
         } else { $idx = 2; } # No arrow if column is not sorted
         $output .= (($columns{$key}{order}) ?
-            '<th'.($columns{$key}{colspan} ? ' colspan="'.$columns{$key}{colspan}.'"' : '')
+            '<th id="col'.$colnum.'"'.($columns{$key}{colspan} ? ' colspan="'.$columns{$key}{colspan}.'"' : '')
             .'><a href="'.$linkdir.'/?sortby='.$key.'&sortorder='
             .((($sortby eq $key) && ($sortorder ne 'rev')) ? 'rev' : '').'">'
             .$columns{$key}{text}.$arrows[$idx].'</a></th>' :
-            '<th>'.$columns{$key}{text}.'</th>');
+            '<th id="col'.$colnum.'">'.$columns{$key}{text}.'</th>');
     }
 
 my $result = "<script type=\"text/javascript\">
@@ -344,14 +346,16 @@
 
     # Print the sorted resources
     my %editors = &Apache::loncommon::permitted_editors();
+    my $rownum = 0;
     foreach my $filename (@sorted_files) {
+        $rownum ++;
         if ($filehash->{$filename}->{"cmode"}&$dirptr) {        # Directories
-            &putdirectory($r, $thisdisfn, $linkdir, $filename,
+            &putdirectory($r, $thisdisfn, $linkdir, $filename, $rownum,
                 $filehash->{$filename}->{"cmtime"},
                 $targetdir, \%bombs, \$numdir);
         } else {                                                # Files
-            &putresource($r, $udom, $uname, $filename, $thisdisfn, $resdir,
-                $targetdir, $linkdir, $crsauthor,
+            &putresource($r, $udom, $uname, $filename, $rownum, $thisdisfn,
+                $resdir, $targetdir, $linkdir, $crsauthor,
                 $filehash->{$filename}->{"cmtime"},
                 $filehash->{$filename}->{"size"}, \$numres,
                 $filehash->{$filename}->{"linkfilename"},
@@ -437,7 +441,7 @@
                                                            $disk_quota,'authoring')
                     .'</div>'
                     .&Apache::loncommon::CSTR_pageheader('','',$headertext)));
-
+    $r->print("\n".'<div class="LC_landmark" role="main" id="LC_main_content">'."\n");
     my $esc_thisdisfn = &Apache::loncommon::escape_single($thisdisfn);
     my $doctitle = 'LON-CAPA '.&mt($title);
     my $newname = &mt('New Name');
@@ -560,10 +564,14 @@
                                        type => 'Type Name Here',
                                        go   => 'Go',
                                        crea => 'Create a new subdirectory or document',
+                                       nmne => 'Name of new subdirectory or document',
                                        qs   => 'Quick name search',
+                                       este => 'Enter search term',
+                                       srte => 'Search term',
                                        cs   => 'Case Sensitive',
                                        re   => 'Regular Expression',
 				       updc => 'Upload a new document',
+                                       namf => 'Name of file to upload',
 				       pick => 'Please select an action to perform using the new filename',
                                        shcu => 'Shortcuts',
                                       );
@@ -580,10 +588,10 @@
     $r->printf(<<END,&Apache::loncommon::help_open_topic('Quicksearch'));
 <div class="LC_columnSection">
     <div>
-      <fieldset style="display:inline">
+      <fieldset style="display: inline; line-height: 185%;">
             <legend>$lt{'qs'}</legend>
                 <script type="text/javascript" src="/adm/quicksearch/quicksearch.js"></script>
-                <input type="text" id="quickfilter" placeholder="Enter search term" onkeyup="applyFilter()"/>
+                <input type="text" id="quickfilter" placeholder="$lt{'este'}" onkeyup="applyFilter()" aria-label="$lt{'srte'}" />
                 <input type="button" value="Clear" onclick="document.getElementById(\'quickfilter\').value=\'\'; applyFilter()" />
                 %s
                 <br />
@@ -617,14 +625,15 @@
                                                    'newtaskfile','newlibraryfile',
                                                    'newdir'));
     }
-    my $selectbox = &Apache::loncommon::select_form('none','action',\%fileoptions);
+    my $selectbox = &Apache::loncommon::select_form('none','action',\%fileoptions,
+                                                    '','','','',&mt('Choose new file/directory action'));
     $r->print(<<END);
   <div style="padding-bottom: 2px">
     <form name="upublisher" enctype="multipart/form-data" method="post" action="/adm/upload">
       <fieldset>
         <legend>$lt{'updc'}</legend>
         <input type="hidden" name="filename" value="/priv$thisdisfn/" />
-        <input type="file" name="upfile" class="LC_flUpload" />
+        <input type="file" name="upfile" class="LC_flUpload" aria-label="$lt{'namf'}" />
         <input type="hidden" id="LC_free_space" value="$free_space" />
         <input type="button" value="$lt{'uplo'}"  onclick="checkUpload(this.form)" />
       </fieldset>
@@ -647,7 +656,7 @@
                         }
                     }
                   </script>
-		  $selectbox <input type="text" id="newnameid" name="newfilename" placeholder="$lt{'type'}" value="" onfocus="if (this.value == is.empty()) this.value=''" /> <input type="button" value="Go" onclick="validate_go();" />
+		  $selectbox <input type="text" id="newnameid" name="newfilename" placeholder="$lt{'type'}" value="" onfocus="if (this.value == is.empty()) this.value=''" aria-label="$lt{'nmne'}" /> <input type="button" value="Go" onclick="validate_go();" />
 		<br />
                 <span>$lt{'shcu'}:
                  <input type="hidden" name="mode"/>
@@ -761,11 +770,12 @@
 }
 #
 #  Put out a directory table row:
-#    putdirectory(r, base, here, dirname, modtime, targetdir, bombs, numdir)
+#    putdirectory(r, reqfile, here, dirname, rownum, modtime, targetdir, bombs, numdir)
 #      r         - Apache request object.
 #      reqfile   - File in request.
 #      here      - Where we are in directory tree.
 #      dirname   - Name of directory special file.
+#      rownum    - Number or current row in table listing items in current directory.
 #      modtime   - Encoded modification time.
 #      targetdir - Publication target directory.
 #      bombs     - Reference to hash of URLs with runtime error messages.
@@ -773,7 +783,7 @@
 #                  in directory (used in form name for each "actions" dropdown).
 #
 sub putdirectory {
-    my ($r, $reqfile, $here, $dirname, $modtime, $targetdir, $bombs, $numdir) = @_;
+    my ($r, $reqfile, $here, $dirname, $rownum, $modtime, $targetdir, $bombs, $numdir) = @_;
 
 # construct the display filename: the directory name unless ..:
 
@@ -804,7 +814,7 @@
             $actionitem =
                     '<form name="dirselect_'.$$numdir.
                     '" action="/adm/publish">'.
-                    '<select name="diraction" onchange="SetPubDir(this.form,document)">'.
+                    '<select name="diraction" onchange="SetPubDir(this.form,document)" aria-labelledby="col2 row'.$rownum.'">'.
                       '<option selected="selected">'.&mt('Select action').'</option>'.
                       '<option value="open">'.&mt('Open').'</option>'.
                       '<option value="publish">'.&mt('Publish').'</option>'.
@@ -822,8 +832,8 @@
 		  '<td><img src="'.
 		  $Apache::lonnet::perlvar{'lonIconsURL'}.'/navmap.folder.closed.gif" alt="folder" /></td>'.
 		  '<td>'.$actionitem.'</td>'.
-		  '<td><span class="LC_filename"><a href="'.&HTML::Entities::encode($here.'/'.$dirname,'<>&"').'/">'.
-		  $disfilename.'</a></span></td>'.
+		  '<th scope="row" class="LC_rowheader" id="row'.$rownum.'"><span class="LC_filename"><a href="'.&HTML::Entities::encode($here.'/'.$dirname,'<>&"').'/">'.
+		  $disfilename.'</a></span></th>'.
 		        '<td colspan="3">'.($kaputt?&Apache::lonhtmlcommon::authorbombs($targetdir.'/'.$disfilename.'/'):'').$Apache::lonpublisher::metadatafields{'title'});
 	if ($Apache::lonpublisher::metadatafields{'subject'} ne '') {
 	    $r->print(' <i>'.
@@ -951,7 +961,7 @@
 #   Put a table row for a file resource.
 #
 sub putresource {
-    my ($r, $udom, $uname, $filename, $thisdisfn, $resdir,
+    my ($r, $udom, $uname, $filename, $rownum, $thisdisfn, $resdir,
         $targetdir, $linkdir, $crsauthor, $cmtime, $size,
         $numres, $linkfilename, $title, $status, $pubstatus,
         $editors) = @_;
@@ -986,17 +996,17 @@
     my $publish_button = (-e $resdir.'/'.$filename) ? &mt('Re-publish') : &mt('Publish');
     my $pub_select = '';
     unless (($crsauthor) && ($filename=~ /\.rights$/)) {
-        &create_pubselect($r,\$pub_select,$udom,$uname,$thisdisfn,$filename,$resdir,$pubstatus,$publish_button,$numres);
+        &create_pubselect($r,\$pub_select,$udom,$uname,$thisdisfn,$filename,$resdir,$pubstatus,$publish_button,$numres,$rownum);
     }
     $r->print(&Apache::loncommon::start_data_table_row().
 	      '<td>'.($filename=~/[\#\~]$/?' ':
 		      '<img src="'.&Apache::loncommon::icon($filename).'" alt="" />').'</td>'.
               '<td>'.$pub_select.'</td>'.
-	      '<td><span class="LC_filename">'.
+	      '<th scope="row" class="LC_rowheader" id="row'.$rownum.'" style="line-height: 185%;"><span class="LC_filename">'.
 	      '<a href="'.$linkdir.'/'.$filename.'">'.
                $filename.'</a></span>'.$editlink2.$editlink.
-	      '</td>'.
-	      '<td>'.$title.'</td>'.
+	      '</th>'.
+	      '<td style="line-height: 185%;">'.$title.'</td>'.
               '<td class="LC_browser_file_'.$pubstatus.'">  </td>'. # Display publication status
               '<td>'.$status.'</td>'.
 	      '<td>'.&Apache::lonlocal::locallocaltime($cmtime).'</td>'.
@@ -1007,10 +1017,10 @@
 }
 
 sub create_pubselect {
-    my ($r,$pub_select,$udom,$uname,$thisdisfn,$filename,$resdir,$pubstatus,$publish_button,$numres) = @_;
+    my ($r,$pub_select,$udom,$uname,$thisdisfn,$filename,$resdir,$pubstatus,$publish_button,$numres,$rownum) = @_;
     $$pub_select = '
 <form name="resselect_'.$$numres.'" action="">
-<select name="reschoice"  onchange="SetResChoice(this.form)">
+<select name="reschoice" onchange="SetResChoice(this.form)" aria-labelledby="col2 row'.$rownum.'">
 <option>'.&mt('Select action').'</option>'.
 '<option value="copy">'.&mt('Copy').'</option>';
     if ($pubstatus eq 'obsolete' || $pubstatus eq 'unpublished') {
@@ -1273,20 +1283,21 @@
     $str = getTitleString($fullname);
         $fullname - Fully qualified filename to check.
 
-=item putdirectory($r, $base, $here, $dirname, $modtime, $targetdir, $bombs,
-                   $numdir)
+=item putdirectory($r, $reqfile, $here, $dirname, $rownum, $modtime, $targetdir,
+                   $bombs, $numdir)
 
     Put out a directory table row:
 
-        $r        - Apache request object.
-        $reqfile  - File in request.
-        $here     - Where we are in directory tree.
-        $dirname  - Name of directory special file.
-        $modtime  - Encoded modification time.
-        targetdir - Publication target directory.
-        bombs     - Reference to hash of URLs with runtime error messages.
-        numdir    - Reference to scalar used to track number of sub-directories
-                    in directory (used in form name for each "actions" dropdown).
+        $r         - Apache request object.
+        $reqfile   - File in request.
+        $here      - Where we are in directory tree.
+        $dirname   - Name of directory special file.
+        $rownum    - Number or current row in table listing items in current directory.
+        $modtime   - Encoded modification time.
+        $targetdir - Publication target directory.
+        $bombs     - Reference to hash of URLs with runtime error messages.
+        $numdir    - Reference to scalar used to track number of sub-directories
+                     in directory (used in form name for each "actions" dropdown).
 
 =back
 


More information about the LON-CAPA-cvs mailing list