[LON-CAPA-cvs] cvs: loncom /interface loncommon.pm londocs.pm
raeburn
raeburn at source.lon-capa.org
Tue Jun 9 01:57:42 EDT 2026
raeburn Tue Jun 9 05:57:42 2026 EDT
Modified files:
/loncom/interface londocs.pm loncommon.pm
Log:
- WCAG 2 compliance - accessibility for keyboard-only interaction.
- Course Editor links to add new content can be reached using Tab key.
- Order of Course Editor menu items (New Folder, Upload, External, Import
Assessment, Collaboration, and Other) when reached by tabbing matches
visual order.
- Sub-menu items in Upload, External etc. reachable using Tab key.
- Course Editor menu item with current focus is outlined when reached
using Tab key.
Index: loncom/interface/londocs.pm
diff -u loncom/interface/londocs.pm:1.741 loncom/interface/londocs.pm:1.742
--- loncom/interface/londocs.pm:1.741 Tue Jun 9 03:59:32 2026
+++ loncom/interface/londocs.pm Tue Jun 9 05:57:42 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Documents
#
-# $Id: londocs.pm,v 1.741 2026/06/09 03:59:32 raeburn Exp $
+# $Id: londocs.pm,v 1.742 2026/06/09 05:57:42 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -8856,8 +8856,9 @@
}
my $backicon = $iconpath.'clickhere.gif';
my $backtext = &mt('Exit Editor');
- $form = '<div class="LC_Box" style="margin:0;">'.
- '<ul id="navigation'.$tid.'" class="LC_TabContent">'."\n".
+ $form = '<div class="LC_DocsOuter">'.
+ '<div class="LC_DocsInner">'.
+ '<ul class="LC_TabContent LC_floatleft">'."\n".
'<li class="goback">'.
'<a href="javascript:toContents('."'$jumpto'".');">'.
'<img src="'.$backicon.'" class="LC_icon" style="border: none; vertical-align: top;"'.
@@ -8876,22 +8877,34 @@
$form .= '<li><a href="javascript:toggleHistoryDisp(0);">'.
&mt('Edit').'</a></li>'."\n";
}
- foreach my $name (reverse(sort(keys(%orderhash)))) {
- if($name ne '00'){
- if($activetab eq '' || $activetab ne $name){
- $active = '';
- }elsif($activetab eq $name){
- $active = 'class="active"';
- }
- $form .= '<li style="float:right" '.$active
- .' onclick="javascript:showPage(this, \''.$name.$tid.'\', \'navigation'.$tid.'\',\'content'.$tid.'\');"><a href="javascript:;"><b>'.&mt(${$orderhash{$name}}[0]).'</b></a></li>'."\n";
- } else {
- $form .= '<li style="float:right">'.${$orderhash{$name}}[1].'</li>'."\n";
-
- }
+ $form .= '</ul>';
+ if (keys(%orderhash)) {
+ my @ordered = sort(keys(%orderhash));
+ if ($ordered[-1] eq '00') {
+ unshift(@ordered, pop(@ordered));
+ }
+ $form .= '<ul id="navigation'.$tid.'" class="LC_TabContent LC_floatright">';
+ foreach my $name (@ordered) {
+ if ($name ne '00') {
+ if ($activetab eq '' || $activetab ne $name) {
+ $active = '';
+ } elsif($activetab eq $name){
+ $active = 'class="active"';
+ }
+ $form .= '<li style="float:left" '.$active
+ .' onclick="javascript:showPage(this, \''.$name.$tid.'\', \'navigation'.$tid.'\',\'content'.$tid.'\');"><a href="javascript:;"><b>'.&mt(${$orderhash{$name}}[0]).'</b></a></li>'."\n";
+ } else {
+ $form .= '<li style="float:left">'.${$orderhash{$name}}[1].'</li>'."\n";
+ }
+ }
+ $form .= '</ul>'."\n";
+ } else {
+ $form .= '<ul class="LC_TabContent LC_floatright">'."\n".
+ '<li class="LC_empty"> </li>'."\n".
+ '</ul>'."\n";
}
- $form .= '</ul>'."\n";
- $form .= '<div id="content'.$tid.'" style="padding: 0 0; margin: 0 0; overflow: hidden; clear:right">'."\n";
+ $form .= '</div>';
+ $form .= '<div id="content'.$tid.'" style="padding: 0 10px; margin: 0 0; overflow: hidden; clear:both">'."\n";
if ($to_show ne '') {
my $saveform;
@@ -10096,25 +10109,62 @@
hideAll(current, nav, data);
openTabs(pageId);
unselectInactive(nav);
+ currentData = document.getElementById(pageId);
if ((currstate == 'active') || (currstate == 'right active')) {
if (currstate == 'active') {
current.className = '';
} else {
current.className = 'right';
}
- activeTab = '';
+ activeTab = '';
toggleExternal();
toggleUpload();
toggleMap();
toggleCrsRes();
toggleImportCrsres();
+ currentData.removeAttribute('tabindex');
resize_scrollbox('contentscroll','1','0');
return;
} else {
current.className = 'active';
}
- currentData = document.getElementById(pageId);
currentData.style.display = 'block';
+ currentData.style.outline = 'none';
+ currentData.setAttribute('tabindex',0);
+ currentData.focus();
+ const rightTabFocusTrap = (e) => {
+ if (e.key === 'Escape') {
+ e.preventDefault();
+ current.querySelector(':scope > a').focus();
+ showPage(current, pageId, nav, data);
+ return;
+ }
+ if (e.key !== 'Tab') return;
+ const focusableElements = \$(currentData).find(':focusable');
+ const focusableNum = focusableElements.length;
+ if (focusableNum === 0) {
+ e.preventDefault();
+ current.querySelector(':scope > a').focus();
+ showPage(current, pageId, nav, data);
+ return;
+ }
+ if (e.shiftKey) {
+ if ((document.activeElement === currentData) ||
+ (document.activeElement === focusableElements[0])) {
+ e.preventDefault();
+ current.querySelector(':scope > a').focus();
+ showPage(current, pageId, nav, data);
+ }
+ } else {
+ if (document.activeElement === focusableElements[focusableNum-1]) {
+ e.preventDefault();
+ current.querySelector(':scope > a').focus();
+ showPage(current, pageId, nav, data);
+ }
+ }
+ return;
+ };
+ currentData.addEventListener('keydown', rightTabFocusTrap);
activeTab = pageId;
toggleExternal();
toggleUpload();
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1527 loncom/interface/loncommon.pm:1.1528
--- loncom/interface/loncommon.pm:1.1527 Tue Jun 9 03:03:00 2026
+++ loncom/interface/loncommon.pm Tue Jun 9 05:57:42 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.1527 2026/06/09 03:03:00 raeburn Exp $
+# $Id: loncommon.pm,v 1.1528 2026/06/09 05:57:42 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -9343,11 +9343,11 @@
}
ul.LC_TabContent {
- display:block;
+ display: inline-block;
background: $sidebg;
border-bottom: solid 1px $lg_border_color;
list-style:none;
- margin: -1px -10px 0 -10px;
+ margin: 0;
padding: 0;
}
@@ -9390,7 +9390,6 @@
ul.LC_TabContent li a:focus {
color: $button_hover;
background:none;
- outline:none;
}
ul.LC_TabContent li:hover {
@@ -9408,7 +9407,7 @@
ul.LC_TabContent li.active a {
color:$font;
background:#FFFFFF;
- outline: none;
+ outline: reset;
}
ul.LC_TabContent li.goback {
@@ -9416,6 +9415,12 @@
border-left: none;
}
+ul.LC_TabContent li.LC_empty {
+ margin-bottom: 1px;
+ border: 0;
+ background-color: $sidebg;
+}
+
#maincoursedoc {
clear:both;
}
@@ -9446,7 +9451,7 @@
text-align: center;
display: block;
text-decoration: none;
- outline: none;
+ outline: none;
}
ul.LC_TabContentBigger li.active a {
@@ -9525,6 +9530,19 @@
padding: 0 0 10px 10px;
}
+.LC_DocsOuter {
+ border: solid 1px $lg_border_color;
+ padding: 0 0 10px 0;
+ margin: 0;
+}
+
+.LC_DocsInner {
+ background-color: $sidebg;
+ display: inline-block;
+ margin: -1px 0 0 0;
+ width: 100%;
+}
+
.LC_MainMenu_Box {
border: solid 1px $lg_border_color;
padding: 0 10px 0 10px;
@@ -10941,7 +10959,7 @@
modal += "<div class=\"LCmodal-overlay\"></div>";
modal += "<div id=\"" + this.windowId + "\" class=\"LCmodal-window\" style=\"width:" + this.width + "px; height:" + this.height + "px; margin-top:-" + (this.height / 2) + "px; margin-left:-" + (this.width / 2) + "px;\">";
modal += this.content;
- modal += "</div>";
+ modal += "</div>";
$(this.parent).append(modal);
More information about the LON-CAPA-cvs
mailing list