--- loncom/interface/lonmenu.pm 2021/09/21 22:54:26 1.510
+++ loncom/interface/lonmenu.pm 2022/07/01 03:14:31 1.525
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Routines to control the menu
#
-# $Id: lonmenu.pm,v 1.510 2021/09/21 22:54:26 raeburn Exp $
+# $Id: lonmenu.pm,v 1.525 2022/07/01 03:14:31 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -99,7 +99,7 @@ It gets filled in the BEGIN block of thi
=over
-=item prep_menuitems(\@menuitem,$ltitarget)
+=item prep_menuitems(\@menuitem,$target,$listclass,$linkattr)
This routine wraps a menuitem in proper HTML. It is used by primary_menu() and
secondary_menu().
@@ -220,9 +220,9 @@ use vars qw(@desklines %category_names %
my @inlineremote;
sub prep_menuitem {
- my ($menuitem,$ltitarget) = @_;
+ my ($menuitem,$target,$listclass,$linkattr) = @_;
return '' unless(ref($menuitem) eq 'ARRAY');
- my $link;
+ my ($link,$targetattr);
if ($$menuitem[1]) { # graphical Link
$link = "':'').'$link |;
+ . qq| href="$$menuitem[0]"$targetattr $linkattr>$link |;
}
# primary_menu() evaluates @primary_menu and returns a two item array,
@@ -247,7 +246,7 @@ sub prep_menuitem {
# @primary_menu is filled within the BEGIN block of this module with
# entries from mydesk.tab
sub primary_menu {
- my ($crstype,$ltimenu,$menucoll,$menuref) = @_;
+ my ($crstype,$ltimenu,$menucoll,$menuref,$links_disabled,$links_target) = @_;
my (%menu,%ltiexc,%menuopts);
# each element of @primary contains following array:
# (link url, icon path, alt text, link text, condition, position)
@@ -265,10 +264,9 @@ sub primary_menu {
my %roles_in_env;
$rolecount = &Apache::lonroles::roles_from_env(\%roles_in_env,$update);
}
- my ($lti,$ltitarget);
+ my $lti;
if ($env{'request.lti.login'}) {
$lti = 1;
- $ltitarget = $env{'request.lti.target'};
if (ref($ltimenu) eq 'HASH') {
foreach my $item ('fullname','logout') {
unless ($ltimenu->{$item}) {
@@ -277,6 +275,27 @@ sub primary_menu {
}
}
}
+ my ($listclass,$linkattr,$target);
+ if ($links_disabled) {
+ $listclass = 'LCisDisabled';
+ $linkattr = 'aria-disabled="true"';
+ }
+ if ($links_target ne '') {
+ $target = $links_target;
+ } else {
+ my ($ltitarget,$deeplinktarget);
+ if ($env{'request.lti.login'}) {
+ $ltitarget = $env{'request.lti.target'};
+ }
+ if ($env{'request.deeplink.login'}) {
+ $deeplinktarget = $env{'request.deeplink.target'};
+ }
+ if (($ltitarget eq 'iframe') || ($deeplinktarget eq '_self')) {
+ $target = '_self';
+ } else {
+ $target = '_top';
+ }
+ }
if (($menucoll) && (ref($menuref) eq 'HASH')) {
%menuopts = %{$menuref};
}
@@ -333,12 +352,9 @@ sub primary_menu {
}
}
if (defined($primary_submenu{$title})) {
- my ($link,$target);
+ my $link;
if ($menuitem->[0] ne '') {
$link = $menuitem->[0];
- unless ($ltitarget eq 'iframe') {
- $target = '_top';
- }
} else {
$link = '#';
}
@@ -364,13 +380,17 @@ sub primary_menu {
}
next if (($env{'request.course.id'}) && ($menucoll) && ($title eq 'Personal') &&
(!@primsub));
+ if ($title eq 'Personal') {
+ $title = &mt($title);
+ }
} else {
$title = &mt($title);
}
if (@primsub > 0) {
- $menu{$position} .= &create_submenu($link,$target,$title,\@primsub,1);
+ $menu{$position} .= &create_submenu($link,$target,$title,\@primsub,1,undef,$listclass,$linkattr);
} elsif ($link) {
- $menu{$position} .= '
'.$title.' ';
+ $menu{$position} .= ($listclass?'':' ').
+ ''.$title.' ';
}
}
} elsif ($$menuitem[3] eq 'Help') { # special treatment for helplink
@@ -382,10 +402,12 @@ sub primary_menu {
'helpdeskmail',
$defdom,$origmail);
if ($to ne '') {
- $menu{$position} .= &prep_menuitem($menuitem,$ltitarget);
+ $menu{$position} .= &prep_menuitem($menuitem,$target,$listclass,$linkattr);
}
} else {
- $menu{$position} .= ''.&Apache::loncommon::top_nav_help('Help').' ';
+ $menu{$position} .= ($listclass?'':' ').
+ &Apache::loncommon::top_nav_help('Help',$linkattr).
+ ' ';
}
} elsif ($$menuitem[3] eq 'Log In') {
if ($public) {
@@ -393,9 +415,9 @@ sub primary_menu {
$$menuitem[0] = '/adm/login';
}
}
- $menu{$position} .= prep_menuitem($menuitem,$ltitarget);
+ $menu{$position} .= prep_menuitem($menuitem,$target,$listclass,$linkattr);
} else {
- $menu{$position} .= prep_menuitem($menuitem,$ltitarget);
+ $menu{$position} .= prep_menuitem($menuitem,$target,$listclass,$linkattr);
}
}
my @output = ('','');
@@ -434,7 +456,8 @@ sub getauthor{
}
sub secondary_menu {
- my ($httphost,$ltiscope,$ltimenu,$noprimary,$menucoll,$menuref) = @_;
+ my ($httphost,$ltiscope,$ltimenu,$noprimary,$menucoll,$menuref,
+ $links_disabled,$links_target) = @_;
my $menu;
my $crstype = &Apache::loncommon::course_type();
@@ -511,6 +534,12 @@ sub secondary_menu {
%menuopts = %{$menuref};
}
+ my ($listclass,$linkattr,$target);
+ if ($links_disabled) {
+ $listclass = 'LCisDisabled';
+ $linkattr = 'aria-disabled="true"';
+ }
+
my ($canmodifycoauthor);
if ($env{'request.role'} eq "au./$env{'user.domain'}/") {
my $extent = "$env{'user.domain'}/$env{'user.name'}";
@@ -520,9 +549,22 @@ sub secondary_menu {
}
}
- my ($roleswitcher_js,$roleswitcher_form,$ltitarget);
- if ($env{'request.lti.login'}) {
- $ltitarget = $env{'request.lti.target'};
+ my ($roleswitcher_js,$roleswitcher_form);
+ if ($links_target ne '') {
+ $target = $links_target;
+ } else {
+ my ($ltitarget,$deeplinktarget);
+ if ($env{'request.lti.login'}) {
+ $ltitarget = $env{'request.lti.target'};
+ }
+ if ($env{'request.deeplink.login'}) {
+ $deeplinktarget = $env{'request.deeplink.target'};
+ }
+ if (($ltitarget eq 'iframe') || ($deeplinktarget eq '_self')) {
+ $target = '_self';
+ } else {
+ $target = '_top';
+ }
}
foreach my $menuitem (@secondary_menu) {
@@ -578,12 +620,9 @@ sub secondary_menu {
}
}
if (defined($secondary_submenu{$title})) {
- my ($link,$target);
+ my $link;
if ($menuitem->[0] ne '') {
$link = $menuitem->[0];
- unless ($ltitarget eq 'iframe') {
- $target = '_top';
- }
} else {
$link = '#';
}
@@ -617,9 +656,12 @@ sub secondary_menu {
}
}
if (@scndsub > 0) {
- $menu .= &create_submenu($link,$target,&mt($title),\@scndsub,1);
+ $menu .= &create_submenu($link,$target,&mt($title),\@scndsub,1,undef,
+ $listclass,$linkattr);
} elsif ($link ne '#') {
- $menu .= ''.&mt($title).' ';
+ $menu .= ($listclass?'':' ').
+ ''.
+ &mt($title).' ';
}
}
} elsif ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
@@ -629,7 +671,7 @@ sub secondary_menu {
&roles_selector(
$env{'course.' . $env{'request.course.id'} . '.domain'},
$env{'course.' . $env{'request.course.id'} . '.num'},
- $httphost,$ltitarget
+ $httphost,$target,$menucoll,$menuref
);
if (($$menuitem[5]) && (!$menuopts{$$menuitem[5]})) {
next unless ($has_opa_priv);
@@ -663,7 +705,7 @@ sub secondary_menu {
}
$$menuitem[0] = &HTML::Entities::encode($$menuitem[0],'&<>"');
}
- $menu .= &prep_menuitem(\@$menuitem,$ltitarget);
+ $menu .= &prep_menuitem(\@$menuitem,$target,$listclass,$linkattr);
}
}
if ($menu =~ /\[url\].*\[symb\]/) {
@@ -701,14 +743,14 @@ sub secondary_menu {
}
sub create_submenu {
- my ($link,$target,$title,$submenu,$translate,$addclass) = @_;
+ my ($link,$target,$title,$submenu,$translate,$addclass,$listclass,$linkattr) = @_;
return unless (ref($submenu) eq 'ARRAY');
- my $disptarget;
- if ($target ne '') {
- $disptarget = ' target="'.$target.'"';
+ my $targetattr;
+ if (($target ne '') && ($link ne '#')) {
+ $targetattr = ' target="'.$target.'"';
}
my $menu = ''.
- ''.
+ ' '.
''.$title.
''.
' ▼ '.
@@ -716,7 +758,7 @@ sub create_submenu {
# $link and $title are only used in the initial string written in $menu
# as seen above, not needed for nested submenus
- $menu .= &build_submenu($target, $submenu, $translate, '1');
+ $menu .= &build_submenu($target, $submenu, $translate, '1', $listclass, $linkattr);
$menu .= ' ';
return $menu;
@@ -726,7 +768,7 @@ sub create_submenu {
# build the dropdown (and nested submenus) recursively
# see perldoc create_submenu documentation for further information
sub build_submenu {
- my ($target, $submenu, $translate, $first_level) = @_;
+ my ($target, $submenu, $translate, $first_level, $listclass, $linkattr) = @_;
unless (@{$submenu}) {
return '';
}
@@ -785,14 +827,17 @@ sub build_submenu {
}
$href =~ s/\[returnurl\]/$returnurl/;
}
+ my $targetattr;
unless (($href eq '') || ($href =~ /^\#/)) {
- if ($target eq '_top') {
- $target = ' target="_top"';
+ if ($target ne '') {
+ $targetattr = ' target="'.$target.'"';
}
}
- $menu .= '';
- $menu .= '' . $title . ' ';
+ $menu .= ' ';
+ $menu .= '' . $title . ' ';
$menu .= ' ';
}
}
@@ -801,7 +846,8 @@ sub build_submenu {
}
sub innerregister {
- my ($forcereg,$bread_crumbs,$group,$pagebuttonshide,$hostname,$ltiscope,$ltiuri) = @_;
+ my ($forcereg,$bread_crumbs,$group,$pagebuttonshide,$hostname,
+ $ltiscope,$ltiuri,$showncrumbsref) = @_;
my $const_space = ($env{'request.state'} eq 'construct');
my $is_const_dir = 0;
@@ -842,10 +888,7 @@ sub innerregister {
}
}
}
- unless (($forcereg) &&
- ($env{'request.noversionuri'} eq '/adm/navmaps') &&
- ($mapurl eq $env{'course.'.$env{'request.course.id'}.'.url'}) ||
- (($crstype eq 'Placement') && (!$env{'request.role.adv'})) ||
+ unless ((($crstype eq 'Placement') && (!$env{'request.role.adv'})) ||
($ltiscope eq 'map') || ($ltiscope eq 'resource')) {
@crumbs = ({text => $crstype.' Contents',
href => "Javascript:gopost('/adm/navmaps','')"});
@@ -896,14 +939,17 @@ sub innerregister {
if ($env{'form.folderpath'}) {
&prepare_functions($resurl,$forcereg,$group,undef,undef,1,$hostname);
($trail) =
- &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
+ &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1,1);
} else {
&Apache::lonhtmlcommon::add_breadcrumb(
{text => "Supplemental $crstype Content",
href => "javascript:gopost('/adm/supplemental','')"});
$title = &mt('View Resource');
($trail) =
- &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
+ &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1,1);
+ }
+ if (ref($showncrumbsref)) {
+ $$showncrumbsref = 1;
}
return $trail;
} elsif ($resurl =~ m{^\Q/uploaded$courseurl/portfolio/syllabus/}) {
@@ -912,7 +958,10 @@ sub innerregister {
$forcereg,$group,undef,undef,1,$hostname);
$title = &mt('Syllabus File');
my ($trail) =
- &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1,$hostname);
+ &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1,1);
+ if (ref($showncrumbsref)) {
+ $$showncrumbsref = 1;
+ }
return $trail;
}
unless ($env{'request.state'} eq 'construct') {
@@ -1034,6 +1083,13 @@ sub innerregister {
$currdir =~ s|[^/]+$||;
my $cleandisfn = &Apache::loncommon::escape_single($thisdisfn);
my $esc_currdir = &Apache::loncommon::escape_single($currdir);
+ my $pubfile = "/res/$udom/$uname/$thisdisfn";
+ my $candelete = 1;
+ if (-e $londocroot.$pubfile) {
+ unless (&Apache::lonnet::metadata($pubfile,'obsolete')) {
+ undef($candelete);
+ }
+ }
#
# Probably should be in mydesk.tab
#
@@ -1041,7 +1097,18 @@ sub innerregister {
s&6&1&list.png&Directory&dir[_1]&golist('$esc_currdir')&List current directory
s&6&2&rtrv.png&Retrieve&version[_1]&gocstr('/adm/retrieve','/priv/$udom/$uname/$cleandisfn')&Retrieve old version
s&6&3&pub.png&Publish&resource[_3]&gocstr('/adm/publish','/priv/$udom/$uname/$cleandisfn')&Publish this resource
+s&7&3©.png&Copy&resource[_4]&gocstr('/adm/cfile?action=copy','/priv/$udom/$uname/$cleandisfn')&Copy this resource
+ENDMENUITEMS
+#
+# Rename and Delete only available if obsolete or unpublished
+#
+ if ($candelete) {
+ $menuitems .= (<
@@ -2403,10 +2524,17 @@ ENDSERVERFORM
}
sub constspaceform {
+ my ($frameset) = @_;
my ($target,$printtarget);
- unless (($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) {
- $target = ' target="_top"';
+ if ($frameset) {
+ $target = ' target="_parent"';
$printtarget = ' target="_parent"';
+ } else {
+ unless ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) ||
+ (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) {
+ $target = ' target="_top"';
+ $printtarget = ' target="_top"';
+ }
}
return(<
@@ -2421,6 +2549,11 @@ sub constspaceform {
+
ENDCONSTSPACEFORM
}
@@ -2436,7 +2569,7 @@ sub hidden_button_check {
}
sub roles_selector {
- my ($cdom,$cnum,$httphost,$ltitarget) = @_;
+ my ($cdom,$cnum,$httphost,$target,$menucoll,$menuref) = @_;
my $crstype = &Apache::loncommon::course_type();
my $now = time;
my (%courseroles,%seccount,%courseprivs,%roledesc);
@@ -2542,10 +2675,15 @@ sub roles_selector {
}
}
if ((keys(%seccount) > 1) || ($numdiffsec > 1)) {
+ my $targetattr;
+ if ($target ne '') {
+ $targetattr = ' target="'.$target.'"';
+ }
my @submenu;
- $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,\%roledesc,$privref);
+ $js = &jump_to_role($cdom,$cnum,\%seccount,\%courseroles,\%courseprivs,
+ \%roledesc,$privref,$menucoll,$menuref);
$form =
- '
+
+
+
$lt{'okdone'} $lt{'cancel'}
+
+
+
+
+END
+ }
+ }
+ }
+ }
+ }
+ return;
+}
+
# ================================================================ Main Program
BEGIN {