Diff for /loncom/interface/lonhtmlcommon.pm between versions 1.370 and 1.410

version 1.370, 2016/01/26 14:30:25 version 1.410, 2023/09/27 14:52:26
Line 78  sub java_not_enabled { Line 78  sub java_not_enabled {
 sub coursepreflink {  sub coursepreflink {
    my ($text,$category)=@_;     my ($text,$category)=@_;
    if (&Apache::lonnet::allowed('opa',$env{'request.course.id'})) {     if (&Apache::lonnet::allowed('opa',$env{'request.course.id'})) {
       return '<a target="_top" href="'.&HTML::Entities::encode("/adm/courseprefs?phase=display&actions=$category",'<>&"').'"><span class="LC_setting">'.$text.'</span></a>';         my $target =' target="_top"';
          if ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) ||
              (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) {
              $target ='';
          }
          return '<a'.$target.' href="'.&HTML::Entities::encode("/adm/courseprefs?phase=display&actions=$category",'<>&"').'"><span class="LC_setting">'.$text.'</span></a>';
    } else {     } else {
       return '';        return '';
    }     }
Line 92  sub raw_href_to_link { Line 97  sub raw_href_to_link {
   
 sub entity_encode {  sub entity_encode {
     my ($text)=@_;      my ($text)=@_;
     return &HTML::Entities::encode($text, '<>&"');      return &HTML::Entities::encode($text, '\'<>&"');
 }  }
   
 sub direct_parm_link {  sub direct_parm_link {
Line 101  sub direct_parm_link { Line 106  sub direct_parm_link {
     $filter=&entity_encode($filter);      $filter=&entity_encode($filter);
     $part=&entity_encode($part);      $part=&entity_encode($part);
     if (($symb) && (&Apache::lonnet::allowed('opa')) && ($target ne 'tex')) {      if (($symb) && (&Apache::lonnet::allowed('opa')) && ($target ne 'tex')) {
        return "<a target='_top' href='/adm/parmset?symb=$symb&amp;filter=$filter&amp;part=$part'><span class='LC_setting'>$linktext</span></a>";          my $target=' target="_top"';
           if ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) ||
               (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) {
               $target='';
           }
           return "<a".$target." href=\"/adm/parmset?symb=$symb&amp;filter=$filter&amp;part=$part\"><span class=\"LC_setting\">$linktext</span></a>";
     } else {      } else {
        return $linktext;          return $linktext;
     }      }
 }  }
 ##############################################  ##############################################
Line 407  sub textbox { Line 417  sub textbox {
 ##############################################  ##############################################
 ##############################################  ##############################################
 sub checkbox {  sub checkbox {
     my ($name,$checked,$value) = @_;      my ($name,$checked,$value,$special) = @_;
     my $Str = '<input type="checkbox" name="'.$name.'" ';      my $Str = '<input type="checkbox" name="'.$name.'" ';
     if (defined($value)) {      if (defined($value)) {
         $Str .= 'value="'.$value.'"';          $Str .= 'value="'.$value.'"';
Line 415  sub checkbox { Line 425  sub checkbox {
     if ($checked) {      if ($checked) {
         $Str .= ' checked="checked"';          $Str .= ' checked="checked"';
     }      }
     $Str .= ' />';      $Str .= $special.' />';
     return $Str;      return $Str;
 }  }
   
Line 538  sub date_setter { Line 548  sub date_setter {
   
     if (! defined($state) || $state ne 'disabled') {      if (! defined($state) || $state ne 'disabled') {
         $state = '';          $state = '';
       } else {
           $state = 'disabled="disabled"';
     }      }
     if (! defined($no_hh_mm_ss)) {      if (! defined($no_hh_mm_ss)) {
         $no_hh_mm_ss = 0;          $no_hh_mm_ss = 0;
Line 856  parameter setting wizard. Line 868  parameter setting wizard.
 ##############################################  ##############################################
 sub pjump_javascript_definition {  sub pjump_javascript_definition {
     my $Str = <<END;      my $Str = <<END;
     function pjump(type,dis,value,marker,ret,call,hour,min,sec) {      function pjump(type,dis,value,marker,ret,call,hour,min,sec,extra) {
         openMyModal("/adm/rat/parameter.html?type="+escape(type)          openMyModal("/adm/rat/parameter.html?type="+escape(type)
                  +"&value="+escape(value)+"&marker="+escape(marker)                   +"&value="+escape(value)+"&marker="+escape(marker)
                  +"&return="+escape(ret)                   +"&return="+escape(ret)
                  +"&call="+escape(call)+"&name="+escape(dis)                   +"&call="+escape(call)+"&name="+escape(dis)
                  +"&defhour="+escape(hour)+"&defmin="+escape(min)                   +"&defhour="+escape(hour)+"&defmin="+escape(min)
                  +"&defsec="+escape(sec)+"&modal=1",350,350,'no');                   +"&defsec="+escape(sec)+"&extra="+escape(extra)
                    +"&modal=1",350,350,'no');
     }      }
 END  END
     return $Str;      return $Str;
Line 1023  data structure used for bookkeeping. Line 1036  data structure used for bookkeeping.
   
 =item $number_to_do The total number of items being processed.  =item $number_to_do The total number of items being processed.
   
   =item $preamble Optional HTML to display before the progress bar.
   
 =back  =back
   
 =back  =back
   
 Returns a hash containing the progress state data structure.  Returns a hash containing the progress state data structure.
   If $number_to_do is zero or null, an indeterminate progress bar will
   be used.
   
 =item &Update_PrgWin()  =item &Update_PrgWin()
   
Line 1116  Returns: none Line 1133  Returns: none
   
 # Create progress  # Create progress
 sub Create_PrgWin {  sub Create_PrgWin {
     my ($r,$number_to_do)=@_;      my ($r,$number_to_do,$preamble)=@_;
     my %prog_state;      my %prog_state;
     $prog_state{'done'}=0;      $prog_state{'done'}=0;
     $prog_state{'firststart'}=&Time::HiRes::time();      $prog_state{'firststart'}=&Time::HiRes::time();
     $prog_state{'laststart'}=&Time::HiRes::time();      $prog_state{'laststart'}=&Time::HiRes::time();
     $prog_state{'max'}=$number_to_do;      $prog_state{'max'}=$number_to_do;
     &Apache::loncommon::LCprogressbar($r);       &Apache::loncommon::LCprogressbar($r,$prog_state{'max'},$preamble); 
     return %prog_state;      return %prog_state;
 }  }
   
 # update progress  # update progress
 sub Update_PrgWin {  sub Update_PrgWin {
     my ($r,$prog_state,$displayString)=@_;      my ($r,$prog_state,$displayString)=@_;
     &Apache::loncommon::LCprogressbarUpdate($r,undef,$displayString);      &Apache::loncommon::LCprogressbarUpdate($r,undef,$displayString,$$prog_state{'max'});
     $$prog_state{'laststart'}=&Time::HiRes::time();      $$prog_state{'laststart'}=&Time::HiRes::time();
 }  }
   
Line 1179  sub Increment_PrgWin { Line 1196  sub Increment_PrgWin {
     if ($$prog_state{'max'}) {      if ($$prog_state{'max'}) {
        $percent=int(100.*$current/$$prog_state{'max'});         $percent=int(100.*$current/$$prog_state{'max'});
     }      }
     &Apache::loncommon::LCprogressbarUpdate($r,$percent,$timeinfo);      &Apache::loncommon::LCprogressbarUpdate($r,$percent,$timeinfo,$$prog_state{'max'});
     $$prog_state{'laststart'}=&Time::HiRes::time();      $$prog_state{'laststart'}=&Time::HiRes::time();
 }  }
   
Line 1194  sub Close_PrgWin { Line 1211  sub Close_PrgWin {
 # ------------------------------------------------------- Puts directory header  # ------------------------------------------------------- Puts directory header
   
 sub crumbs {  sub crumbs {
     my ($uri,$target,$prefix,$form,$skiplast)=@_;      my ($uri,$target,$prefix,$form,$skiplast,$onclick)=@_;
 # You cannot crumbnify uploaded or adm resources  # You cannot crumbnify uploaded or adm resources
     if ($uri=~/^\/*(uploaded|adm)\//) { return &mt('(Internal Course/Group Content)'); }      if ($uri=~/^\/*(uploaded|adm)\//) { return &mt('(Internal Course/Community Content)'); }
     if ($target) {      if ($target) {
         $target = ' target="'.          $target = ' target="'.
                   &Apache::loncommon::escape_single($target).'"';                    &Apache::loncommon::escape_single($target).'"';
Line 1216  sub crumbs { Line 1233  sub crumbs {
             } else {              } else {
                 $path.='/';                   $path.='/'; 
             }              }
               if ($path eq '/res/') {
                   unless (&Apache::lonnet::allowed('bre',$path)) {
                       $output.="$dir/";
                       next;
                   }
               }
             my $href_path = &HTML::Entities::encode($path,'<>&"');              my $href_path = &HTML::Entities::encode($path,'<>&"');
             &Apache::loncommon::inhibit_menu_check(\$href_path);              &Apache::loncommon::inhibit_menu_check(\$href_path);
             if ($form) {              if ($form) {
                 my $href = 'javascript:'.$form.".action='".$href_path."';".$form.'.submit();';                  my $href = 'javascript:'.$form.".action='".$href_path."';".$form.'.submit();';
                 $output.=qq{<a href="$href"$target>$dir</a>/};                  $output.=qq{<a href="$href"$onclick$target>$dir</a>/};
             } else {              } else {
                 $output.=qq{<a href="$href_path"$target>$dir</a>/};                  $output.=qq{<a href="$href_path"$onclick$target>$dir</a>/};
             }              }
         }          }
     } else {      } else {
Line 1293  sub htmlareaheaders { Line 1316  sub htmlareaheaders {
 ENDEDITOR  ENDEDITOR
  }   }
     $s.=(<<ENDJQUERY);      $s.=(<<ENDJQUERY);
 <script type="text/javascript" src="/adm/jQuery/js/jquery-1.11.3.min.js"></script>  <script type="text/javascript" src="/adm/jQuery/js/jquery-3.2.1.min.js"></script>
 <script type="text/javascript" src="/adm/jQuery/js/jquery-ui-1.11.4.custom.min.js"></script>  <script type="text/javascript" src="/adm/jQuery/js/jquery-ui-1.12.1.custom.min.js"></script>
 <link rel="stylesheet" type="text/css" href="/adm/jQuery/css/smoothness/jquery-ui-1.11.4.custom.css" />  <link rel="stylesheet" type="text/css" href="/adm/jQuery/css/smoothness/jquery-ui-1.12.1.custom.min.css" />
 <script type="text/javascript" src="/adm/jpicker/js/jpicker-1.1.6.min.js" >  <script type="text/javascript" src="/adm/jpicker/js/jpicker-1.1.6.min.js" >
 </script>  </script>
 <link rel="stylesheet" type="text/css" href="/adm/jpicker/css/jPicker-1.1.6.min.css" />  <link rel="stylesheet" type="text/css" href="/adm/jpicker/css/jPicker-1.1.6.min.css" />
Line 1332  $(document).ready(function(){ Line 1355  $(document).ready(function(){
 });';  });';
 }  }
   
   sub countdown {
   
       # Code to put a due date countdown in 'duedatecountdown' span.
       # This is currently located in the breadcrumb headers.
       # note that the dueDateLayout is internatinoalized below.
       # Here document is used to support the substitution into the javascript below.
       # ..which unforunately necessitates escaping the $'s in the javascript.
       # There are several times of importance
       #
       # serverDueDate -  The absolute time at which the problem expires.
       # serverTime    -  The server's time when the problem finished computing.
       # clientTime    -  The client's time...as close to serverTime as possible.
       #                  The clientTime will be slightly later due to
       #                  1. The latency between problem computation and
       #                     the first network action.
       #                  2. The time required between the page load-start and the actual
       #                     initial javascript execution that got clientTime.
       # These are used as follows:
       #   The difference between clientTime and serverTime are used to
       #   correct for differences in clock settings between the browser's system and the
       #   server's.
       #
       #   The difference between clientTime and the time at which the ready() method
       #   starts executing is used to estimate latencies for page load and submission.
       #   Since this is an estimate, it is doubled.  The latency estimate + one minute
       #   is used to determine when the countdown timer turns red to warn the user
       #   to think about submitting.
   
   
       my $dueDateLayout = &mt('Due in: {dn} {dl} {hnn}{sep}{mnn}{sep}{snn} [_1]',
                               "<span id='submitearly'></span>");
       my $early = '- <b>'.&mt('Submit Early').'</b>';
       my $pastdue = '- <b>'.&mt('Past Due').'</b>';
       return <<"JAVASCRIPT";
   
       var documentReadyTime;
   
   \$(document).ready(function() {
      if (typeof(dueDate) != "undefined") {
          documentReadyTime = (new Date()).getTime();
         \$("#duedatecountdown").countdown({until: dueDate, compact: true,
            layout: "$dueDateLayout",
            onTick: function (periods) {
               var latencyEstimate = (documentReadyTime - clientTime) * 2;
               if(\$.countdown.periodsToSeconds(periods) < (300 + latencyEstimate)) {
                  \$("#submitearly").html("$early");
                  if (\$.countdown.periodsToSeconds(periods) < 1) {
                       \$("#submitearly").html("$pastdue");
                  }
               }
               if(\$.countdown.periodsToSeconds(periods) < (60 + latencyEstimate)) {
                  \$(this).css("color", "red");   //Highlight last minute.
               }
            }
         });
      }
   });
   
   JAVASCRIPT
   
   }
   
 # ----------------------------------------- Script to activate only some fields  # ----------------------------------------- Script to activate only some fields
   
 sub htmlareaselectactive {  sub htmlareaselectactive {
Line 1555  sub htmlareaselectactive { Line 1640  sub htmlareaselectactive {
   
  });   });
 ';  ';
     $output .= &color_picker;      $output .= &color_picker();
   
     # Code to put a due date countdown in 'duedatecountdown' span.  
     # This is currently located in the breadcrumb headers.  
     # note that the dueDateLayout is internatinoalized below.  
     # Here document is used to support the substitution into the javascript below.  
     # ..which unforunately necessitates escaping the $'s in the javascript.  
     # There are several times of importance  
     #  
     # serverDueDate -  The absolute time at which the problem expires.  
     # serverTime    -  The server's time when the problem finished computing.  
     # clientTime    -  The client's time...as close to serverTime as possible.  
     #                  The clientTime will be slightly later due to  
     #                  1. The latency between problem computation and   
     #                     the first network action.  
     #                  2. The time required between the page load-start and the actual  
     #                     initial javascript execution that got clientTime.  
     # These are used as follows:  
     #   The difference between clientTime and serverTime are used to   
     #   correct for differences in clock settings between the browser's system and the  
     #   server's.  
     #  
     #   The difference between clientTime and the time at which the ready() method  
     #   starts executing is used to estimate latencies for page load and submission.  
     #   Since this is an estimate, it is doubled.  The latency estimate + one minute  
     #   is used to determine when the countdown timer turns red to warn the user  
     #   to think about submitting.  
   
     my $dueDateLayout = &mt('Due in: {dn} {dl} {hnn}{sep}{mnn}{sep}{snn} [_1]',      $output .= &countdown();
                             "<span id='submitearly'></span>");  
     my $early = '- <b>'.&mt('Submit Early').'</b>';  
     my $pastdue = '- <b>'.&mt('Past Due').'</b>';  
     $output .= <<JAVASCRIPT;  
   
     var documentReadyTime;      $output .= <<"JAVASCRIPT";
   
 \$(document).ready(function() {  
    if (typeof(dueDate) != "undefined") {  
        documentReadyTime = (new Date()).getTime();  
       \$("#duedatecountdown").countdown({until: dueDate, compact: true,   
          layout: "$dueDateLayout",  
          onTick: function (periods) {  
     var latencyEstimate = (documentReadyTime - clientTime) * 2;  
             if(\$.countdown.periodsToSeconds(periods) < (300 + latencyEstimate)) {  
                \$("#submitearly").html("$early");  
                if (\$.countdown.periodsToSeconds(periods) < 1) {  
                     \$("#submitearly").html("$pastdue");  
                }  
             }  
             if(\$.countdown.periodsToSeconds(periods) < (60 + latencyEstimate)) {  
                \$(this).css("color", "red");   //Highlight last minute.  
             }  
          }  
       });  
    }  
 });  
   
     /* This code describes the spellcheck options that will be used for      /* This code describes the spellcheck options that will be used for
        items with class 'spellchecked'.  It is necessary for those objects'         items with class 'spellchecked'.  It is necessary for those objects'
Line 1703  sub show_return_link { Line 1737  sub show_return_link {
     unless ($env{'request.course.id'}) { return 0; }      unless ($env{'request.course.id'}) { return 0; }
     if ($env{'request.noversionuri'}=~m{^/priv/} ||      if ($env{'request.noversionuri'}=~m{^/priv/} ||
         $env{'request.uri'}=~m{^/priv/}) { return 1; }          $env{'request.uri'}=~m{^/priv/}) { return 1; }
     return if ($env{'request.noversionuri'} eq '/adm/supplemental');      return if (($env{'request.noversionuri'} eq '/adm/supplemental') &&
                  ($env{'form.folder'} ne 'supplemental'));
     if (($env{'request.noversionuri'} =~ m{^/adm/(viewclasslist|navmaps)($|\?)})      return if (($env{'form.folderpath'} ne '') &&
                  (($env{'request.noversionuri'} =~ m{^/adm/$match_domain/$match_username/aboutme$}) ||
                   ($env{'request.noversionuri'} =~ m{^/public/$match_domain/$match_courseid/syllabus$})));
       return if (($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement') &&
                  (!$env{'request.role.adv'}));
       if (($env{'request.noversionuri'} =~ m{^/adm/viewclasslist($|\?)})
         || ($env{'request.noversionuri'} =~ m{^/adm/.*/aboutme($|\?)})) {          || ($env{'request.noversionuri'} =~ m{^/adm/.*/aboutme($|\?)})) {
   
         return if ($env{'form.register'});          return if ($env{'form.register'});
     }      }
       if ((($env{'request.symb'} ne '') || ($env{'form.folderpath'} ne '')) &&
            ($env{'request.noversionuri'} =~m{^/adm/coursedocs/showdoc/uploaded/($match_domain)/($match_courseid)/(docs|supplemental)/})) {
           my ($cdom,$cnum,$area) =  ($1,$2,$3);
           if (($env{'course.'.$env{'request.course.id'}.'.domain'} eq $cdom) &&
               ($env{'course.'.$env{'request.course.id'}.'.num'} eq $cnum)) {
               if (($env{'request.symb'}) && ($area eq 'docs')) {
                   my ($map,$resid,$url) = &Apache::lonnet::decode_symb($env{'request.symb'});
                   return if ($env{'request.noversionuri'} eq '/adm/coursedocs/showdoc/'.$url);
               } elsif (($env{'form.folderpath'}) && ($area eq 'supplemental')) {
                   return;
               }
           }
       }
     return (($env{'request.noversionuri'}=~m{^/(res|public)/} &&      return (($env{'request.noversionuri'}=~m{^/(res|public)/} &&
              $env{'request.symb'} eq '')               $env{'request.symb'} eq '')
             ||              ||
Line 1718  sub show_return_link { Line 1770  sub show_return_link {
             (($env{'request.noversionuri'}=~/^\/adm\//) &&              (($env{'request.noversionuri'}=~/^\/adm\//) &&
              ($env{'request.noversionuri'}!~/^\/adm\/wrapper\//) &&               ($env{'request.noversionuri'}!~/^\/adm\/wrapper\//) &&
              ($env{'request.noversionuri'}!~               ($env{'request.noversionuri'}!~
               m{^/adm/.*/(smppg|bulletinboard|exttools?)($|\?)})                m{^/adm/.*/(smppg|bulletinboard|ext\.tool)($|\?)})
            ));             ));
 }  }
   
Line 1778  clientTime = (new Date()).getTime(); Line 1830  clientTime = (new Date()).getTime();
 END  END
 }  }
   
   ##
   # Client-side javascript to convert any dashes in text pasted
   # into textbox(es) for numericalresponse item(s) to a standard
   # minus, i.e., - . Calls to dash_to_minus_js() in end_problem()
   # and in loncommon::endbodytag() for a .page (arg: dashjs => 1)
   #
   # Will apply to any input tag with class: LC_numresponse_text.
   # Currently set in start_textline for numericalresponse items.
   #
   
   sub dash_to_minus_js {
       return <<'ENDJS';
   
   <script type="text/javascript">
   //<![CDATA[
   //<!-- BEGIN LON-CAPA Internal
   document.addEventListener("DOMContentLoaded", (event) => {
       const numresp = document.querySelectorAll("input.LC_numresponse_text");
       if (numresp.length > 0) {
           numresp.forEach((el) => {
               el.addEventListener("paste", (e) => {
                   e.preventDefault();
                   e.stopPropagation();
                   let p = (e.clipboardData || window.clipboardData).getData("text");
                   p.toString();
                   p = p.replace(/\p{Dash}/gu, '-');
                   putInText(p);
               });
           });
       }
       const putInText = (newText, el = document.activeElement) => {
           const [start, end] = [el.selectionStart, el.selectionEnd];
           el.setRangeText(newText, start, end, 'end');
       }
   });
   // END LON-CAPA Internal -->
   //]]>
   </script>
   
   ENDJS
   }
   
 ############################################################  ############################################################
 ############################################################  ############################################################
   
Line 1837  loncommon::help_open_topic() to generate Line 1931  loncommon::help_open_topic() to generate
 text to include in the link in the optional help item ($topic_help) on the right  text to include in the link in the optional help item ($topic_help) on the right
 side of the breadcrumbs row.  side of the breadcrumbs row.
   
   =item $links_target
   
   optionally includes the target (_top, _parent or _self) for (i) initial
   $menulink item in the breadcrumbs (if present), (ii) return to last location
   (if present), and (iii) help item at the right side of breadcrumbs menu, 
   created by loncommon::help_open_topic() or loncommon::help_open_menu().
   
 =back  =back
   
 =back  =back
Line 1868  returns: nothing Line 1969  returns: nothing
           
     sub breadcrumbs {      sub breadcrumbs {
         my ($component,$component_help,$menulink,$helplink,$css_class,$no_mt,           my ($component,$component_help,$menulink,$helplink,$css_class,$no_mt, 
             $CourseBreadcrumbs,$topic_help,$topic_help_text) = @_;              $CourseBreadcrumbs,$topic_help,$topic_help_text,$links_target) = @_;
         #          #
         $css_class ||= 'LC_breadcrumbs';          $css_class ||= 'LC_breadcrumbs';
   
Line 1884  returns: nothing Line 1985  returns: nothing
         # The first one should be the course or a menu link          # The first one should be the course or a menu link
         if (!defined($menulink)) { $menulink=1; }          if (!defined($menulink)) { $menulink=1; }
         if ($menulink) {          if ($menulink) {
               if ($env{'request.course.id'}) {
                   my ($menucoll,$deeplinkmenu,$menuref) = &Apache::loncommon::menucoll_in_effect();
                   if (($menucoll) && (ref($menuref) eq 'HASH')) {
                       if ($menuref->{'main'} eq 'n') {
                          undef($menulink);
                       }
                   }
               }
           }
           if ($menulink) {
             my $description = 'Menu';              my $description = 'Menu';
             my $no_mt_descr = 0;              my $no_mt_descr = 0;
             if ((exists($env{'request.course.id'})) &&               if ((exists($env{'request.course.id'})) && 
Line 1893  returns: nothing Line 2004  returns: nothing
                     $env{'course.'.$env{'request.course.id'}.'.description'};                      $env{'course.'.$env{'request.course.id'}.'.description'};
                 $no_mt_descr = 1;                  $no_mt_descr = 1;
                 if ($env{'request.noversionuri'} =~                   if ($env{'request.noversionuri'} =~ 
                     m{^/public/($match_domain)/($match_courseid)/syllabus$}) {                      m{^/?public/($match_domain)/($match_courseid)/syllabus$}) {
                     unless (($env{'course.'.$env{'request.course.id'}.'.domain'} eq $1) &&                      unless (($env{'course.'.$env{'request.course.id'}.'.domain'} eq $1) &&
                             ($env{'course.'.$env{'request.course.id'}.'.num'} eq $2)) {                              ($env{'course.'.$env{'request.course.id'}.'.num'} eq $2)) {
                         $description = 'Menu';                          $description = 'Menu';
Line 1901  returns: nothing Line 2012  returns: nothing
                     }                      }
                 }                  }
             }              }
               my $target = '_top';
               if ($links_target) {
                   $target = $links_target;
               } elsif ((($env{'request.lti.login'}) && ($env{'request.lti.target'} eq 'iframe')) ||
                   (($env{'request.deeplink.login'}) && ($env{'request.deeplink.target'} eq '_self'))) {
                   $target='';
               }
             $menulink =  {  href   =>'/adm/menu',              $menulink =  {  href   =>'/adm/menu',
                             title  =>'Go to main menu',                              title  =>'Go to main menu',
                             target =>'_top',                              target =>$target,
                             text   =>$description,                              text   =>$description,
                             no_mt  =>$no_mt_descr, };                              no_mt  =>$no_mt_descr, };
             if($last) {              if($last) {
Line 1921  returns: nothing Line 2039  returns: nothing
                             title => &mt('Back to most recent content resource'),                              title => &mt('Back to most recent content resource'),
                             class => 'LC_menubuttons_link',                              class => 'LC_menubuttons_link',
                           };                            };
             if ($env{'request.noversionuri'} eq '/adm/searchcat') {              if ($links_target) {
                 $hashref->{'target'} = '_top';                   $hashref->{'target'} = $links_target;
             }              }
             $links=&htmltag( 'a','<img src="/res/adm/pages/tolastloc.png" alt="'.$alttext.'" class="LC_icon" />',              $links=&htmltag( 'a','<img src="/res/adm/pages/tolastloc.png" alt="'.$alttext.'" class="LC_icon" />',
                              $hashref);                               $hashref);
Line 1973  returns: nothing Line 2091  returns: nothing
         if ($faq ne '' || $component_help ne '' || $bug ne '') {          if ($faq ne '' || $component_help ne '' || $bug ne '') {
             $icons .= &Apache::loncommon::help_open_menu($component,              $icons .= &Apache::loncommon::help_open_menu($component,
                                                          $component_help,                                                           $component_help,
                                                          $faq,$bug);                                                           $faq,$bug,'','','','',
                                                            $links_target);
         }          }
         if ($topic_help && $topic_help_text) {          if ($topic_help && $topic_help_text) {
            $icons .= ' '.&Apache::loncommon::help_open_topic($topic_help,&mt($topic_help_text),'',             $icons .= ' '.&Apache::loncommon::help_open_topic($topic_help,&mt($topic_help_text),'',
                                                              undef,600);                                                               undef,600,'',$links_target);
         }          }
         #          #
   
Line 2177  returns: nothing Line 2296  returns: nothing
 } # End of scope for @Crumbs  } # End of scope for @Crumbs
   
 sub docs_breadcrumbs {  sub docs_breadcrumbs {
     my ($allowed,$crstype,$contenteditor,$title,$precleared)=@_;      my ($allowed,$crstype,$contenteditor,$title,$precleared,$checklinkprot)=@_;
     my ($folderpath,@folders,$supplementalflag);      my ($folderpath,@folders,$supplementalflag);
     @folders = split('&',$env{'form.folderpath'});      @folders = split('&',$env{'form.folderpath'});
     if ($env{'form.folderpath'} =~ /^supplemental/) {      if ($env{'form.folderpath'} =~ /^supplemental/) {
Line 2192  sub docs_breadcrumbs { Line 2311  sub docs_breadcrumbs {
         my $foldername=shift(@folders);          my $foldername=shift(@folders);
         if ($folderpath) {$folderpath.='&';}          if ($folderpath) {$folderpath.='&';}
         $folderpath.=$folder.'&'.$foldername;          $folderpath.=$folder.'&'.$foldername;
         my $url;          my $url = $env{'request.use_absolute'};
         if ($allowed) {          if ($allowed) {
             $url = '/adm/coursedocs?folderpath=';              $url .= '/adm/coursedocs?folderpath=';
         } else {          } else {
             $url = '/adm/supplemental?folderpath=';              $url .= '/adm/supplemental?folderpath=';
         }          }
         $url .= &escape($folderpath);          $url .= &escape($folderpath);
         my $name=&unescape($foldername);          my $name=&unescape($foldername);
 # each of randompick number, hidden, encrypted, random order, is_page   # each of randompick number, hidden, encrypted, random order, is_page 
 # are appended with ":"s to the foldername  # are appended with ":"s to the foldername
         $name=~s/\:(\d*)\:(\w*)\:(\w*):(\d*)\:?(\d*)$//;          $name=~s/\:(\d*)\:(\w*)\:(\w*):(\d*)\:?(\d*)$//;
         unless ($supplementalflag) {          if ($contenteditor) {
             if ($contenteditor) {               if ($supplementalflag) {
                   if ($2) { $ishidden=1; }
               } else {
                 if ($1 ne '') {                  if ($1 ne '') {
                     $randompick=$1;                      $randompick=$1;
                 } else {                  } else {
Line 2245  sub docs_breadcrumbs { Line 2366  sub docs_breadcrumbs {
             $plain=~s/\&gt\;\s*$//;              $plain=~s/\&gt\;\s*$//;
         }          }
         my $menulink = 0;          my $menulink = 0;
         if (!$allowed && !$contenteditor) {          if (!$allowed && !$contenteditor && !$supplementalflag) { 
             $menulink = 1;              $menulink = 1;
         }          }
           if ($checklinkprot) {
               if ($env{'request.deeplink.login'}) {
                   my $linkprotout = &Apache::lonmenu::linkprot_exit();
                   if ($linkprotout) {
                       &Apache::lonhtmlcommon::add_breadcrumb_tool('tools',$linkprotout);
                   }
               }
           }
         return (&breadcrumbs(undef,undef,$menulink,'nohelp',undef,undef,          return (&breadcrumbs(undef,undef,$menulink,'nohelp',undef,undef,
                              $contenteditor),                               $contenteditor),
                              $randompick,$ishidden,$isencrypted,$plain,                               $randompick,$ishidden,$isencrypted,$plain,
Line 2621  sub course_custom_roles { Line 2750  sub course_custom_roles {
   
   
 sub resource_info_box {  sub resource_info_box {
    my ($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp)=@_;     my ($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp,$divforres)=@_;
    my $return='';     my $return='';
    if ($stuvcurrent ne '') {     if (($stuvcurrent ne '') || ($divforres)) {
        $return = '<div class="LC_left_float">';         $return = '<div class="LC_left_float">';
    }     }
    if ($symb) {     if ($symb) {
Line 2652  sub resource_info_box { Line 2781  sub resource_info_box {
     } else {      } else {
        $return='<p><span class="LC_error">'.&mt('No context provided.').'</span></p>';         $return='<p><span class="LC_error">'.&mt('No context provided.').'</span></p>';
     }      }
     if ($stuvcurrent ne '') {      if (($stuvcurrent ne '') || ($divforres)) {
         $return .= '</div>';          $return .= '</div>';
     }      }
     return $return;      return $return;
Line 2667  sub resource_info_box { Line 2796  sub resource_info_box {
 #  #
   
 sub display_usage {  sub display_usage {
     my ($current_disk_usage,$disk_quota) = @_;      my ($current_disk_usage,$disk_quota,$context) = @_;
     my $usage = $current_disk_usage/1000;      my $usage = $current_disk_usage/1024;
     my $quota = $disk_quota/1000;      my $quota = $disk_quota/1024;
     my $percent;      my $percent;
     if ($disk_quota == 0) {      if ($disk_quota == 0) {
         $percent = 100.0;          $percent = 100.0;
Line 2693  sub display_usage { Line 2822  sub display_usage {
     if ($prog_width > 100) {      if ($prog_width > 100) {
         $prog_width = 100;          $prog_width = 100;
     }      }
       my $display = 'block';
       if ($context eq 'authoring') {
           $display = 'inline';
       }
     return '      return '
   <div id="meter1" align="left" '.$cssclass.'>'.&mt('Currently using [_1] of the [_2] available.',$usage.' MB <span style="font-weight:bold;">('.$percent.'%)</span>',$quota.' MB')."\n".    <div id="meter1" align="left" style="display:'.$display.'" '.$cssclass.'>'.&mt('Currently using [_1] of the [_2] available.',$usage.' MB <span style="font-weight:bold;">('.$percent.'%)</span>',$quota.' MB')."\n".
 '   <div id="meter2" style="display:block; margin-top:5px; margin-bottom:5px; margin-left:0px; margin-right:0px; width:400px; border:1px solid #000000; height:10px;">'."\n".  '   <div id="meter2" style="display:block; margin-top:3px; margin-bottom:3px; margin-left:0px; margin-right:0px; width:400px; border:1px solid #000000; height:10px;">'."\n".
 '    <div id="meter3" style="display:block; background-color:'.$color.'; width:'.$prog_width.'%; height:10px; color:#000000; margin:0px;"></div>'."\n".  '    <div id="meter3" style="display:block; background-color:'.$color.'; width:'.$prog_width.'%; height:10px; color:#000000; margin:0px;"></div>'."\n".
 '   </div>'."\n".  '   </div>'."\n".
 '  </div>';  '  </div>';
Line 3379  PARAMSONE Line 3512  PARAMSONE
         if (itemid != null) {          if (itemid != null) {
             itemh = itemid.offsetHeight;              itemh = itemid.offsetHeight;
         }          }
         var primaryheight = document.getElementById('LC_nav_bar').offsetHeight;          var primaryheight = 0;
         var secondaryheight;          if (document.getElementById('LC_nav_bar') != null) { 
               primaryheight = document.getElementById('LC_nav_bar').offsetHeight;
           }
           var secondaryheight = 0;
         if (document.getElementById('LC_secondary_menu') != null) {           if (document.getElementById('LC_secondary_menu') != null) { 
             secondaryheight = document.getElementById('LC_secondary_menu').offsetHeight;              secondaryheight = document.getElementById('LC_secondary_menu').offsetHeight;
         }          }
         var crumbsheight = document.getElementById('LC_breadcrumbs').offsetHeight;          var crumbsheight = 0;
           if (document.getElementById('LC_breadcrumbs') != null) {
               crumbsheight = document.getElementById('LC_breadcrumbs').offsetHeight;
           }
         var dccidheight = 0;          var dccidheight = 0;
         if (document.getElementById('dccid') != null) {          if (document.getElementById('dccid') != null) {
             dccidheight = document.getElementById('dccid').offsetHeight;              dccidheight = document.getElementById('dccid').offsetHeight;
Line 3457  THIRD Line 3596  THIRD
 sub javascript_jumpto_resource {  sub javascript_jumpto_resource {
     my $confirm_switch = &mt("Editing requires switching to the resource's home server.")."\n".      my $confirm_switch = &mt("Editing requires switching to the resource's home server.")."\n".
                          &mt('Switch server?');                           &mt('Switch server?');
       my $confirm_new_tab = &mt("Editing requires using the resource's home server.")."\n".
                             &mt('Open a new browser tab?');
     &js_escape(\$confirm_switch);      &js_escape(\$confirm_switch);
       &js_escape(\$confirm_new_tab);
     return (<<ENDUTILITY)      return (<<ENDUTILITY)
   
 function go(url) {  function go(url) {
    if (url!='' && url!= null) {     if (url!='' && url!= null) {
        currentURL = null;         currentURL = null;
        currentSymb= null;         currentSymb= null;
        window.location.href=url;         var lcHostname = setLCHost();
          if (lcHostname!='' && lcHostname!= null) {
              var RegExp = /^https?\:/;
              if (RegExp.test(url)) {
                  window.location.href=url;
              } else {
                  window.location.href=lcHostname+url;
              }
          } else {
              window.location.href=url;
          }
    }     }
 }  }
   
 function need_switchserver(url) {  function need_switchserver(url,target) {
     if (url!='' && url!= null) {      if (url!='' && url!= null) {
         if (confirm("$confirm_switch")) {          if (target == '_blank') {
               if (confirm("$confirm_new_tab")) {
                   window.open(url,target);
               }
           } else if (confirm("$confirm_switch")) {
             go(url);              go(url);
         }          }
     }      }
Line 3482  ENDUTILITY Line 3638  ENDUTILITY
 }  }
   
 sub jump_to_editres {  sub jump_to_editres {
     my ($cfile,$home,$switchserver,$forceedit,$forcereg,$symb,$folderpath,      my ($cfile,$home,$switchserver,$forceedit,$forcereg,$symb,$shownsymb,
         $title,$idx,$suppurl,$todocs) = @_;          $folderpath,$title,$hostname,$idx,$suppurl,$todocs,$suppanchor) = @_;
     my $jscall;      my ($jscall,$anchor,$usehttp,$usehttps,$is_ext,$target);
     if ($switchserver) {      if ($switchserver) {
         if ($home) {          if ($home) {
               my $resedit;
               if ($cfile =~ m{^/priv/($match_domain)/($match_username)/}) {
                   my ($audom,$auname) = ($1,$2);
                   unless (&Apache::lonnet::is_course($audom,$auname)) {
                       unless ((&Apache::lonnet::will_trust('othcoau',$env{'user.domain'},$audom)) &&
                               (&Apache::lonnet::will_trust('coaurem',$audom,$env{'user.domain'}))) {
                          return;
                       }
                       if (($symb ne '') && ($env{'request.course.id'}) &&
                           (&Apache::lonnet::allowed('mdc',$env{'request.course.id'}))) {
                           unless (&Apache::lonnet::can_switchserver($env{'user.domain'},$home)) {
                               $target = '_blank';
                               $resedit = 1;
                           }
                       }
                   }
               }
             $cfile = '/adm/switchserver?otherserver='.$home.'&amp;role='.              $cfile = '/adm/switchserver?otherserver='.$home.'&amp;role='.
                      &HTML::Entities::encode($env{'request.role'},'"<>&');                       &HTML::Entities::encode($env{'request.role'},'"<>&');
             if ($symb) {              if ($shownsymb) {
                 $cfile .= '&amp;symb='.&HTML::Entities::encode($symb,'"<>&');                  $cfile .= '&amp;symb='.&HTML::Entities::encode($shownsymb,'"<>&');
                   if ($resedit) {
                       $cfile .= '&amp;edit=1';
                   }
             } elsif ($folderpath) {              } elsif ($folderpath) {
                 $cfile .= '&amp;folderpath='.&HTML::Entities::encode($folderpath,'"<>&');                  $cfile .= '&amp;folderpath='.&HTML::Entities::encode($folderpath,'"<>&');
             }              }
Line 3500  sub jump_to_editres { Line 3676  sub jump_to_editres {
             if ($forcereg) {              if ($forcereg) {
                 $cfile .= '&amp;register=1';                  $cfile .= '&amp;register=1';
             }              }
             $jscall = "need_switchserver('".&Apache::loncommon::escape_single($cfile)."');";              $jscall = "need_switchserver('".&Apache::loncommon::escape_single($cfile)."','$target')";
         }          }
     } else {      } else {
         unless ($cfile =~ m{^/priv/}) {          unless ($cfile =~ m{^/priv/}) {
               if ($cfile =~ m{^(/adm/wrapper/ext/([^#]+))(?:|#([^#]+))$}) {
                   $cfile = $1;
                   my $extlink = $2;
                   $anchor = $3;
                   $is_ext = 1;
                   if (($extlink !~ /^https:/) && ($ENV{'SERVER_PORT'} == 443)) {
                       unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) {
                           $usehttp = 1;
                       }
                   } elsif ($env{'request.use_absolute'}) {
                       if ($env{'request.use_absolute'} =~ m{^https://}) {
                           $usehttps = 1;
                       }
                   } 
               } elsif ($cfile =~ m{^/?public/($match_domain)/($match_courseid)/syllabus}) {
                   if ($ENV{'SERVER_PORT'} == 443) {
                       my ($cdom,$cnum) = ($1,$2);
                       if (($env{'request.course.id'}) &&
                           ($env{'course.'.$env{'request.course.id'}.'.num'} eq $cnum) &&
                           ($env{'course.'.$env{'request.course.id'}.'.domain'} eq $cdom)) {
                           if ($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'} =~ m{^http://}) {
                               unless ((&Apache::lonnet::uses_sts()) || (&Apache::lonnet::waf_allssl($hostname))) {
                                   $usehttp = 1;
                               }
                           }
                       }
                   } elsif ($env{'request.use_absolute'}) {
                       if ($env{'request.use_absolute'} =~ m{^https://}) {
                           $usehttps = 1;
                       }
                   }
               }
             if ($symb) {              if ($symb) {
                   if ($anchor ne '') {
                       if ($symb =~ m{^([^#]+)\Q#$anchor\E$}) {
                           $symb = $1.&escape(&escape('#')).$anchor;
                       }
                   }
                 $cfile .= (($cfile=~/\?/)?'&amp;':'?')."symb=$symb";                  $cfile .= (($cfile=~/\?/)?'&amp;':'?')."symb=$symb";
             } elsif ($folderpath) {              } elsif ($folderpath) {
                 $cfile .= (($cfile=~/\?/)?'&amp;':'?').                  $cfile .= (($cfile=~/\?/)?'&amp;':'?').
Line 3523  sub jump_to_editres { Line 3736  sub jump_to_editres {
             }              }
             if ($forceedit) {              if ($forceedit) {
                 $cfile .= (($cfile=~/\?/)?'&amp;':'?').'forceedit=1';                  $cfile .= (($cfile=~/\?/)?'&amp;':'?').'forceedit=1';
                   if ($usehttps) {
                       $cfile = $env{'request.use_absolute'}.(($cfile =~ /^\//)? '':'/').$cfile;
                   }
               } elsif ($usehttp) {
                   if ($hostname ne '') {
                       $cfile = 'http://'.$hostname.(($cfile =~ /^\//)? '':'/').$cfile;
                   }
                   $cfile .= (($cfile=~/\?/)?'&amp;':'?').'usehttp=1';
               } elsif ($usehttps) {
                   $cfile = $env{'request.use_absolute'}.(($cfile =~ /^\//)? '':'/').$cfile;
             }              }
             if ($forcereg) {              if ($forcereg) {
                 $cfile .= (($cfile=~/\?/)?'&amp;':'?').'register=1';                  $cfile .= (($cfile=~/\?/)?'&amp;':'?').'register=1';
             }              }
             if ($todocs) {              if ($todocs) {
                $cfile .= (($cfile=~/\?/)?'&amp;':'?').'todocs=1';                  $cfile .= (($cfile=~/\?/)?'&amp;':'?').'todocs=1';
               }
               if ($suppanchor ne '') {
                   $cfile .= (($cfile=~/\?/)?'&amp;':'?').'anchor='.
                             &HTML::Entities::encode($suppanchor,'"<>&');
             }              }
         }          }
           if ($anchor ne '') {
               $cfile .= '#'.$anchor;
           }
         $jscall = "go('".&Apache::loncommon::escape_single($cfile)."')";          $jscall = "go('".&Apache::loncommon::escape_single($cfile)."')";
     }      }
     return $jscall;      return $jscall;
Line 3542  sub jump_to_editres { Line 3772  sub jump_to_editres {
 # javascript_valid_email  # javascript_valid_email
 #  #
 # Generates javascript to validate an e-mail address.  # Generates javascript to validate an e-mail address.
 # Returns a javascript function which accetps a form field as argumnent, and  # Returns a javascript function which accepts a form field as argument, and
 # returns false if field.value does not satisfy two regular expression matches  # returns false if field.value does not satisfy two regular expression matches
 # for a valid e-mail address.  Backwards compatible with old browsers without  # for a valid e-mail address.  Backwards compatible with old browsers without
 # support for javascript RegExp (just checks for @ in field.value in this case).   # support for javascript RegExp (just checks for @ in field.value in this case). 
   
 sub javascript_valid_email {  sub javascript_valid_email {
     my $scripttag .= <<'END';      my $scripttag .= <<'END';
 function validmail(field) {  function validmail(field,suffix) {
     var str = field.value;      var str = field.value;
       if (suffix != '' && suffix != undefined) {
           str += suffix;
       }
     if (window.RegExp) {      if (window.RegExp) {
         var reg1str = "(@.*@)|(\\.\\.)|(@\\.)|(\\.@)|(^\\.)";          var reg1str = "(@.*@)|(\\.\\.)|(@\\.)|(\\.@)|(^\\.)";
         var reg2str = "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$"; //"          var reg2str = "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$"; //"

Removed from v.1.370  
changed lines
  Added in v.1.410


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>