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

raeburn raeburn at source.lon-capa.org
Wed May 6 13:55:19 EDT 2026


raeburn		Wed May  6 17:55:19 2026 EDT

  Modified files:              
    /loncom/publisher	loncfile.pm 
  Log:
  - WCAG 2 compliance.
    - Include landmark for page's main content to support "Skip to main content".
    - Include labels for form elements.
    - Replace use of <table> for layout with <div>.
  - Display meaningful message if action is "archive" or "accessibility" and
    directory (or file) context has been lost.
  
  
-------------- next part --------------
Index: loncom/publisher/loncfile.pm
diff -u loncom/publisher/loncfile.pm:1.134 loncom/publisher/loncfile.pm:1.135
--- loncom/publisher/loncfile.pm:1.134	Thu Apr 16 22:41:04 2026
+++ loncom/publisher/loncfile.pm	Wed May  6 17:55:19 2026
@@ -9,7 +9,7 @@
 #  and displays a page showing the results of the action.
 #
 #
-# $Id: loncfile.pm,v 1.134 2026/04/16 22:41:04 raeburn Exp $
+# $Id: loncfile.pm,v 1.135 2026/05/06 17:55:19 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -850,35 +850,23 @@
                         (' 'x2).
                         '<input type="button" name="uncheckall" value="'.&mt('uncheck all').
                         '" style="height:20px;" onclick="uncheckAll(document.phaseone.filetype);" /></legend>'.
-                        '<table>');
-        my $rem;
+                        '<div class="LC_grid" role="grid" style="margin: 0;">');
         my $numinrow = 6;
         for (my $i=0; $i<@posstypes; $i++) {
             my $rem = $i%($numinrow);
             if ($rem == 0) {
                if ($i > 0) {
-                    $request->print('</tr>'."\n");
+                    $request->print('</div>'."\n");
                }
-               $request->print('<tr>'."\n");
+               $request->print('<div class="LC_grid_row" role="row">'."\n");
             }
-            $request->print('<td class="LC_left_item">'.
+            $request->print('<div class="LC_grid_cell" role="gridcell">'.
                             '<span class="LC_nobreak"><label>'.
                             '<input type="checkbox" name="filetype" '.
                             'value="'.$posstypes[$i].'" /> '.
-                            $posstypes[$i].'</label></span></td>'."\n");
+                            $posstypes[$i].'</label></span></div>'."\n");
         }
-        $rem = scalar(@posstypes)%($numinrow);
-        my $colsleft;
-        if ($rem) {
-            $colsleft = $numinrow - $rem;
-        }
-        if ($colsleft > 1 ) {
-            $request->print('<td colspan="'.$colsleft.'" class="LC_left_item">'.
-                            ' </td>'."\n");
-        } elsif ($colsleft == 1) {
-            $request->print('<td class="LC_left_item"> </td>'."\n");
-        }
-        $request->print('</tr></table>'."\n".
+        $request->print('</div></div>'."\n".
                         '</fieldset>'.
                         '<fieldset><legend>'.&mt('Archive file format').'</legend>');
         foreach my $possfmt ('tar','zip') {
@@ -909,11 +897,17 @@
         $request->print('</fieldset>'."\n".
                         '<fieldset style="display:none" id="archive_saveas">'.
                         '<legend>'.&mt('Filename to download').'</legend>'.
-                        '<table style="border-spacing:0"><tr><td style="padding:0;">'.&mt('Name').'<br />'."\n".
-                        '<input type="text" name="archivefname" value="" size="8" /></td><td style="padding:0;">'.
+                        '<div class="LC_grid" role="grid">'.
+                        '<div class="LC_grid_row" role="row">'.
+                        '<div class="LC_grid_cell" role="gridcell" style="margin-right: 0; padding-right: 0">'.
+                        &mt('Name').'<br />'."\n".
+                        '<input type="text" name="archivefname" value="" size="8"'.
+                        ' aria-label="'.&mt('Name to assign to file (excluding file extension)').'" /></div>'.
+                        '<div class="LC_grid_cell" role="gridcell" style="margin-left: 0; padding-left: 0;">'.
                         &mt('Extension').'<br />'."\n".
-                        '<input type="text" name="archiveext" id="archiveext" value="" size="4" readonly="readonly" />'.
-                        '</td></tr></table></fieldset>'."\n".
+                        '<input type="text" name="archiveext" id="archiveext" value="" size="4"'.
+                        ' readonly="readonly" aria-label="'.&mt('File extension (set automatically)').'" />'.
+                        '</div></div></div></fieldset>'."\n".
                         &Apache::lonhtmlcommon::row_closure(1).
                         &Apache::lonhtmlcommon::end_pick_box().'<br />'."\n"
         );
@@ -1012,7 +1006,7 @@
 
 sub cancel_archive_form {
     my ($r,$title,$fname,$earlyout,$idnum) = @_;
-    $r->print('<h2>'.$title.'</h2>'."\n".
+    $r->print('<h2 class="LC_heading_2">'.$title.'</h2>'."\n".
               '<form action="/adm/cfile" method="post" onsubmit="return confirmation(this);">'."\n".
               '<input type="hidden" name="filename" value="'.$fname.'" />'."\n".
               '<input type="hidden" name="action" value="'.$env{'form.action'}.'" />'."\n".
@@ -1058,42 +1052,30 @@
                       '<span class="LC_nobreak"><label><input type="checkbox" name="recurse" /> '.
                       &mt('include subdirectories').'</label></span>'.
                       '</fieldset>'.
-                      '<fieldset><legend>'.&mt('File types (extensions) to include').(' 'x2).
+                      '<fieldset style="margin: 0;"><legend>'.&mt('File types (extensions) to include').(' 'x2).
                       '<span style="text-decoration:line-through">'.(' 'x5).'</span>'.(' 'x2).
                       '<input type="button" name="checkall" value="'.&mt('check all').
                       '" style="height:20px;" onclick="checkAll(document.phaseone.filetype);" />'.
                       (' 'x2).
                       '<input type="button" name="uncheckall" value="'.&mt('uncheck all').
                       '" style="height:20px;" onclick="uncheckAll(document.phaseone.filetype);" /></legend>'.
-                      '<table>');
-            my $rem;
+                      '<div class="LC_grid" role="grid" style="margin: 0;">');
             my $numinrow = 6;
             for (my $i=0; $i<@posstypes; $i++) {
                 my $rem = $i%($numinrow);
                 if ($rem == 0) {
                     if ($i > 0) {
-                        $r->print('</tr>'."\n");
+                        $r->print('</div>'."\n");
                     }
-                    $r->print('<tr>'."\n");
+                    $r->print('<div class="LC_grid_row" role="row">'."\n");
                 }
-                $r->print('<td class="LC_left_item">'.
+                $r->print('<div class="LC_grid_cell" role="gridcell">'.
                           '<span class="LC_nobreak"><label>'.
                           '<input type="checkbox" name="filetype" '.
                           'value="'.$posstypes[$i].'" /> '.
-                          $posstypes[$i].'</label></span></td>'."\n");
-            }
-            $rem = scalar(@posstypes)%($numinrow);
-            my $colsleft;
-            if ($rem) {
-                $colsleft = $numinrow - $rem;
-            }
-            if ($colsleft > 1) {
-                $r->print('<td colspan="'.$colsleft.'" class="LC_left_item">'.
-                                ' </td>'."\n");
-            } elsif ($colsleft == 1) {
-                $r->print('<td class="LC_left_item"> </td>'."\n");
+                          $posstypes[$i].'</label></span></div>'."\n");
             }
-            $r->print('</tr></table>'."\n".
+            $r->print('</div></div>'."\n".
                       '</fieldset>');
         }
         $r->print('<fieldset class="LC_wcag"><legend>'.&mt('WCAG standard').'</legend>');
@@ -2012,10 +1994,37 @@
     }
 
     unless ($fn) {
-	&Debug($r, "loncfile::handler - doctored url is empty");
-	$r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
-		       ' trying to cfile non-existing file', $r->filename);
-	return HTTP_NOT_FOUND;
+        if (($env{'form.action'} eq 'archive') ||
+            ($env{'form.action'} eq 'accessibility')) {
+            my $text = 'File Operation';
+            my $title = 'Authoring Space File Operation';
+            &Apache::lonhtmlcommon::clear_breadcrumbs();
+            &Apache::lonhtmlcommon::add_breadcrumb({
+                'text'  => $text,
+                'title' => $title,
+                'href'  => '',
+            });
+            $r->print(&Apache::loncommon::start_page($title)
+                     .&Apache::lonhtmlcommon::breadcrumbs()
+                     .'<div class="LC_landmark" role="main" id="LC_main_content">'
+                     .'<h2 class="LC_heading_2">'.&mt('Unable to determine Authoring Space context').'</h2>');
+            if ($env{'form.action'} eq 'accessibility') {
+                $r->print('<p>'.
+                          &mt('Please display a resource or directory, and then click the "Accessibility" link/icon').
+                          '</p>');
+            } else {
+                $r->print('<p>'.
+                          &mt('Please display a directory, and then click the "Export" link/icon').
+                          '</p>');
+            }
+            $r->print('</div>'.&Apache::loncommon::end_page());
+            return OK;
+        } else {
+            &Debug($r, "loncfile::handler - doctored url is empty");
+            $r->log_reason($env{'user.name'}.' at '.$env{'user.domain'}.
+                           ' trying to cfile non-existing file', $r->filename);
+            return HTTP_NOT_FOUND;
+        }
     }
 
 # ----------------------------------------------------------- Start page output
@@ -2296,10 +2305,12 @@
     $r->print(&Apache::loncommon::start_page($title,$js,$args)
              .&Apache::lonhtmlcommon::breadcrumbs()
              .&Apache::loncommon::head_subbox(
-                  &Apache::loncommon::CSTR_pageheader($trailfile))
+                  &Apache::loncommon::CSTR_pageheader($trailfile))."\n"
+             .'<div class="LC_landmark" role="main" id="LC_main_content">'."\n"
     );
 
-    unless (($env{'form.action'} eq 'archive') || ($env{'form.action'} eq 'accessibility')) {
+    unless ((($env{'form.action'} eq 'accessibility') ||
+             ($env{'form.action'} eq 'archive')) && ($env{'form.phase'} ne 'two')) {
         $r->print('<p>'.&mt('Location').': '.&display($fn).'</p>');
     }
 
@@ -2312,7 +2323,6 @@
         }
     }
 
-
     &Debug($r, "loncfile::handler Form action is $env{'form.action'} ");
     my %action = &Apache::lonlocal::texthash(
         'delete'          => 'Delete',
@@ -2348,7 +2358,7 @@
                 (grep(/^\Q$newtype\E$/, at disallowed))) {
                 $r->print('<p class="LC_error">'
                          .&mt('Creation of a new file of type: [_1] is not permitted in Course Authoring Space',$newtype)
-                         .'</p>'
+                         .'</p></div>'
                          .&Apache::loncommon::end_page()
                 );
                 return OK;
@@ -2357,7 +2367,7 @@
                 $r->print('<p>'.&mt('Location').': '.&display($fn).'</p>'."\n".
                           '<p class="LC_error">'.
                           &mt('Export to an archive file is not permitted in Course Authoring Space').
-                          '</p>'."\n".
+                          '</p></div>'."\n".
                           &Apache::loncommon::end_page());
                 return OK; 
             }
@@ -2368,23 +2378,23 @@
                     my $title = $action{$env{'form.action'}};
                     &cancel_archive_form($r,$title,$fname,$archive_earlyout,$archive_idnum);
                     &CloseForm1($r,$fn);
-                    $r->print(&Apache::loncommon::end_page());
+                    $r->print('</div>'.&Apache::loncommon::end_page());
                     return OK;
                 }
             } else {
                 $r->print('<p>'.&mt('Location').': '.&display($fn).'</p>'."\n".
                           '<p class="LC_error">'.
                           &mt('You do not have permission to export to an archive file in this Authoring Space').
-                          '</p>'."\n".
+                          '</p></div>'."\n".
                           &Apache::loncommon::end_page());
                 return OK;
             }
         }
-        $r->print('<h2>'.$action{$env{'form.action'}}.'</h2>'."\n");
+        $r->print('<h2 class="LC_heading_2">'.$action{$env{'form.action'}}.'</h2>'."\n");
     } else {
         $r->print('<p class="LC_error">'
                  .&mt('Unknown Action: [_1]',$env{'form.action'})
-                 .'</p>'
+                 .'</p></div>'
                  .&Apache::loncommon::end_page()
         );
         return OK;
@@ -2398,7 +2408,7 @@
 	&phaseone($r,$fn,$uname,$udom);
     }
 
-    $r->print(&Apache::loncommon::end_page());
+    $r->print('</div>'.&Apache::loncommon::end_page());
     return OK;
 }
 


More information about the LON-CAPA-cvs mailing list