--- loncom/interface/loncommon.pm 2021/09/25 20:35:26 1.1367 +++ loncom/interface/loncommon.pm 2023/11/17 17:02:20 1.1418 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common routines # -# $Id: loncommon.pm,v 1.1367 2021/09/25 20:35:26 raeburn Exp $ +# $Id: loncommon.pm,v 1.1418 2023/11/17 17:02:20 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -61,7 +61,7 @@ use POSIX qw(strftime mktime); use Apache::lonmenu(); use Apache::lonenc(); use Apache::lonlocal; -use Apache::lonnet(); +use Apache::lonnavmaps(); use HTML::Entities; use Apache::lonhtmlcommon(); use Apache::loncoursedata(); @@ -71,7 +71,9 @@ use Apache::lonuserutils(); use Apache::lonuserstate(); use Apache::courseclassifier(); use LONCAPA qw(:DEFAULT :match); +use LONCAPA::ltiutils; use LONCAPA::LWPReq; +use LONCAPA::map(); use HTTP::Request; use DateTime::TimeZone; use DateTime::Locale; @@ -435,7 +437,7 @@ sub studentbrowser_javascript { +ENDJS + } $endbodytag= - "
". + "$endbodyjs
". &mt('Continue').''. $endbodytag; } } + if ((ref($args) eq 'HASH') && ($args->{'dashjs'})) { + $endbodytag = &Apache::lonhtmlcommon::dash_to_minus_js().$endbodytag; + } return $endbodytag; } @@ -7715,6 +8241,11 @@ fieldset { /* overflow: hidden; */ } +fieldset#LC_selectuser { + margin: 0; + padding: 0; +} + article.geogebraweb div { margin: 0; } @@ -8258,6 +8789,10 @@ a#LC_content_toolbar_edittoplevel { background-image:url(/res/adm/pages/edittoplevel.gif); } +a#LC_content_toolbar_printout { + background-image:url(/res/adm/pages/printout.gif); +} + ul#LC_toolbar li a:hover { background-position: bottom center; } @@ -8375,6 +8910,18 @@ ul.LC_funclist li { cursor:pointer; } +.LCisDisabled { + cursor: not-allowed; + opacity: 0.5; +} + +a[aria-disabled="true"] { + color: currentColor; + display: inline-block; /* For IE11/ MS Edge bug */ + pointer-events: none; + text-decoration: none; +} + pre.LC_wordwrap { white-space: pre-wrap; white-space: -moz-pre-wrap; @@ -8548,7 +9095,13 @@ Inputs: $title - optional title for the 3- whether the side effect should occur (side effect of setting $env{'internal.head.redirect'} to the url - redirected too) + redirected to) + 4- whether the redirect target should be + the opener of the current (pop-up) + window (side effect of setting + $env{'internal.head.to_opener'} to + 1, if true. + 5- whether encrypt check should be skipped domain -> force to color decorate a page for a specific domain function -> force usage of a specific rolish color scheme @@ -8611,15 +9164,45 @@ sub headtag { } } if (ref($args->{'redirect'})) { - my ($time,$url,$inhibit_continue) = @{$args->{'redirect'}}; - $url = &Apache::lonenc::check_encrypt($url); + my ($time,$url,$inhibit_continue,$to_opener,$skip_enc_check) = @{$args->{'redirect'}}; + if (!$skip_enc_check) { + $url = &Apache::lonenc::check_encrypt($url); + } if (!$inhibit_continue) { $env{'internal.head.redirect'} = $url; } - $result.=< +ADDMETA + if ($to_opener) { + $env{'internal.head.to_opener'} = 1; + my $dest = &js_escape($url); + my $timeout = int($time * 1000); + $result .=<<"ENDJS"; + +ENDJS + } else { + $result.=<<"ADDMETA"; ADDMETA + } } else { unless (($args->{'frameset'}) || ($args->{'js_ready'}) || ($args->{'only_body'}) || ($args->{'no_nav_bar'})) { my $requrl = $env{'request.uri'}; @@ -8844,7 +9427,8 @@ sub print_suppression { } my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - my $blocked = &blocking_status('printout',$cnum,$cdom,undef,1); + my $clientip = &Apache::lonnet::get_requestor_ip(); + my $blocked = &blocking_status('printout',$clientip,$cnum,$cdom,undef,1); if ($blocked) { my $checkrole = "cm./$cdom/$cnum"; if ($env{'request.course.sec'} ne '') { @@ -8963,6 +9547,10 @@ $args - additional optional args support will contain https:// if server uses https (as per hosts.tab), but request is for http hostname -> hostname, originally from $r->hostname(), (optional). + links_disabled -> Links in primary and secondary menus are disabled + (Can enable them once page has loaded - see lonroles.pm + for an example). + links_target -> Target for links, e.g., _parent (optional). =back @@ -9051,6 +9639,7 @@ sub start_page { } } + my $showncrumbs; if (! exists($args->{'skip_phases'}{'body'}) ) { if ($args->{'frameset'}) { my $attr_string = &make_attr_string($args->{'force_register'}, @@ -9063,7 +9652,8 @@ sub start_page { $args->{'only_body'}, $args->{'domain'}, $args->{'force_register'}, $args->{'no_nav_bar'}, $args->{'bgcolor'}, $args, - \@advtools,$ltiscope,$ltiuri,\%ltimenu,$menucoll,\%menu); + \@advtools,$ltiscope,$ltiuri,\%ltimenu,$menucoll, + \%menu,\$showncrumbs); } } @@ -9085,6 +9675,7 @@ sub start_page { #Breadcrumbs if (exists($args->{'bread_crumbs'}) or exists($args->{'bread_crumbs_component'})) { + unless ($showncrumbs) { &Apache::lonhtmlcommon::clear_breadcrumbs(); #if any br links exists, add them to the breadcrumbs if (exists($args->{'bread_crumbs'}) and ref($args->{'bread_crumbs'}) eq 'ARRAY') { @@ -9107,12 +9698,20 @@ sub start_page { } else { undef($menulink); } + my $linkprotout; + if ($env{'request.deeplink.login'}) { + my $linkprotout = &Apache::lonmenu::linkprot_exit(); + if ($linkprotout) { + &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$linkprotout); + } + } #if bread_crumbs_component exists show it as headline else show only the breadcrumbs if(exists($args->{'bread_crumbs_component'})){ $result .= &Apache::lonhtmlcommon::breadcrumbs($args->{'bread_crumbs_component'},'',$menulink); } else { $result .= &Apache::lonhtmlcommon::breadcrumbs('','',$menulink); } + } } return $result; } @@ -9154,7 +9753,7 @@ sub menucoll_in_effect { if ($env{'request.course.id'}) { $menucoll = $env{'course.'.$env{'request.course.id'}.'.menudefault'}; if ($env{'request.deeplink.login'}) { - my ($deeplink_symb,$deeplink); + my ($deeplink_symb,$deeplink,$check_login_symb); my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; if ($env{'request.noversionuri'} =~ m{^/(res|uploaded)/}) { @@ -9164,11 +9763,21 @@ sub menucoll_in_effect { $deeplink = $navmap->get_mapparam(undef, &Apache::lonnet::declutter($env{'request.noversionuri'}), '0.deeplink'); + } else { + $check_login_symb = 1; } } else { - $deeplink = &Apache::lonnet::EXT('resource.0.deeplink'); + my $symb = &Apache::lonnet::symbread(); + if ($symb) { + $deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$symb); + } else { + $check_login_symb = 1; + } } } else { + $check_login_symb = 1; + } + if ($check_login_symb) { $deeplink_symb = &deeplink_login_symb($cnum,$cdom); if ($deeplink_symb =~ /\.(page|sequence)$/) { my $mapname = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($deeplink_symb))[2]); @@ -9181,7 +9790,7 @@ sub menucoll_in_effect { } } if ($deeplink ne '') { - my ($state,$others,$listed,$scope,$protect,$display) = split(/,/,$deeplink); + my ($state,$others,$listed,$scope,$protect,$display,$target) = split(/,/,$deeplink); if ($display =~ /^\d+$/) { $deeplinkmenu = 1; $menucoll = $display; @@ -9236,6 +9845,50 @@ sub symb_from_tinyurl { } } +sub usable_exttools { + my %tooltypes; + if ($env{'request.course.id'}) { + if ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'}) { + if ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'} eq 'both') { + %tooltypes = ( + crs => 1, + dom => 1, + ); + } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'} eq 'crs') { + $tooltypes{'crs'} = 1; + } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.exttool'} eq 'dom') { + $tooltypes{'dom'} = 1; + } + } else { + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $crstype = lc($env{'course.'.$env{'request.course.id'}.'.type'}); + if ($crstype eq '') { + $crstype = 'course'; + } + if ($crstype eq 'course') { + if ($env{'course.'.$env{'request.course.id'}.'internal.coursecode'}) { + $crstype = 'official'; + } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.textbook'}) { + $crstype = 'textbook'; + } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.lti'}) { + $crstype = 'lti'; + } else { + $crstype = 'unofficial'; + } + } + my %domdefaults = &Apache::lonnet::get_domain_defaults($cdom); + if ($domdefaults{$crstype.'domexttool'}) { + $tooltypes{'dom'} = 1; + } + if ($domdefaults{$crstype.'exttool'}) { + $tooltypes{'crs'} = 1; + } + } + } + return %tooltypes; +} + sub wishlist_window { return(<<'ENDWISHLIST');