[LON-CAPA-cvs] cvs: loncom /interface loncourserespicker.pm

raeburn raeburn at source.lon-capa.org
Mon Aug 24 12:59:04 EDT 2026


raeburn		Mon Aug 24 16:59:04 2026 EDT

  Modified files:              
    /loncom/interface	loncourserespicker.pm 
  Log:
  - Checking checkboxes for folders does not check boxes for any contained 
    resources for which form input elements are disabled.
  - Accessibility checking using puppeteer/axe-core and headless browser
    excludes external resources and external tools.
  - WCAG 2.2 compliance for view-only access to course editing tools
    - Group form elements in fieldset with legend for screenreaders when
      selecting resources needing URL shortcuts or accessibility checking.
  
  
-------------- next part --------------
Index: loncom/interface/loncourserespicker.pm
diff -u loncom/interface/loncourserespicker.pm:1.27 loncom/interface/loncourserespicker.pm:1.28
--- loncom/interface/loncourserespicker.pm:1.27	Mon Jun 29 19:28:12 2026
+++ loncom/interface/loncourserespicker.pm	Mon Aug 24 16:59:04 2026
@@ -1,6 +1,6 @@
 # The LearningOnline Network
 #
-# $Id: loncourserespicker.pm,v 1.27 2026/06/29 19:28:12 raeburn Exp $
+# $Id: loncourserespicker.pm,v 1.28 2026/08/24 16:59:04 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -368,6 +368,9 @@
         $info = '<span class="LC_fontsize_medium">'.
                 &mt('Choose the resource(s) and/or folder(s) from Main Content for which shortened URL(s) are needed.').
                 '</span><br /><br />';
+        if ($readonly) {
+            $disabled = ' disabled="disabled"';
+        }
     } elsif ($context eq 'imsexport') {
         $info = &mt('Choose which items you wish to export from your '.$crstype.'.');
         $startcount = 5;
@@ -382,6 +385,9 @@
         }
     } elsif ($context eq 'wcagcheck') {
         $startcount = 2;
+        if ($readonly) {
+            $disabled = ' disabled="disabled"';
+        }
     }
     if ($disabled) {
         $togglebuttons = '<br />';
@@ -412,16 +418,22 @@
                 '</fieldset>';
         }
         $display .= '</div>';
-    } elsif (($context eq 'shorturls') || ($context eq 'wcagcheck')) {
-        my $legend = $togglebuttons;
-        if ($context eq 'wcagcheck') {
-            $legend = '<span class="LC_nobreak">'.&mt('Main Content').': '.$togglebuttons.'</span>';
-            $display .= '<div class="LC_floatleft">';
+    } elsif ($context eq 'shorturls') {
+        if ($disabled) {
+            $display .= '<fieldset style="LC_borderless">'.
+                        '<legend class="LC_visually_hidden">'.&mt('Select Resources').'</legend>'."\n";
+        } else {
+            $display .= '<fieldset style="display: inline">'.
+                        '<legend>'.$togglebuttons.'</legend>'."\n";
         }
+    } elsif ($context eq 'wcagcheck') {
+        $display .= '<div class="LC_floatleft">'.
+                    '<fieldset style="display: inline">'.
+                    '<legend><span class="LC_nobreak">'.&mt('Main Content').':';
         unless ($disabled) {
-            $display .= '<fieldset style="display: inline">'.
-                        '<legend>'.$legend.'</legend>'."\n";
+            $display .= ' '.$togglebuttons;
         }
+        $display .= '</span></legend>';
     } elsif (($context eq 'examblock') || ($context eq 'passback')) {
         $display .= $info.$togglebuttons;
     } elsif ($context eq 'dumpdocs') {
@@ -535,7 +547,12 @@
                         $display .= 'checked="checked"';
                     }
                 }
-                $display .= $disabled.$labeltext.' />'."\n";
+                if (($context eq 'wcagcheck') &&
+                    (($curRes->is_tool) || ($curRes->src =~ m{^/adm/wrapper/ext/}))) {
+                    $display .= ' disabled="disabled"'.$labeltext.' />'."\n"; 
+                } else {
+                    $display .= $disabled.$labeltext.' />'."\n";
+                }
             }
             if ($context eq 'dumpdocs') {
                 $display .= '</td><td valign="top">';
@@ -717,25 +734,27 @@
             $display .=
                 '<p>'.
                 '<input type="submit" name="shorturls" value="'.
-                &mt('Create Tiny URL(s)').'" /></p></fieldset>';
+                &mt('Create Tiny URL(s)').'" /></p>';
         }
+        $display .= '</fieldset>';
     } elsif ($context eq 'wcagcheck') {
         my $suppcount = 0;
-        unless ($readonly) {
-            $display .= '</fieldset></div>';
-            my $supp;
-            my ($rescount,$supptitles,$ordered,$src_by_id) = &get_supp_hashes($cnum,$cdom);
-            my ($supplemental) = &Apache::loncommon::get_supplemental($cnum,$cdom,1);
-            if ($rescount) {
-                my $otherchk = 'wcagsupp';
-                $supp = '<div class="LC_floatleft">'.
+        $display .= '</fieldset></div>';
+        my ($rescount,$supptitles,$ordered,$src_by_id) = &get_supp_hashes($cnum,$cdom);
+        my ($supplemental) = &Apache::loncommon::get_supplemental($cnum,$cdom,1);
+        if ($rescount) {
+            my $otherchk = 'wcagsupp';
+            $display .= '<div class="LC_floatleft">'.
                         '<fieldset><legend><span class="LC_nobreak">'.
-                        &mt('Supplemental Content').': '.
+                        &mt('Supplemental Content').': ';
+            unless ($disabled) {
+                $display.=
                         '<input type="button" value="'.&mt('check all').'" '.
                         'onclick="javascript:checkAll(document.'.$formname.'.'.$otherchk.')" />'.
                         '  <input type="button" value="'.&mt('uncheck all').'"'.
-                        ' onclick="javascript:uncheckAll(document.'.$formname.'.'.$otherchk.')" />'.
-                        '</span></legend>'.
+                        ' onclick="javascript:uncheckAll(document.'.$formname.'.'.$otherchk.')" />';
+            }
+            $display .= '</span></legend>'.
                         &Apache::loncommon::start_data_table().
                         &Apache::loncommon::start_data_table_header_row().
                         '<th>'.&mt('Check for Accessibility?').'</th>'.
@@ -745,35 +764,33 @@
                         my $startsupp = $startcount + $count + 3;
                         $lastcontainer = $startsupp;
                         $supp_parent{$depth} = $lastcontainer;
-                        $supp .= &recurse_supp($formname,$startsupp,$depth,$mapnum,$supptitles,$ordered,
-                                               $src_by_id,\$suppcount,\%supp_parent,\%supp_children,
-                                               \%supp_hierarchy,\$lastcontainer).
-                        &Apache::loncommon::end_data_table();
-            }
-            if ($supp) {
-                $supp .= '</fieldset></div>';
-            }
-            $display .= $supp.
-                        '<div style="padding:0;clear:both;margin:0;border:0"></div>'.
-                        '<div>'."\n".
-                        '<h2 class="LC_heading_2">'.&mt('Accessibility level').'</h2>'."\n".
-                        '<fieldset class="LC_wcag"><legend>'.&mt('WCAG standard').'</legend>'.
-                        '<span class="LC_nobreak">'.
-                        '<label><input name="standard" type="radio" value="20" />2.0</label>'.
-                        (' 'x2).
-                        '<label><input name="standard" type="radio" value="21" />2.1</label>'.
-                        (' 'x2).
-                        '<label><input name="standard" type="radio" value="22" checked="checked" />2.2</label>'.
-                        '</span></fieldset>'.
-                        (' 'x2).
-                        '<fieldset class="LC_wcag"><legend>'.&mt('Compliance level').'</legend>'.
-                        '<span class="LC_nobreak"><label><input name="compliance" type="radio" value ="a" />A</label>'.
-                        (' 'x2).
-                        '<label><input name="compliance" type="radio" value="aa" checked="checked" />AA</label>'.
-                        (' 'x2).
-                        '<label><input name="compliance" type="radio" value="aaa" />AAA</label>'.
-                        '</span></fieldset></div>'.
-                        '<div>'.
+                        $display .= &recurse_supp($formname,$context,$readonly,$startsupp,$depth,$mapnum,
+                                                  $supptitles,$ordered,$src_by_id,\$suppcount,\%supp_parent,
+                                                  \%supp_children,\%supp_hierarchy,\$lastcontainer).
+                        &Apache::loncommon::end_data_table().
+                        '</fieldset></div>';
+        }
+        $display .= '<div style="padding:0;clear:both;margin:0;border:0"></div>'.
+                    '<div>'."\n".
+                    '<h2 class="LC_heading_2">'.&mt('Accessibility level').'</h2>'."\n".
+                    '<fieldset class="LC_wcag"><legend>'.&mt('WCAG standard').'</legend>'.
+                    '<span class="LC_nobreak">'.
+                    '<label><input name="standard" type="radio" value="20"'.$disabled.' />2.0</label>'.
+                    (' 'x2).
+                    '<label><input name="standard" type="radio" value="21"'.$disabled.' />2.1</label>'.
+                    (' 'x2).
+                    '<label><input name="standard" type="radio" value="22" checked="checked"'.$disabled.' />2.2</label>'.
+                    '</span></fieldset>'.
+                    (' 'x2).
+                    '<fieldset class="LC_wcag"><legend>'.&mt('Compliance level').'</legend>'.
+                    '<span class="LC_nobreak"><label><input name="compliance" type="radio" value ="a"'.$disabled.' />A</label>'.
+                    (' 'x2).
+                    '<label><input name="compliance" type="radio" value="aa" checked="checked"'.$disabled.' />AA</label>'.
+                    (' 'x2).
+                    '<label><input name="compliance" type="radio" value="aaa"'.$disabled.' />AAA</label>'.
+                    '</span></fieldset></div>';
+        unless ($disabled) {
+            $display .= '<div>'.
                         '<input type="submit" name="wcagcheck" value="'.&mt('Check Accessibility').'" />'.
                         '</div>';
         }
@@ -826,9 +843,13 @@
 }
 
 sub recurse_supp {
-    my ($formname,$startcount,$depth,$mapnum,$supptitles,$ordered,$src_by_id,
-        $countref,$parent,$children,$hierarchy,$lastcontainer) = @_;
+    my ($formname,$context,$readonly,$startcount,$depth,$mapnum,$supptitles,
+        $ordered,$src_by_id,$countref,$parent,$children,$hierarchy,$lastcontainer) = @_;
     my $output = '';
+    my $disabled = '';
+    if ($readonly) {
+        $disabled = ' disabled="disabled"';
+    }
     my $chkname = 'wcagsupp';
     my $location = &Apache::loncommon::lonhttpdurl("/adm/lonIcons");
     if ((ref($supptitles) eq 'HASH') && (ref($ordered) eq 'HASH') &&
@@ -873,15 +894,21 @@
                 } else {
                     $output .= 'onclick="javascript:checkResource(document.'.$formname.','."'$currelem'".')" ';
                 }
-                $output .= $labeltext.' />'."\n";
+                if (($context eq 'wcagcheck') &&
+                    (($src_by_id->{$mapnum.':'.$idx} =~ /ext\.tool$/) ||
+                     ($src_by_id->{$mapnum.':'.$idx} =~ m{^\Qhttp://\E}))) {
+                    $output .= ' disabled="disabled"'.$labeltext.' />'."\n";
+                } else {
+                    $output .= $disabled.$labeltext.' />'."\n";
+                }
                 $output .= $showitem.'<img '.$icon.' /> '."\n".
                            ' '.$supptitles->{"$mapnum:$idx"}.$whitespace.'</td>';
                 $output .= &Apache::loncommon::end_data_table_row()."\n";
                 if ($is_map) {
                     $parent->{$deeper} = $$lastcontainer;
-                    $output .= &recurse_supp($formname,$startcount,$deeper,$newmap,$supptitles,
-                                             $ordered,$src_by_id,$countref,$parent,$children,
-                                             $hierarchy,$lastcontainer);
+                    $output .= &recurse_supp($formname,$context,$readonly,$startcount,$deeper,
+                                             $newmap,$supptitles,$ordered,$src_by_id,$countref,
+                                             $parent,$children,$hierarchy,$lastcontainer);
                 }
             }
             $$lastcontainer = $parent->{$shallower};
@@ -897,10 +924,14 @@
 function checkAll(field) {
     if (field.length > 0) {
         for (i = 0; i < field.length; i++) {
-            field[i].checked = true ;
+            if (!field[i].disabled) {
+                field[i].checked = true;
+            }
         }
     } else {
-        field.checked = true
+        if (!field.disabled) {
+            field.checked = true;
+        }
     }
 }
 
@@ -1078,7 +1109,9 @@
 
 function containerCheck(form,item) {
     var elem = $elem;
-    form.elements[elem].checked = true;
+    if (!form.elements[elem].disabled) {
+        form.elements[elem].checked = true;
+    }
     if(Object.prototype.toString.call(parents[item]) === '[object Array]') {
         if (parents[item].length > 0) {
             for (var j=0; j<parents[item].length; j++) {


More information about the LON-CAPA-cvs mailing list