Diff for /loncom/interface/lonhtmlcommon.pm between versions 1.312 and 1.358.2.13

version 1.312, 2012/05/04 19:03:18 version 1.358.2.13, 2018/09/03 20:37:00
Line 61  use Time::HiRes; Line 61  use Time::HiRes;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonnet;  use Apache::lonnet;
 use HTML::Entities();  use HTML::Entities();
 use LONCAPA;  use LONCAPA qw(:DEFAULT :match);
   
 sub java_not_enabled {  sub java_not_enabled {
    return "\n".'<span class="LC_error">'.      if (($env{'browser.mobile'}) && ($env{'browser.mobile'} =~ /^ipad|ipod|iphone$/i)) {
           &mt('The required Java applet could not be started. Please make sure to have Java installed and active in your browser.').          return "\n".'<span class="LC_error">'.
           "</span>\n";                 &mt('The required Java applet could not be started, because Java is not supported by your mobile device.').
                  "</span>\n";
       } else {
           return "\n".'<span class="LC_error">'.
                  &mt('The required Java applet could not be started. Please make sure to have Java installed and active in your browser.').
                  "</span>\n";
       }
 }  }
   
 sub coursepreflink {  sub coursepreflink {
Line 86  sub raw_href_to_link { Line 92  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 95  sub direct_parm_link { Line 101  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&filter=$filter&part=$part'><span class='LC_setting'>$linktext</span></a>";         return "<a target='_top' 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 170  sub dragmath_js { Line 176  sub dragmath_js {
                   function mathedit(textarea, doc) {                    function mathedit(textarea, doc) {
                      targetEntry = textarea;                       targetEntry = textarea;
                      targetDoc   = doc;                       targetDoc   = doc;
                      newwin  = window.open("/adm/dragmath/applet/$popup.html","","width=565,height=500,resizable");                       newwin  = window.open("/adm/dragmath/$popup.html","","width=565,height=500,resizable");
                   }                    }
                 // ]]>                  // ]]>
                 </script>                  </script>
Line 209  dependencies for a web page uploaded dir Line 215  dependencies for a web page uploaded dir
 =cut  =cut
   
 sub dependencycheck_js {  sub dependencycheck_js {
     my ($symb,$title) = @_;      my ($symb,$title,$url,$folderpath,$uri) = @_;
     my $link = '/adm/dependencies?symb='.&HTML::Entities::encode($symb,'<>&"').      my $link;
                '&title='.&HTML::Entities::encode($title,'<>&"');      if ($symb) {
           $link = '/adm/dependencies?symb='.&HTML::Entities::encode($symb,'<>&"');
       } elsif ($folderpath) {
           $link = '/adm/dependencies?folderpath='.&HTML::Entities::encode($folderpath,'<>&"');
            $url = $uri;
       } elsif ($uri =~ m{^/public/$match_domain/$match_courseid/syllabus$}) {
           $link = '/adm/dependencies';
       }
       $link .= (($link=~/\?/)?'&amp;':'?').'title='.
                &HTML::Entities::encode($title,'<>&"');
       if ($url) {
           $link .= '&url='.&HTML::Entities::encode($url,'<>&"');
       }
     return <<ENDJS;      return <<ENDJS;
                 <script type="text/javascript">                  <script type="text/javascript">
                 // <![CDATA[                  // <![CDATA[
Line 389  sub textbox { Line 407  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 397  sub checkbox { Line 415  sub checkbox {
     if ($checked) {      if ($checked) {
         $Str .= ' checked="checked"';          $Str .= ' checked="checked"';
     }      }
     $Str .= ' />';      $Str .= $special.' />';
     return $Str;      return $Str;
 }  }
   
Line 464  the date/time fields are left empty. Line 482  the date/time fields are left empty.
 =item $state  =item $state
   
 Specifies the initial state of the form elements.  Either 'disabled' or empty.  Specifies the initial state of the form elements.  Either 'disabled' or empty.
 Defaults to empty, which indiciates the form elements are not disabled.   Defaults to empty, which indicates the form elements are not disabled.
   
   =item $no_hh_mm_ss
   
   If true, text boxes for hours, minutes and seconds are omitted.
   
   =item $defhour
   
   Default value for hours (a default of 0 is used otherwise).
   
   =item $defmin
   
   Default value for minutes (a default of 0 is used otherwise).
   
   =item defsec
   
   Default value for seconds (a default of 0 is used otherwise).
   
   =item $nolink
   
   If true, a "Select calendar" link (to pop-up a calendar) is not displayed
   to the right of the items.
   
   =item $no_mm_ss
   
   If true, text boxes for minutes and seconds are omitted.
   
   =item $no_ss
   
   If true, text boxes for seconds are omitted.
   
 =back  =back
   
Line 478  The method used to restrict user input w Line 525  The method used to restrict user input w
 ##############################################  ##############################################
 sub date_setter {  sub date_setter {
     my ($formname,$dname,$currentvalue,$special,$includeempty,$state,      my ($formname,$dname,$currentvalue,$special,$includeempty,$state,
         $no_hh_mm_ss,$defhour,$defmin,$defsec,$nolink) = @_;          $no_hh_mm_ss,$defhour,$defmin,$defsec,$nolink,$no_mm_ss,$no_ss) = @_;
     my $now = time;      my $now = time;
   
     my $tzname;      my $tzname;
Line 487  sub date_setter { Line 534  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 622  ENDJS Line 671  ENDJS
     my $minuteselector = qq{<input type="text" name="$dname\_minute" $special $state value="$min" size="3" />};      my $minuteselector = qq{<input type="text" name="$dname\_minute" $special $state value="$min" size="3" />};
     my $secondselector= qq{<input type="text" name="$dname\_second" $special $state value="$sec" size="3" />};      my $secondselector= qq{<input type="text" name="$dname\_second" $special $state value="$sec" size="3" />};
     my $cal_link;      my $cal_link;
     if (!$nolink) {      unless (($nolink) || ($state eq 'disabled')) {
         $cal_link = qq{<a href="javascript:$dname\_opencalendar()">};          $cal_link = qq{<a href="javascript:$dname\_opencalendar()">};
     }      }
     #      #
Line 631  ENDJS Line 680  ENDJS
         $result .= &mt('[_1] [_2] [_3] ',          $result .= &mt('[_1] [_2] [_3] ',
                        $monthselector,$dayselector,$yearselector).                         $monthselector,$dayselector,$yearselector).
                    $tzone;                     $tzone;
         if (!$nolink) {      } elsif ($no_mm_ss) {
             $result .= &mt('[_1]Select Date[_2]',$cal_link,'</a>');          $result .= &mt('[_1] [_2] [_3] [_4]',
         }                        $monthselector,$dayselector,$yearselector,
                         $hourselector).
                      $tzone;
       } elsif ($no_ss) {
           $result .= &mt('[_1] [_2] [_3] [_4] [_5]m',
                         $monthselector,$dayselector,$yearselector,
                         $hourselector,$minuteselector).
                      $tzone;
     } else {      } else {
         $result .= &mt('[_1] [_2] [_3] [_4] [_5]m [_6]s ',          $result .= &mt('[_1] [_2] [_3] [_4] [_5]m [_6]s ',
                       $monthselector,$dayselector,$yearselector,                        $monthselector,$dayselector,$yearselector,
                       $hourselector,$minuteselector,$secondselector).                        $hourselector,$minuteselector,$secondselector).
                    $tzone;                     $tzone;
         if (!$nolink) {      }
             $result .= &mt('[_1]Select Date[_2]',$cal_link,'</a>');      unless (($nolink) || ($state eq 'disabled')) {
         }          $result .= &mt('[_1]Select Date[_2]',$cal_link,'</a>');
     }      }
     $result .= "</span>\n<!-- end $dname date setting form -->\n";      $result .= "</span>\n<!-- end $dname date setting form -->\n";
     return $result;      return $result;
Line 1100  sub Close_PrgWin { Line 1156  sub Close_PrgWin {
     undef(%$prog_state);      undef(%$prog_state);
 }  }
   
   
 # ------------------------------------------------------- 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 1125  sub crumbs { Line 1182  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 1202  sub htmlareaheaders { Line 1265  sub htmlareaheaders {
 ENDEDITOR  ENDEDITOR
  }   }
     $s.=(<<ENDJQUERY);      $s.=(<<ENDJQUERY);
 <script type="text/javascript" src="/adm/jQuery/js/jquery-1.6.2.min.js"></script>  <script type="text/javascript" src="/adm/jQuery/js/jquery-1.11.3.min.js"></script>
 <script type="text/javascript" src="/adm/jQuery/js/jquery-ui-1.8.16.custom.min.js"></script>  <script type="text/javascript" src="/adm/jQuery/js/jquery-ui-1.11.4.custom.min.js"></script>
 <link rel="stylesheet" type="text/css" href="/adm/jQuery/css/smoothness/jquery-ui-1.8.16.custom.css" />  <link rel="stylesheet" type="text/css" href="/adm/jQuery/css/smoothness/jquery-ui-1.11.4.custom.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" />
 <script type="text/javascript" src="/adm/countdown/js/jquery.countdown.js"></script>  <script type="text/javascript" src="/adm/countdown/js/jquery.countdown.min.js"></script>
 <link rel="stylesheet" type="text/css" href="/adm/countdown/css/jquery.countdown.css" />  <link rel="stylesheet" type="text/css" href="/adm/countdown/css/jquery.countdown.css" />
   
   <script type="text/javascript" src="/adm/spellchecker/js/jquery.spellchecker.min.js"></script>
   <link rel="stylesheet" type="text/css" href="/adm/spellchecker/css/spellchecker.css" />
   <script type="text/javascript" src="/adm/nicescroll/jquery.nicescroll.min.js"></script>
   
 ENDJQUERY  ENDJQUERY
  return $s;   return $s;
 }  }
Line 1225  sub htmlarea_lang { Line 1293  sub htmlarea_lang {
     return $lang;      return $lang;
 }  }
   
   # return javacsript to activate elements of .colorchooser with jpicker:
   # Caller is responsible for enclosing this in <script> tags:
   #
   sub color_picker {
       return '
   $(document).ready(function(){
       $.fn.jPicker.defaults.images.clientPath="/adm/jpicker/images/";
       $(".colorchooser").jPicker({window: { position: {x: "screenCenter", y: "bottom"}}});
   });';
   }
   
 # ----------------------------------------- Script to activate only some fields  # ----------------------------------------- Script to activate only some fields
   
 sub htmlareaselectactive {  sub htmlareaselectactive {
     my ($args) = @_;       my ($args) = @_; 
     unless (&htmlareabrowser()) { return ''; }      unless (&htmlareabrowser()) { return ''; }
     my $output='<script type="text/javascript" defer="defer">'."\n"      my $output='<script type="text/javascript" defer="defer">'."\n"
               .'// <![CDATA['."\n";                .'// <![CDATA['."\n"
                 .'//<!-- BEGIN LON-CAPA Internal'."\n";
     my $lang = &htmlarea_lang();      my $lang = &htmlarea_lang();
     my $fullpage = 'false';      my $fullpage = 'false';
     my ($dragmath_prefix,$dragmath_helpicon,$dragmath_whitespace);      my ($dragmath_prefix,$dragmath_helpicon,$dragmath_whitespace);
Line 1254  sub htmlareaselectactive { Line 1334  sub htmlareaselectactive {
             }              }
         }          }
     }      }
   
       my %lt = &Apache::lonlocal::texthash(
                 'plain'       => 'Plain text',
                 'rich'        => 'Rich formatting',
                 'plain_title' => 'Disable rich text formatting and edit in plain text',
                 'rich_title'  => 'Enable rich text formatting (bold, italic, etc.)',
             );
   
     $output.='      $output.='
           
     function containsBlockHtml(id) {      function containsBlockHtml(id) {
Line 1262  sub htmlareaselectactive { Line 1350  sub htmlareaselectactive {
     }      }
           
     function startRichEditor(id) {      function startRichEditor(id) {
           // fix character entities inside <m>
           // NOTE: this is not fixing characters inside <parse>
           // NOTE: < and > inside <chem> should fix automatically because there should not be a letter after <.
           var ta = document.getElementById(id);
           var value = ta.value;
           var in_m = false; // in the m element
           var in_text = false; // in the text inside the m element
           var im = -1; // position of <m>
           var it = -1; // position of the text inside
           for (var i=0; i<value.length; i++) {
               if (value.substr(i, 2) == "<m") {
                   // ignore previous <m> if found twice
                   in_m = true;
                   in_text = false;
                   im = i;
                   it = -1;
               } else if (in_m) {
                   if (!in_text) {
                       if (value.charAt(i) == ">") {
                           in_text = true;
                           it = i+1;
                       }
                   } else if (value.substr(i, 4) == "</m>") {
                       in_m = false;
                       var text = value.substr(it, i-it);
                       var l1 = text.length;
                       text = text.replace(/</g, "&lt;");
                       text = text.replace(/>/g, "&gt;");
                       var l2 = text.length;
                       value = value.substr(0, it) + text + "</m>" + value.substr(i+4);
                       i = i + (l2-l1);
                   }
               }
           }
           ta.value = value;
     CKEDITOR.replace(id,       CKEDITOR.replace(id, 
     {      {
     customConfig: "/ckeditor/loncapaconfig.js",      customConfig: "/ckeditor/loncapaconfig.js",
Line 1273  sub htmlareaselectactive { Line 1396  sub htmlareaselectactive {
           
     function destroyRichEditor(id) {      function destroyRichEditor(id) {
     CKEDITOR.instances[id].destroy();      CKEDITOR.instances[id].destroy();
           // replace character entities &lt; and &gt; in <m> and <chem>
           // and "&amp;fctname(" by "&fctname("
           // and the quotes inside functions: "&fct(1, &quot;a&quot;)" -> "&fct(1, "a")"
           var ta = document.getElementById(id);
           var value = ta.value;
           var in_element = false; // in the m or chem element
           var tagname = ""; // m or chem
           var in_text = false; // in the text inside the element
           var im = -1; // position of start tag
           var it = -1; // position of the text inside
           for (var i=0; i<value.length; i++) {
               if (value.substr(i, 2) == "<m" || value.substr(i, 5) == "<chem") {
                   // ignore previous tags if found twice
                   in_element = true;
                   if (value.substr(i, 2) == "<m")
                       tagname = "m";
                   else
                       tagname = "chem";
                   in_text = false;
                   im = i;
                   it = -1;
               } else if (in_element) {
                   if (!in_text) {
                       if (value.charAt(i) == ">") {
                           in_text = true;
                           it = i+1;
                       }
                   } else if (value.substr(i, 3+tagname.length) == "</"+tagname+">") {
                       in_element = false;
                       var text = value.substr(it, i-it);
                       var l1 = text.length;
                       text = text.replace(/&lt;/g, "<");
                       text = text.replace(/&gt;/g, ">");
                       var l2 = text.length;
                       value = value.substr(0, it) + text + value.substr(i);
                       i = i + (l2-l1);
                   }
               }
           }
           // fix function names
           value = value.replace(/&amp;([a-zA-Z_]+)\(/g, "&$1(");
           // fix quotes in functions
           var pos_next_fct = value.search(/&[a-zA-Z_]+\(/);
           var depth = 0;
           for (var i=0; i<value.length; i++) {
               if (i == pos_next_fct) {
                   depth++;
                   var sub = value.substring(i+1);
                   var pos2 = sub.search(/&[a-zA-Z_]+\(/);
                   if (pos2 == -1)
                       pos_next_fct = -1;
                   else
                       pos_next_fct = i + 1 + pos2;
               } else if (depth > 0) {
                   if (value.charAt(i) == ")")
                       depth--;
                   else if (value.substr(i, 6) == "&quot;")
                       value = value.substr(0, i) + "\"" + value.substr(i+6);
               }
           }
           // replace the text value
           ta.value = value;
     }      }
           
     function editorHandler(event) {      function editorHandler(event) {
Line 1282  sub htmlareaselectactive { Line 1467  sub htmlareaselectactive {
     var rt_enabled  = $(this).hasClass("LC_enable_rt");      var rt_enabled  = $(this).hasClass("LC_enable_rt");
         if (rt_enabled) {          if (rt_enabled) {
     startRichEditor(id);      startRichEditor(id);
  $("#LC_rt_"+id).html("<b>&laquo; Plain text</b>");   $("#LC_rt_"+id).html("<b>&laquo; '.$lt{'plain'}.'</b>");
  $("#LC_rt_"+id).attr("title", "Disable rich text formatting and edit in plain text");   $("#LC_rt_"+id).attr("title", "'.$lt{'plain_title'}.'");
  $("#LC_rt_"+id).addClass("LC_disable_rt");   $("#LC_rt_"+id).addClass("LC_disable_rt");
  $("#LC_rt_"+id).removeClass("LC_enable_rt");   $("#LC_rt_"+id).removeClass("LC_enable_rt");
     } else {      } else {
  destroyRichEditor(id);   destroyRichEditor(id);
  $("#LC_rt_"+id).html("<b>Rich formatting &raquo;</b>");   $("#LC_rt_"+id).html("<b>'.$lt{'rich'}.' &raquo;</b>");
  $("#LC_rt_"+id).attr("title", "Enable rich text formatting (bold, italic, etc.)");   $("#LC_rt_"+id).attr("title", "'.$lt{'rich_title'}.'");
  $("#LC_rt_"+id).addClass("LC_enable_rt");   $("#LC_rt_"+id).addClass("LC_enable_rt");
  $("#LC_rt_"+id).removeClass("LC_disable_rt");   $("#LC_rt_"+id).removeClass("LC_disable_rt");
  }';   }';
Line 1310  sub htmlareaselectactive { Line 1495  sub htmlareaselectactive {
  var id = $(this).attr("id");   var id = $(this).attr("id");
                         var rt_enabled = containsBlockHtml(id);                          var rt_enabled = containsBlockHtml(id);
  if(rt_enabled) {   if(rt_enabled) {
  $(this).before("<div><a href=\"#\" id=\"LC_rt_"+id+"\" title=\"Disable rich text formatting and edit in plain text\" class=\"LC_disable_rt\"><b>&laquo; Plain text</b></a></div>");   $(this).before("<div><a href=\"#\" id=\"LC_rt_"+id+"\" title=\"'.$lt{'plain_title'}.'\" class=\"LC_disable_rt\"><b>&laquo; '.$lt{'plain'}.'</b></a></div>");
  startRichEditor(id);   startRichEditor(id);
  $("#LC_rt_"+id).click(editorHandler);   $("#LC_rt_"+id).click(editorHandler);
  }   }
  else {   else {
  $(this).before("<div><a href=\"#\" id=\"LC_rt_"+id+"\" title=\"Enable rich text formatting (bold, italic, etc.)\" class=\"LC_enable_rt\"><b>Rich formatting &raquo;</b></a></div>");   $(this).before("<div><a href=\"#\" id=\"LC_rt_"+id+"\" title=\"'.$lt{'rich_title'}.'\" class=\"LC_enable_rt\"><b>'.$lt{'rich'}.' &raquo;</b></a></div>");
  $("#LC_rt_"+id).click(editorHandler);   $("#LC_rt_"+id).click(editorHandler);
  }';   }';
     if ($dragmath_prefix ne '') {      if ($dragmath_prefix ne '') {
Line 1329  sub htmlareaselectactive { Line 1514  sub htmlareaselectactive {
  });   });
  $(".LC_richDefaultOn").each(function() {   $(".LC_richDefaultOn").each(function() {
  var id = $(this).attr("id");   var id = $(this).attr("id");
  $(this).before("<div><a href=\"#\" id=\"LC_rt_"+id+"\" title=\"Disable rich text formatting and edit in plain text\" class=\"LC_disable_rt\"><b>&laquo; Plain text</b></a></div>");   $(this).before("<div><a href=\"#\" id=\"LC_rt_"+id+"\" title=\"'.$lt{'plain_title'}.'\" class=\"LC_disable_rt\"><b>&laquo; '.$lt{'plain'}.'</b></a></div>");
  startRichEditor(id);   startRichEditor(id);
  $("#LC_rt_"+id).click(editorHandler);   $("#LC_rt_"+id).click(editorHandler);
  });   });
  $(".LC_richDefaultOff").each(function() {   $(".LC_richDefaultOff").each(function() {
  var id = $(this).attr("id");   var id = $(this).attr("id");
  $(this).before("<div><a href=\"#\" id=\"LC_rt_"+id+"\" title=\"Enable rich text formatting (bold, italic, etc.)\" class=\"LC_enable_rt\"><b>Rich formatting &raquo;</b></a></div>");   $(this).before("<div><a href=\"#\" id=\"LC_rt_"+id+"\" title=\"'.$lt{'rich_title'}.'\" class=\"LC_enable_rt\"><b>'.$lt{'rich'}.' &raquo;</b></a></div>");
  $("#LC_rt_"+id).click(editorHandler);   $("#LC_rt_"+id).click(editorHandler);
  });   });
                 $.fn.jPicker.defaults.images.clientPath="/adm/jpicker/images/";  
                 $(".colorchooser").jPicker();  
   
   
  });   });
 ';  ';
       $output .= &color_picker;
   
     # Code to put a due date countdown in 'duedatecountdown' span.      # Code to put a due date countdown in 'duedatecountdown' span.
     # This is currently located in the breadcrumb headers.      # This is currently located in the breadcrumb headers.
     # note that the dueDateLayout is internatinoalized below.      # note that the dueDateLayout is internatinoalized below.
Line 1370  sub htmlareaselectactive { Line 1555  sub htmlareaselectactive {
     #   is used to determine when the countdown timer turns red to warn the user      #   is used to determine when the countdown timer turns red to warn the user
     #   to think about submitting.      #   to think about submitting.
   
     my $dueDateLayout = '<b>' .  &mt('Due in: {dn} {dl} {hnn}{sep}{mnn}{sep}{snn} - Submit early!') . '</b>';      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>';
     $output .= <<JAVASCRIPT;      $output .= <<JAVASCRIPT;
   
     var documentReadyTime;      var documentReadyTime;
Line 1382  sub htmlareaselectactive { Line 1570  sub htmlareaselectactive {
          layout: "$dueDateLayout",           layout: "$dueDateLayout",
          onTick: function (periods) {           onTick: function (periods) {
     var latencyEstimate = (documentReadyTime - clientTime) * 2;      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)) {              if(\$.countdown.periodsToSeconds(periods) < (60 + latencyEstimate)) {
                \$(this).css("color", "red");   //Highlight last minute.                 \$(this).css("color", "red");   //Highlight last minute.
             }              }
Line 1389  sub htmlareaselectactive { Line 1583  sub htmlareaselectactive {
       });        });
    }     }
 });  });
   
       /* This code describes the spellcheck options that will be used for
          items with class 'spellchecked'.  It is necessary for those objects'
          to explicitly request checking (e.g. onblur is a nice event for that).
        */
        \$(document).ready(function() {
    \$(".spellchecked").spellchecker({
      url: "/ajax/spellcheck",
      lang: "en",                      
      engine: "pspell",
      suggestionBoxPosition: "below",
      innerDocument: true
     });
    \$("textarea.spellchecked").spellchecker({
      url: "/ajax/spellcheck",
      lang: "en",                      
      engine: "pspell",
      suggestionBoxPosition: "below",
      innerDocument: true
     });
   
    });
   
       /* the muli colored editor can generate spellcheck with language 'none'
          to disable spellcheck as well
       */
       function doSpellcheck(element, lang) {
    if (lang != 'none') {
        \$(element).spellchecker('option', {lang: lang});
       \$(element).spellchecker('check');
           }
       }
   
   
 JAVASCRIPT  JAVASCRIPT
     if ($dragmath_prefix ne '') {      if ($dragmath_prefix ne '') {
         $output .= '          $output .= '
Line 1419  JAVASCRIPT Line 1647  JAVASCRIPT
   
     }      }
     $output.="\nwindow.status='Activated Editfields';\n"      $output.="\nwindow.status='Activated Editfields';\n"
               .'// END LON-CAPA Internal -->'."\n"
             .'// ]]>'."\n"              .'// ]]>'."\n"
             .'</script>';              .'</script>';
     return $output;      return $output;
Line 1445  sub show_return_link { Line 1674  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{^/~}) { return 1; }          $env{'request.uri'}=~m{^/priv/}) { return 1; }
       return if ($env{'request.noversionuri'} eq '/adm/supplemental');
   
     if (($env{'request.noversionuri'} =~ m{^/adm/(viewclasslist|navmaps)($|\?)})      if (($env{'request.noversionuri'} =~ m{^/adm/(viewclasslist|navmaps)($|\?)})
         || ($env{'request.noversionuri'} =~ m{^/adm/.*/aboutme($|\?)})) {          || ($env{'request.noversionuri'} =~ m{^/adm/.*/aboutme($|\?)})) {
Line 1484  sub set_due_date { Line 1714  sub set_due_date {
     # The code should correct for gross differences between the server      # The code should correct for gross differences between the server
     # and client's time setting      # and client's time setting
   
     my $js = "       return <<"END";
 <script type='text/javascript'>  
   <script type="text/javascript">
   //<![CDATA[    //<![CDATA[
 var serverDueDate = $duems;  var serverDueDate = $duems;
 var serverTime    = $now;  var serverTime    = $now;
Line 1494  var dueDate       = new Date(serverDueDa Line 1725  var dueDate       = new Date(serverDueDa
   
   //]]>    //]]>
 </script>  </script>
 ";  
   
     return $js;  END
 }  }
 ##  ##
 # Sets the time at which the problem finished computing.  # Sets the time at which the problem finished computing.
Line 1508  var dueDate       = new Date(serverDueDa Line 1738  var dueDate       = new Date(serverDueDa
 sub set_compute_end_time {  sub set_compute_end_time {
   
     my $now = time()*1000; # Javascript times are in ms.      my $now = time()*1000; # Javascript times are in ms.
     my $js = "      return <<"END";
 <script type='text/javascript'>  
   <script type="text/javascript">
 //<![CDATA[  //<![CDATA[
 serverTime = $now;  serverTime = $now;
 clientTime = (new Date()).getTime();  clientTime = (new Date()).getTime();
 //]]>  //]]>
 </script>  </script>
   
 ";  END
     return $js;  
       
 }  }
   
 ############################################################  ############################################################
Line 1536  A link to help for the component will be Line 1765  A link to help for the component will be
 All inputs can be undef without problems.  All inputs can be undef without problems.
   
 Inputs: $component (the text on the right side of the breadcrumbs trail),  Inputs: $component (the text on the right side of the breadcrumbs trail),
         $component_help          $component_help (the help item filename (without .tex extension).
         $menulink (boolean, controls whether to include a link to /adm/menu)          $menulink (boolean, controls whether to include a link to /adm/menu)
         $helplink (if 'nohelp' don't include the orange help link)          $helplink (if 'nohelp' don't include the orange help link)
         $css_class (optional name for the class to apply to the table for CSS)          $css_class (optional name for the class to apply to the table for CSS)
         $no_mt (optional flag, 1 if &mt() is _not_ to be applied to $component          $no_mt (optional flag, 1 if &mt() is _not_ to be applied to $component
            when including the text on the right.             when including the text on the right.
           $CourseBreadcrumbs (optional flag, 1 if &breadcrumbs called from &docs_breadcrumbs,
              because breadcrumbs are being)
           $topic_help (optional help item to be displayed on right side of the breadcrumbs 
              row, using loncommon::help_open_topic() to generate the link.
           $topic_help_text (text to include in the link in the optional help item 
              on the right side of the breadcrumbs row.
   
 Returns a string containing breadcrumbs for the current page.  Returns a string containing breadcrumbs for the current page.
   
 =item &clear_breadcrumbs()  =item &clear_breadcrumbs()
Line 1568  returns: nothing Line 1804  returns: nothing
     my %tools = ();      my %tools = ();
           
     sub breadcrumbs {      sub breadcrumbs {
         my ($component,$component_help,$menulink,$helplink,$css_class,$no_mt, $CourseBreadcrumbs) = @_;          my ($component,$component_help,$menulink,$helplink,$css_class,$no_mt, 
               $CourseBreadcrumbs,$topic_help,$topic_help_text) = @_;
         #          #
         $css_class ||= 'LC_breadcrumbs';          $css_class ||= 'LC_breadcrumbs';
   
Line 1592  returns: nothing Line 1829  returns: nothing
                 $description =                   $description = 
                     $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'} =~ 
                       m{^/?public/($match_domain)/($match_courseid)/syllabus$}) {
                       unless (($env{'course.'.$env{'request.course.id'}.'.domain'} eq $1) &&
                               ($env{'course.'.$env{'request.course.id'}.'.num'} eq $2)) {
                           $description = 'Menu';
                           $no_mt_descr = 0;
                       }
                   }
             }              }
             $menulink =  {  href   =>'/adm/menu',              $menulink =  {  href   =>'/adm/menu',
                             title  =>'Go to main menu',                              title  =>'Go to main menu',
Line 1607  returns: nothing Line 1852  returns: nothing
             }              }
         }          }
         my $links;          my $links;
         if ((&show_return_link) && (!$CourseBreadcrumbs)) {          if ((&show_return_link) && (!$CourseBreadcrumbs) && (ref($last) eq 'HASH')) {
             my $alttext = &mt('Go Back');              my $alttext = &mt('Go Back');
             $links=&htmltag( 'a',"<img src='/res/adm/pages/reload.png' border='0' style='vertical-align:middle;' alt='$alttext' />",              my $hashref = { href => '/adm/flip?postdata=return:',
                             { href => '/adm/flip?postdata=return:',                              title => &mt('Back to most recent content resource'),
                               title => &mt("Back to most recent content resource") });                              class => 'LC_menubuttons_link',
                             };
               if ($env{'request.noversionuri'} eq '/adm/searchcat') {
                   $hashref->{'target'} = '_top'; 
               }
               $links=&htmltag( 'a','<img src="/res/adm/pages/tolastloc.png" alt="'.$alttext.'" class="LC_icon" />',
                                $hashref);
             $links=&htmltag('li',$links);              $links=&htmltag('li',$links);
         }          }
         $links.= join "",           $links.= join "", 
Line 1640  returns: nothing Line 1891  returns: nothing
         # last breadcrumb is the first order heading of a page          # last breadcrumb is the first order heading of a page
         # for course breadcrumbs it's just bold          # for course breadcrumbs it's just bold
   
         $links .= &htmltag( 'li', htmltag($CourseBreadcrumbs ? 'b' : 'h1',          if ($lasttext ne '') {
                 $lasttext), {title => $lasttext});              $links .= &htmltag( 'li', htmltag($CourseBreadcrumbs ? 'b' : 'h1',
                       $lasttext), {title => $lasttext});
         unless ($CourseBreadcrumbs) {  
             $links .=   '<li> <span id="duedatecountdown"></span></li>';  
         }          }
   
         my $icons = '';          my $icons = '';
Line 1663  returns: nothing Line 1912  returns: nothing
                                                          $component_help,                                                           $component_help,
                                                          $faq,$bug);                                                           $faq,$bug);
         }          }
           if ($topic_help && $topic_help_text) {
              $icons .= ' '.&Apache::loncommon::help_open_topic($topic_help,&mt($topic_help_text),'',
                                                                undef,600);
           }
         #          #
   
   
           if ($links ne '') {
         unless ($CourseBreadcrumbs) {              unless ($CourseBreadcrumbs) {
             $links = &htmltag('ol',  $links, { id => "LC_MenuBreadcrumbs"   });                  $links = &htmltag('ol',  $links, { id => "LC_MenuBreadcrumbs"   });
         } else {              } else {
             $links = &htmltag('ul',  $links, { class => "LC_CourseBreadcrumbs" });                  $links = &htmltag('ul',  $links, { class => "LC_CourseBreadcrumbs" });
               }
         }          }
   
   
         if ($component) {          if (($component) || ($topic_help && $topic_help_text)) {
             $links = &htmltag('span',               $links = &htmltag('span', 
                              ( $no_mt ? $component : mt($component) ).                               ( $no_mt ? $component : mt($component) ).
                              ( $icons ? $icons : '' ),                               ( $icons ? $icons : '' ),
Line 1682  returns: nothing Line 1936  returns: nothing
                              .$links                                .$links 
 ;  ;
         }          }
                   my $nav_and_tools = 0;
         &render_tools(\$links);          foreach my $item ('navigation','tools') {
         $links = &htmltag('div', $links,               if (ref($tools{$item}) eq 'ARRAY') {
                         { id => "LC_breadcrumbs" }) unless ($CourseBreadcrumbs) ;                  $nav_and_tools += scalar(@{$tools{$item}})
         &render_advtools(\$links);              }
           }
           if (($links ne '') || ($nav_and_tools)) {
               &render_tools(\$links);
               $links = &htmltag('div', $links, 
                                 { id => "LC_breadcrumbs" }) unless ($CourseBreadcrumbs) ;
           }
           my $adv_tools = 0;
           if (ref($tools{'advtools'}) eq 'ARRAY') {
               $adv_tools = scalar(@{$tools{'advtools'}});
           }
           if (($links ne '') || ($adv_tools)) {
               &render_advtools(\$links);
           }
   
         # Return the @Crumbs stack to what we started with          # Return the @Crumbs stack to what we started with
         push(@Crumbs,$last);          push(@Crumbs,$last);
Line 1724  Currently there are 3 possible values fo Line 1991  Currently there are 3 possible values fo
 left of breadcrumbs line  left of breadcrumbs line
   
 =item tools   =item tools 
 right of breadcrumbs line  remaining items in right of breadcrumbs line
   
 =item advtools   =item advtools 
 advanced tools shown in a separate box below breadcrumbs line   advanced tools shown in a separate box below breadcrumbs line 
Line 1764  returns: nothing Line 2031  returns: nothing
         undef(%tools);          undef(%tools);
     }      }
   
   =item &current_breadcrumb_tools()
   
   returns: a hash containing the current breadcrumb tools.
   
   =cut
   
       sub current_breadcrumb_tools {
           return %tools;
       }
   
 =item &render_tools(\$breadcrumbs)  =item &render_tools(\$breadcrumbs)
   
 Creates html for breadcrumb tools (categories navigation and tools) and inserts   Creates html for breadcrumb tools (categories navigation and tools) and inserts 
Line 1814  returns: nothing Line 2091  returns: nothing
   
 } # End of scope for @Crumbs  } # End of scope for @Crumbs
   
   sub docs_breadcrumbs {
       my ($allowed,$crstype,$contenteditor,$title,$precleared)=@_;
       my ($folderpath,@folders,$supplementalflag);
       @folders = split('&',$env{'form.folderpath'});
       if ($env{'form.folderpath'} =~ /^supplemental/) {
           $supplementalflag = 1;
       }
       my $plain='';
       my $container = 'sequence';
       my ($randompick,$isencrypted,$ishidden,$is_random_order) = (-1,0,0,0);
       my @docs_crumbs;
       while (@folders) {
           my $folder=shift(@folders);
           my $foldername=shift(@folders);
           if ($folderpath) {$folderpath.='&';}
           $folderpath.=$folder.'&'.$foldername;
           my $url;
           if ($allowed) {
               $url = '/adm/coursedocs?folderpath=';
           } else {
               $url = '/adm/supplemental?folderpath=';
           }
           $url .= &escape($folderpath);
           my $name=&unescape($foldername);
   # each of randompick number, hidden, encrypted, random order, is_page 
   # are appended with ":"s to the foldername
           $name=~s/\:(\d*)\:(\w*)\:(\w*):(\d*)\:?(\d*)$//;
           unless ($supplementalflag) {
               if ($contenteditor) { 
                   if ($1 ne '') {
                       $randompick=$1;
                   } else {
                       $randompick=-1;
                   }
                   if ($2) { $ishidden=1; }
                   if ($3) { $isencrypted=1; }
                   if ($4 ne '') { $is_random_order = 1; }
                   if ($5 == 1) {$container = 'page'; }
               }
           }
           if ($folder eq 'supplemental') {
               $name = &mt('Supplemental Content');
           }
           if ($contenteditor) {
               $plain.=$name.' &gt; ';
           }
           push(@docs_crumbs,
                             {'href'  => $url,
                              'title' => $name,
                              'text'  => $name,
                              'no_mt' => 1,
                             });
       }
       if ($title) {
           push(@docs_crumbs,
                             {'title' => $title,
                              'text'  => $title,
                              'no_mt' => 1,}
                             );
       }
       if (wantarray) {
           unless ($precleared) {
               &clear_breadcrumbs();
           }
           &add_breadcrumb(@docs_crumbs);
           if ($contenteditor) {
               $plain=~s/\&gt\;\s*$//;
           }
           my $menulink = 0;
           if (!$allowed && !$contenteditor) {
               $menulink = 1;
           }
           return (&breadcrumbs(undef,undef,$menulink,'nohelp',undef,undef,
                                $contenteditor),
                                $randompick,$ishidden,$isencrypted,$plain,
                                $is_random_order,$container);
       } else {
           return \@docs_crumbs;
       }
   }
   
 ############################################################  ############################################################
 ############################################################  ############################################################
   
Line 1874  returns: nothing Line 2232  returns: nothing
 my @row_count;  my @row_count;
   
 sub start_pick_box {  sub start_pick_box {
     my ($css_class) = @_;      my ($css_class,$id) = @_;
     if (defined($css_class)) {      if (defined($css_class)) {
  $css_class = 'class="'.$css_class.'"';   $css_class = 'class="'.$css_class.'"';
     } else {      } else {
  $css_class= 'class="LC_pick_box"';   $css_class= 'class="LC_pick_box"';
     }      }
       my $table_id;
       if (defined($id)) {
           $table_id = ' id="'.$id.'"';
       }
     unshift(@row_count,0);      unshift(@row_count,0);
     my $output = <<"END";      my $output = <<"END";
  <table $css_class>   <table $css_class $table_id>
 END  END
     return $output;      return $output;
 }  }
Line 2037  sub course_selection { Line 2399  sub course_selection {
   
     my $courseform='<b>'.&Apache::loncommon::selectcourse_link      my $courseform='<b>'.&Apache::loncommon::selectcourse_link
                      ($formname,'pickcourse','pickdomain','coursedesc','',1,$crstype).'</b>';                       ($formname,'pickcourse','pickdomain','coursedesc','',1,$crstype).'</b>';
         $output .= '<input type="radio" name="coursepick" value="all" onclick="coursePick(this.form)" />'.$allcrs.'<br />';          $output .= '<label><input type="radio" name="coursepick" value="all" onclick="coursePick(this.form)" />'.$allcrs.'</label><br />';
     if ($totcodes > 0) {      if ($totcodes > 0) {
         my $numtitles = @$codetitles;          my $numtitles = @$codetitles;
         if ($numtitles > 0) {          if ($numtitles > 0) {
             $output .= '<input type="radio" name="coursepick" value="category" onclick="coursePick(this.form);alert('."'".&mt('Choose categories, from left to right')."'".')" />'.&mt('Pick courses by category:').' <br />';              $output .= '<label><input type="radio" name="coursepick" value="category" onclick="coursePick(this.form);alert('."'".&html_escape(&mt('Choose categories, from left to right'))."'".')" />'.&mt('Pick courses by category:').'</label><br />';
             $output .= '<table><tr><td>'.$$codetitles[0].'<br />'."\n".              $output .= '<table><tr><td>'.$$codetitles[0].'<br />'."\n".
                '<select name="'.$standardnames->[0].                 '<select name="'.$standardnames->[0].
                '" onChange="setPick(this.form);courseSet('."'$$codetitles[0]'".')">'."\n".                 '" onchange="setPick(this.form);courseSet('."'$$codetitles[0]'".')">'."\n".
                ' <option value="-1" />Select'."\n";                 ' <option value="-1" />Select'."\n";
             my @items = ();              my @items = ();
             my @longitems = ();              my @longitems = ();
Line 2074  sub course_selection { Line 2436  sub course_selection {
             for (my $i=1; $i<$numtitles; $i++) {              for (my $i=1; $i<$numtitles; $i++) {
                 $output .= '<td>'.$$codetitles[$i].'<br />'."\n".                  $output .= '<td>'.$$codetitles[$i].'<br />'."\n".
                           '<select name="'.$standardnames->[$i].                            '<select name="'.$standardnames->[$i].
                           '" onChange="courseSet('."'$$codetitles[$i]'".')">'."\n".                            '" onchange="courseSet('."'$$codetitles[$i]'".')">'."\n".
                           '<option value="-1">&lt;-Pick '.$$codetitles[$i-1].'</option>'."\n".                            '<option value="-1">&lt;-Pick '.$$codetitles[$i-1].'</option>'."\n".
                           '</select>'."\n".                            '</select>'."\n".
                           '</td>';                            '</td>';
Line 2082  sub course_selection { Line 2444  sub course_selection {
             $output .= '</tr></table><br />';              $output .= '</tr></table><br />';
         }          }
     }      }
     $output .= '<input type="radio" name="coursepick" value="specific" onclick="coursePick(this.form);opencrsbrowser('."'".$formname."','dccourse','dcdomain','coursedesc','','1','$crstype'".')" />'.$pickspec.' '.$courseform.'&nbsp;&nbsp;<input type="text" value="0" size="4" name="coursetotal" /><input type="hidden" name="courselist" value="" />selected.<br />'."\n";      $output .=
           '<label><input type="radio" name="coursepick" value="specific"'
          .' onclick="coursePick(this.form);opencrsbrowser('."'".$formname."','dccourse','dcdomain','coursedesc','','1','$crstype'".')" />'
          .$pickspec.'</label>'
          .' '.$courseform.'&nbsp;&nbsp;'
          .&mt('[_1] selected.',
                   '<input type="text" value="0" size="4" name="coursetotal" readonly="readonly" />'
                  .'<input type="hidden" name="courselist" value="" />')
          .'<br />'."\n";
     return $output;      return $output;
 }  }
   
Line 2203  sub resource_info_box { Line 2573  sub resource_info_box {
     return $return;      return $return;
 }  }
   
   # display_usage
   # 
   # Generates a div containing a block, filled to show percentage of current quota used
   #
   # Quotas available for user portfolios, group portfolios, authoring spaces, and course
   # content stored directly within a course (i.e., excluding published content).
   #
   
   sub display_usage {
       my ($current_disk_usage,$disk_quota,$context) = @_;
       my $usage = $current_disk_usage/1024;
       my $quota = $disk_quota/1024;
       my $percent;
       if ($disk_quota == 0) {
           $percent = 100.0;
       } else {
           $percent = 100*($current_disk_usage/$disk_quota);
       }
       $usage = sprintf("%.2f",$usage);
       $quota = sprintf("%.2f",$quota);
       $percent = sprintf("%.0f",$percent);
       my ($color,$cssclass);
       if ($percent <= 60) {
           $color = '#00A000';
       } elsif ($percent > 60 && $percent < 90) {
           $color = '#FFD300';
           $cssclass = 'class="LC_warning"';
       } elsif( $percent >= 90) {
           $color = '#FF0000';
           $cssclass = 'class="LC_error"';
       }
       my $prog_width = $percent;
       if ($prog_width > 100) {
           $prog_width = 100;
       }
       my $display = 'block';
       if ($context eq 'authoring') {
           $display = 'inline';
       }
       return '
     <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: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>'."\n".
   '  </div>';
   }
   
 ##############################################  ##############################################
 ##############################################  ##############################################
   
Line 2214  sub resource_info_box { Line 2631  sub resource_info_box {
 # 1. number to display.  # 1. number to display.
 #    If input for number is empty only the title will be displayed.   #    If input for number is empty only the title will be displayed. 
 # 2. title text to display.  # 2. title text to display.
   # 3. optional id for the <div>
 # Outputs - a scalar containing html mark-up for the div.  # Outputs - a scalar containing html mark-up for the div.
   
 sub topic_bar {  sub topic_bar {
     my ($num,$title) = @_;      my ($num,$title,$id) = @_;
     my $number = '';      my $number = '';
     if ($num ne '') {      if ($num ne '') {
         $number = '<span>'.$num.'</span>';          $number = '<span>'.$num.'</span>';
     }      }
     return '<div class="LC_topic_bar">'.$number.$title.'</div>';      if ($id ne '') {
           $id = 'id="'.$id.'"';
       }
       return '<div class="LC_topic_bar" '.$id.'>'.$number.$title.'</div>';
 }  }
   
 ##############################################  ##############################################
Line 2443  sub set_form_elements { Line 2864  sub set_form_elements {
   
 sub file_submissionchk_js {  sub file_submissionchk_js {
     my ($turninpaths,$multiples) = @_;      my ($turninpaths,$multiples) = @_;
     my $overwritewarn = &mt('File(s) you uploaded for your submission will overwrite existing file(s) submitted for this item').'\\n'.      my $overwritewarn = &mt('File(s) you uploaded for your submission will overwrite existing file(s) submitted for this item')."\n".
                       &mt('Continue submission and overwrite the file(s)?');                        &mt('Continue submission and overwrite the file(s)?');
     my $delfilewarn = &mt('You have indicated you wish to remove some files previously included in your submission.').'\\n'.      &js_escape(\$overwritewarn);
       my $delfilewarn = &mt('You have indicated you wish to remove some files previously included in your submission.')."\n".
                       &mt('Continue submission with these files removed?');                        &mt('Continue submission with these files removed?');
       &js_escape(\$delfilewarn);
     my ($turninpathtext,$multtext,$arrayindexofjs);      my ($turninpathtext,$multtext,$arrayindexofjs);
     if (ref($turninpaths) eq 'HASH') {      if (ref($turninpaths) eq 'HASH') {
         foreach my $key (sort(keys(%{$turninpaths}))) {          foreach my $key (sort(keys(%{$turninpaths}))) {
Line 2686  ENDSCRIPT Line 3109  ENDSCRIPT
 ##############################################  ##############################################
 ##############################################  ##############################################
   
   sub resize_scrollbox_js {
       my ($context,$tabidstr,$tid) = @_;
       my (%names,$paddingwfrac,$offsetwfrac,$offsetv,$minw,$minv);
       if ($context eq 'docs') {
           %names = (
                      boxw   => 'contenteditor',
                      item   => 'contentlist',
                      header => 'uploadfileresult',
                      scroll => 'contentscroll',
                      boxh   => 'contenteditor',
                    );
           $paddingwfrac = 0.09;
           $offsetwfrac = 0.015;
           $offsetv = 20;
           $minw = 250;
           $minv = 200;
       } elsif ($context eq 'params') {
           %names = (
                      boxw   => 'parameditor',
                      item   => 'mapmenuinner',
                      header => 'parmstep1',
                      scroll => 'mapmenuscroll',
                      boxh   => 'parmlevel',
                    );
           $paddingwfrac = 0.2;
           $offsetwfrac = 0.015;
           $offsetv = 80;
           $minw = 100;
           $minv = 100; 
       }
       my $viewport_js = &Apache::loncommon::viewport_geometry_js();
       my $output = '
   
   window.onresize=callResize;
   
   ';
       if ($context eq 'docs') {
           if ($env{'form.active'}) {
               $output .= "\nvar activeTab = '$env{'form.active'}$tid';\n";
           } else {
               $output .= "\nvar activeTab = '';\n";
           }
       }
       $output .=  <<"FIRST";
   
   $viewport_js
   
   function resize_scrollbox(scrollboxname,chkw,chkh) {
       var scrollboxid = 'div_'+scrollboxname;
       var scrolltableid = 'table_'+scrollboxname;
       var scrollbox;
       var scrolltable;
       var ismobile = '$env{'browser.mobile'}';
   
       if (document.getElementById("$names{'boxw'}") == null) {
           return;
       }
   
       if (document.getElementById(scrollboxid) == null) {
           return;
       } else {
           scrollbox = document.getElementById(scrollboxid);
       }
   
   
       if (document.getElementById(scrolltableid) == null) {
           return;
       } else {
           scrolltable = document.getElementById(scrolltableid);
       }
   
       init_geometry();
       var vph = Geometry.getViewportHeight();
       var vpw = Geometry.getViewportWidth();
   
   FIRST
       if ($context eq 'docs') {
           $output .= "
       var alltabs = ['$tabidstr'];
   ";
       } elsif ($context eq 'params') {
           $output .= "
       if (document.getElementById('$names{'boxh'}') == null) {
           return;
       }
   ";
       }
       $output .= <<"SECOND";
       var listwchange;
       var scrollchange;
       if (chkw == 1) {
           var boxw = document.getElementById("$names{'boxw'}").offsetWidth;
           var itemw;
           var itemid = document.getElementById("$names{'item'}");
           if (itemid != null) {
               itemw = itemid.offsetWidth;
           }
           var itemwstart = itemw;
   
           var scrollboxw = scrollbox.offsetWidth;
           var scrollboxscrollw = scrollbox.scrollWidth;
           var scrollstart = scrollboxw;
   
           var offsetw = parseInt(vpw * $offsetwfrac);
           var paddingw = parseInt(vpw * $paddingwfrac);
   
           var minscrollboxw = $minw;
           var maxcolw = 0;
   SECOND
       if ($context eq 'docs') {
           $output .= <<"DOCSONE";
           var actabw = 0;
           for (var i=0; i<alltabs.length; i++) {
               if (activeTab == alltabs[i]) {
                   actabw = document.getElementById(alltabs[i]).offsetWidth;
                   if (actabw > maxcolw) {
                       maxcolw = actabw;
                   }
               } else {
                   if (document.getElementById(alltabs[i]) != null) {
                       var thistab = document.getElementById(alltabs[i]);
                       thistab.style.visibility = 'hidden';
                       thistab.style.display = 'block';
                       var tabw = document.getElementById(alltabs[i]).offsetWidth;
                       thistab.style.display = 'none';
                       thistab.style.visibility = '';
                       if (tabw > maxcolw) {
                           maxcolw = tabw;
                       }
                   }
               }
           }
   DOCSONE
       } elsif ($context eq 'params') {
           $output .= <<"PARAMSONE";
           var parmlevelrows = new Array();
           var mapmenucells = new Array();
           parmlevelrows = document.getElementById("$names{'boxh'}").rows;
           var numrows = parmlevelrows.length;
           if (numrows > 1) {
               mapmenucells = parmlevelrows[2].getElementsByTagName('td');
           }
           maxcolw = mapmenucells[0].offsetWidth;
   PARAMSONE
       }
       $output .= <<"THIRD";
           if (maxcolw > 0) {
               var newscrollboxw;
               if (maxcolw+paddingw+scrollboxscrollw<boxw) {
                   newscrollboxw = boxw-paddingw-maxcolw;
                   if (newscrollboxw < minscrollboxw) {
                       newscrollboxw = minscrollboxw;
                   }
                   scrollbox.style.width = newscrollboxw+"px";
                   if (newscrollboxw != scrollboxw) {
                       var newitemw = newscrollboxw-offsetw;
                       itemid.style.width = newitemw+"px";
                   }
               } else {
                   newscrollboxw = boxw-paddingw-maxcolw;
                   if (newscrollboxw < minscrollboxw) {
                       newscrollboxw = minscrollboxw;
                   }
                   scrollbox.style.width = newscrollboxw+"px";
                   if (newscrollboxw != scrollboxw) {
                       var newitemw = newscrollboxw-offsetw;
                       itemid.style.width = newitemw+"px";
                   }
               }
   
               if (newscrollboxw != scrollboxw) {
                   var newscrolltablew = newscrollboxw+offsetw;
                   scrolltable.style.width = newscrolltablew+"px";
               }
           }
   
           if (newscrollboxw != scrollboxw) {
               scrollchange = 1;
           }
   
           if (itemid.offsetWidth != itemwstart) {
               listwchange = 1;
           }
       }
       if ((chkh == 1) || (listwchange)) {
           var itemid = document.getElementById("$names{'item'}");
           if (itemid != null) {
               itemh = itemid.offsetHeight;
           }
           var primaryheight = document.getElementById('LC_nav_bar').offsetHeight;
           var secondaryheight;
           if (document.getElementById('LC_secondary_menu') != null) { 
               secondaryheight = document.getElementById('LC_secondary_menu').offsetHeight;
           }
           var crumbsheight = document.getElementById('LC_breadcrumbs').offsetHeight;
           var dccidheight = 0;
           if (document.getElementById('dccid') != null) {
               dccidheight = document.getElementById('dccid').offsetHeight;
           }
           var headerheight = 0;
           if (document.getElementById("$names{'header'}") != null) {
               headerheight = document.getElementById("$names{'header'}").offsetHeight;
           }
           var tabbedheight = document.getElementById("tabbededitor").offsetHeight;
           var boxheight = document.getElementById("$names{'boxh'}").offsetHeight;
           var freevspace = vph-(primaryheight+secondaryheight+crumbsheight+dccidheight+headerheight+tabbedheight+boxheight);
   
           var scrollboxheight = scrollbox.offsetHeight;
           var scrollboxscrollheight = scrollbox.scrollHeight;
           var scrollboxh = scrollboxheight;
   
           var minvscrollbox = $minv;
           var offsetv = $offsetv;
           var newscrollboxheight;
           if (freevspace < 0) {
               newscrollboxheight = scrollboxheight+freevspace-offsetv;
               if (newscrollboxheight < minvscrollbox) {
                   newscrollboxheight = minvscrollbox;
               }
               scrollbox.style.height = newscrollboxheight + "px";
           } else {
               if (scrollboxscrollheight > scrollboxheight) {
                   if (freevspace > offsetv) {
                       newscrollboxheight = scrollboxheight+freevspace-offsetv;
                       if (newscrollboxheight < minvscrollbox) {
                           newscrollboxheight = minvscrollbox;
                       }
                       scrollbox.style.height = newscrollboxheight+"px";
                   }
               }
           }
           scrollboxheight = scrollbox.offsetHeight;
           var itemh = document.getElementById("$names{'item'}").offsetHeight;
   
           if (scrollboxscrollheight <= scrollboxheight) {
               if ((itemh+offsetv)<scrollboxheight) {
                   newscrollheight = itemh+offsetv;
                   scrollbox.style.height = newscrollheight+"px";
               }
           }
           var newscrollboxh = scrollbox.offsetHeight;
           if (scrollboxh != newscrollboxh) {
               scrollchange = 1;
           }
       }
       if (ismobile && scrollchange) {
           \$("#div_$names{'scroll'}").getNiceScroll().onResize();
       }
       return;
   }
   
   function callResize() {
       var timer;
       clearTimeout(timer);
       timer=setTimeout('resize_scrollbox("$names{'scroll'}","1","1")',500);
   }
   
   THIRD
       return $output;
   }
   
   ##############################################
   ##############################################
   
   sub javascript_jumpto_resource {
       my $confirm_switch = &mt("Editing requires switching to the resource's home server.")."\n".
                            &mt('Switch server?');
       &js_escape(\$confirm_switch);
       return (<<ENDUTILITY)
   
   function go(url) {
      if (url!='' && url!= null) {
          currentURL = null;
          currentSymb= null;
          window.location.href=url;
      }
   }
   
   function need_switchserver(url) {
       if (url!='' && url!= null) {
           if (confirm("$confirm_switch")) {
               go(url);
           }
       }
       return;
   }
   
   ENDUTILITY
   
   }
   
   sub jump_to_editres {
       my ($cfile,$home,$switchserver,$forceedit,$forcereg,$symb,$folderpath,
           $title,$idx,$suppurl,$todocs,$suppanchor) = @_;
       my ($jscall,$anchor);
       if ($switchserver) {
           if ($home) {
               $cfile = '/adm/switchserver?otherserver='.$home.'&amp;role='.
                        &HTML::Entities::encode($env{'request.role'},'"<>&');
               if ($symb) {
                   $cfile .= '&amp;symb='.&HTML::Entities::encode($symb,'"<>&');
               } elsif ($folderpath) {
                   $cfile .= '&amp;folderpath='.&HTML::Entities::encode($folderpath,'"<>&');
               }
               if ($forceedit) {
                   $cfile .= '&amp;forceedit=1';
               }
               if ($forcereg) {
                   $cfile .= '&amp;register=1';
               }
               $jscall = "need_switchserver('".&Apache::loncommon::escape_single($cfile)."');";
           }
       } else {
           unless ($cfile =~ m{^/priv/}) {
               if ($cfile =~ m{^(/adm/wrapper/ext/[^#]+)#([^#]+)$}) {
                   $cfile = $1;
                   $anchor = $2;
               }
               if ($symb) {
                   if ($anchor ne '') {
                       if ($symb =~ m{^([^#]+)\Q#$anchor\E$}) {
                           $symb = $1.&escape(&escape('#')).$anchor;
                       }
                   }
                   $cfile .= (($cfile=~/\?/)?'&amp;':'?')."symb=$symb";
               } elsif ($folderpath) {
                   $cfile .= (($cfile=~/\?/)?'&amp;':'?').
                             'folderpath='.&HTML::Entities::encode(&escape($folderpath),'"<>&');
                   if ($title) {
                       $cfile .= (($cfile=~/\?/)?'&amp;':'?').
                                 'title='.&HTML::Entities::encode(&escape($title),'"<>&');
                   }
                   if ($idx) {
                       $cfile .= (($cfile=~/\?/)?'&amp;':'?').'idx='.$idx;
                   }
                   if ($suppurl) {
                       $cfile .= (($cfile=~/\?/)?'&amp;':'?').
                                 'suppurl='.&HTML::Entities::encode(&escape($suppurl));
                   }
               }
               if ($forceedit) {
                   $cfile .= (($cfile=~/\?/)?'&amp;':'?').'forceedit=1';
               }
               if ($forcereg) {
                   $cfile .= (($cfile=~/\?/)?'&amp;':'?').'register=1';
               }
               if ($todocs) {
                   $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)."')";
       }
       return $jscall;
   }
   
   ##############################################
   ##############################################
   
 # javascript_valid_email  # javascript_valid_email
 #  #
 # Generates javascript to validate an e-mail address.  # Generates javascript to validate an e-mail address.
Line 2745  END Line 3533  END
 sub htmltag{  sub htmltag{
     return      return
         qq|<$_[0]|          qq|<$_[0]|
         . join( '', map { qq| $_="${$_[2]}{$_}"| if ${$_[2]}{$_} } keys %{ $_[2] } )          . join( '', map { qq| $_="${$_[2]}{$_}"| if ${$_[2]}{$_} } keys(%{ $_[2] }) )
         . ($_[1] ? qq|>$_[1]</$_[0]>| : qq|/>|). "\n";          . ($_[1] ? qq|>$_[1]</$_[0]>| : qq|/>|). "\n";
 };  };
   
Line 3008  add_item_funclist Line 3796  add_item_funclist
 Inputs: ./.  Inputs: ./.
   
 Returns: HTML code with function list end  Returns: HTML code with function list end
   
 =cut  =cut
   
 sub end_funclist {  sub end_funclist {
Line 3049  sub funclist_from_array { Line 3838  sub funclist_from_array {
                { listattr => {class => 'LC_funclist'} });                 { listattr => {class => 'LC_funclist'} });
 }     }   
   
   =pod
   
   =over
   
   =item &actionbox( \@array )
   
   Constructs a XHTML list from \@array with the first item being visually
   highlighted and set to the value 'Actions'. The list is wrapped in a division.
   
   The actionlist is used to offer contextual actions, mostly at the bottom
   of a page, on which the outcome of an processed action is shown,
   e.g. a file operation in Authoring Space.
   
   =over
   
   =item \@array
   
   A reference to the array containing text. Details: sub funclist_from_array
   
   =back
    
   Returns: XHTML div as string.
   
   =back
   
   =cut  
   
   sub actionbox {
       my ($items) = @_;
       return unless(ref($items) eq 'ARRAY');
       return
           '<div class="LC_actionbox">'
          .&funclist_from_array($items, {legend => &mt('Actions')})
          .'</div>';
   }
   
 1;  1;
   
 __END__  __END__

Removed from v.1.312  
changed lines
  Added in v.1.358.2.13


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