--- loncom/interface/lonhtmlcommon.pm	2006/08/08 19:10:54	1.152
+++ loncom/interface/lonhtmlcommon.pm	2007/11/06 04:39:19	1.169
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common html routines
 #
-# $Id: lonhtmlcommon.pm,v 1.152 2006/08/08 19:10:54 albertel Exp $
+# $Id: lonhtmlcommon.pm,v 1.169 2007/11/06 04:39:19 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -60,7 +60,6 @@ use Time::Local;
 use Time::HiRes;
 use Apache::lonlocal;
 use Apache::lonnet;
-use lib '/home/httpd/lib/perl/';
 use LONCAPA;
 
 ##############################################
@@ -78,7 +77,7 @@ use LONCAPA;
 sub authorbombs {
     my $url=shift;
     $url=&Apache::lonnet::declutter($url);
-    my ($udom,$uname)=($url=~/^(\w+)\/(\w+)\//);
+    my ($udom,$uname)=($url=~m{^($LONCAPA::domain_re)/($LONCAPA::username_re)/});
     my %bombs=&Apache::lonmsg::all_url_author_res_msg($uname,$udom);
     foreach (keys %bombs) {
 	if ($_=~/^$udom\/$uname\//) {
@@ -141,6 +140,7 @@ sub select_recent {
     foreach my $value (sort(keys(%recent))) {
 	unless ($value =~/^error\:/) {
 	    my $escaped = &Apache::loncommon::escape_url($value);
+	    &Apache::loncommon::inhibit_menu_check(\$escaped);
 	    $return.="\n<option value='$escaped'>".
 		&unescape((split(/\&/,$recent{$value}))[1]).
 		'</option>';
@@ -481,6 +481,19 @@ ENDJS
     return $result;
 }
 
+
+sub build_url {
+    my ($base, $fields)=@_;
+    my $url;
+    $url = $base.'?';
+    foreach my $key (keys(%$fields)) {
+        $url.=&escape($key).'='.&escape($$fields{$key}).'&amp;';
+    }
+    $url =~ s/&amp;$//;
+    return $url;
+}
+
+
 ##############################################
 ##############################################
 
@@ -682,7 +695,7 @@ Returns: a perl string as described.
 ##############################################
 ##############################################
 sub StatusOptions {
-    my ($status, $formName,$size,$onchange)=@_;
+    my ($status, $formName,$size,$onchange,$mult)=@_;
     $size = 1 if (!defined($size));
     if (! defined($status)) {
         $status = 'Active';
@@ -691,6 +704,9 @@ sub StatusOptions {
 
     my $Str = '';
     $Str .= '<select name="Status"';
+    if (defined($mult)){
+        $Str .= ' multiple="multiple" ';
+    }
     if(defined($formName) && $formName ne '' && ! defined($onchange)) {
         $Str .= ' onchange="document.'.$formName.'.submit()"';
     }
@@ -699,10 +715,10 @@ sub StatusOptions {
     }
     $Str .= ' size="'.$size.'" ';
     $Str .= '>'."\n";
-    foreach my $type (['Active',  &mt('Currently Enrolled')],
-		      ['Future',  &mt('Future Enrollment')],
-		      ['Expired', &mt('Previously Enrolled')],
-		      ['Any',     &mt('Any Enrollment Status')]) {
+    foreach my $type (['Active',  &mt('Currently Has Access')],
+		      ['Future',  &mt('Will Have Future Access')],
+		      ['Expired', &mt('Previously Had Access')],
+		      ['Any',     &mt('Any Access Status')]) {
 	my ($name,$label) = @$type;
 	$Str .= '<option value="'.$name.'" ';
 	if ($status eq $name) {
@@ -853,7 +869,7 @@ sub Create_PrgWin {
          popwin=open(\'\',\'popwin\',\'width=400,height=100\');".
         "popwin.document.writeln(\'".$start_page.
               "<h4>$heading<\/h4>".
-              "<form name=\"popremain\" method=\"post\">".
+              "<form action= \"\" name=\"popremain\" method=\"post\">".
               '<input type="text" size="'.$width.'" name="remaining" value="'.
 	      &mt('Starting').'" /><\\/form>'.$end_page.
               "\');".
@@ -865,7 +881,7 @@ sub Create_PrgWin {
 	$prog_state{'window'}='window';
 	if (!$formname) {
 	    $prog_state{'formname'}=&get_uniq_name();
-	    &r_print($r,'<form name="'.$prog_state{'formname'}.'">');
+	    &r_print($r,'<form action="" name="'.$prog_state{'formname'}.'">');
 	} else {
 	    $prog_state{'formname'}=$formname;
 	}
@@ -892,7 +908,7 @@ sub Create_PrgWin {
 # update progress
 sub Update_PrgWin {
     my ($r,$prog_state,$displayString)=@_;
-    &r_print($r,'<script>'.$$prog_state{'window'}.'.document.'.
+    &r_print($r,'<script type="text/javascript">'.$$prog_state{'window'}.'.document.'.
 	     $$prog_state{'formname'}.'.'.
 	     $$prog_state{'inputname'}.'.value="'.
 	     $displayString.'";</script>');
@@ -1003,13 +1019,15 @@ sub crumbs {
 		} 
 	    } else {
 		$path.='/'; 
+	    }	    
+            my $href_path = &HTML::Entities::encode($path,'<>&"');
+	    &Apache::loncommon::inhibit_menu_check(\$href_path);
+	    if ($form) {
+	        my $href = 'javascript:'.$form.".action='".$href_path."';".$form.'.submit();';
+	        $output.=qq{<a href="$href" $target>$dir</a>/};
+	    } else {
+	        $output.=qq{<a href="$href_path" $target>$dir</a>/};
 	    }
-            my $linkpath = &Apache::loncommon::escape_single($path);
-            if ($form) {
-		$linkpath=
-                    qq{javascript:$form.action='$linkpath';$form.submit();};
-            }
-	    $output.=qq{<a href="$linkpath" $target>$dir</a>/};
 	}
     } else {
 	foreach my $dir (split('/',$uri)) {
@@ -1046,7 +1064,7 @@ var checkwin;
 function spellcheckerwindow(string) {
     var esc_string = string.replace(/\"/g,'&quot;');
     checkwin=window.open($nothing,'spellcheckwin','height=320,width=280,resizable=yes,scrollbars=yes,location=no,menubar=no,toolbar=no');
-    checkwin.document.writeln('$start_page<form name="spellcheckform" action="/adm/spellcheck" method="post"><input type="hidden" name="text" value="'+esc_string+'" /><\/form>$end_page');
+    checkwin.document.writeln('$start_page<form name="spellcheckform" action="/adm/spellcheck" method="post"><input type="hidden" name="text" value="'+esc_string+'" /><\\/form>$end_page');
     checkwin.document.close();
 }
 // END LON-CAPA Internal -->
@@ -1083,46 +1101,13 @@ ENDLINK
 }
 
 sub htmlareaheaders {
-    if (&htmlareablocked()) { return ''; }
-    unless (&htmlareabrowser()) { return ''; }
-    my $lang='en';
-    if (&mt('htmlarea_lang') ne 'htmlarea_lang') {
-	$lang=&mt('htmlarea_lang');
-    }
+    return if (&htmlareablocked());
+    return if (!&htmlareabrowser());
     return (<<ENDHEADERS);
-<script type="text/javascript">
-_editor_url='/htmlarea/';
-_editor_lang='$lang';
-</script>
-<script type="text/javascript" src="/htmlarea/htmlarea.js"></script>
-<link rel="stylesheet" type="text/css" href="/htmlarea/htmlarea.css" />
+<script type="text/javascript" src="/fckeditor/fckeditor.js"></script>
 ENDHEADERS
 }
 
-# ------------------------------------------------- Activate additional buttons
-
-sub htmlareaaddbuttons {
-    if (&htmlareablocked()) { return ''; }
-    unless (&htmlareabrowser()) { return ''; }
-    return (<<ENDADDBUTTON);
-    var config=new HTMLArea.Config();
-    config.registerButton('ed_math','LaTeX Inline',
-			  '/htmlarea/images/ed_math.gif',false,
-			    function(editor,id) {
-			      editor.surroundHTML('&nbsp;<m>\$','\$</m>&nbsp;');
-			    }
-			  );
-    config.registerButton('ed_math_eqn','LaTeX Equation',
-			  '/htmlarea/images/ed_math_eqn.gif',false,
-			    function(editor,id) {
-			      editor.surroundHTML(
-				     '&nbsp;\\n<center><m>\\\\[','\\\\]</m></center>\\n&nbsp;');
-			    }
-			  );
-    config.toolbar.push(['ed_math','ed_math_eqn']);
-ENDADDBUTTON
-}
-
 # ----------------------------------------------------------------- Preferences
 
 sub disablelink {
@@ -1141,16 +1126,33 @@ sub enablelink {
     return '<a href="'.&HTML::Entities::encode('/adm/preferences?action=set_wysiwyg&wysiwyg=on&returnurl=','<>&"').&escape($ENV{'REQUEST_URI'}).'">'.&mt('Enable WYSIWYG Editor').'</a>';
 }
 
+# ------------------------------------------------- lang to use in html editor
+sub htmlarea_lang {
+    my $lang='en';
+    if (&mt('htmlarea_lang') ne 'htmlarea_lang') {
+	$lang=&mt('htmlarea_lang');
+    }
+    return $lang;
+}
+
 # ----------------------------------------- Script to activate only some fields
 
 sub htmlareaselectactive {
     my @fields=@_;
     unless (&htmlareabrowser()) { return ''; }
     if (&htmlareablocked()) { return '<br />'.&enablelink(@fields); }
-    my $output='<script type="text/javascript" defer="1">'.
-	&htmlareaaddbuttons();
-    foreach(@fields) {
-	$output.="\nHTMLArea.replace('$_',config);";
+    my $output='<script type="text/javascript" defer="1">';
+    my $lang = &htmlarea_lang();
+    foreach my $field (@fields) {
+	$output.="
+{
+    var oFCKeditor = new FCKeditor('$field');
+    oFCKeditor.Config['CustomConfigurationsPath'] = 
+	'/fckeditor/loncapaconfig.js';    
+    oFCKeditor.ReplaceTextarea();
+    oFCKeditor.Config['AutoDetectLanguage'] = false;
+    oFCKeditor.Config['DefaultLanguage'] = '$lang';
+}";
     }
     $output.="\nwindow.status='Activated Editfields';\n</script><br />".
 	&disablelink(@fields);
@@ -1203,7 +1205,8 @@ Pushes a breadcrumb on the stack of crum
 
 input: $breadcrumb, a hash reference.  The keys 'href','title', and 'text'
 are required.  If present the keys 'faq' and 'bug' will be used to provide
-links to the FAQ and bug sites.
+links to the FAQ and bug sites. If the key 'no_mt' is present the 'title' 
+and 'text' values won't be sent through &mt()
 
 returns: nothing    
 
@@ -1253,13 +1256,22 @@ returns: nothing
                      if (defined($_->{'target'}) && $_->{'target'} ne '') {
                          $result .= 'target="'.$_->{'target'}.'" ';
                      }
-                     $result .='title="'.&mt($_->{'title'}).'">'.
-                         &mt($_->{'text'}).'</a>';
+		     if ($_->{'no_mt'}) {
+			 $result .='title="'.$_->{'title'}.'">'.
+			     $_->{'text'}.'</a>';
+		     } else {
+			 $result .='title="'.&mt($_->{'title'}).'">'.
+			     &mt($_->{'text'}).'</a>';
+		     }
                      $result;
                      } @Crumbs
                  );
         $links .= '-&gt;' if ($links ne '');
-        $links .= '<b>'.&mt($last->{'text'}).'</b>';
+	if ($last->{'no_mt'}) {
+	    $links .= '<b>'.$last->{'text'}.'</b>';
+	} else {
+	    $links .= '<b>'.&mt($last->{'text'}).'</b>';
+	}
         #
         my $icons = '';
         $faq = $last->{'faq'} if (exists($last->{'faq'}));
@@ -1322,7 +1334,7 @@ returns: nothing
 # row2
 # row3   ... etc.
 # &submit_row(0
-# &end_pickbox()
+# &end_pick_box()
 #
 # where row1, row 2 etc. are chosen from &role_select_row,&course_select_row,
 # &status_select_row and &email_default_row
@@ -1461,7 +1473,14 @@ sub course_select_row {
     my ($title,$formname,$totcodes,$codetitles,$idlist,$idlist_titles,
 	$css_class) = @_;
     my $output = &row_title($title,$css_class);
-    $output .= qq|
+    $output .= &course_selection($formname,$totcodes,$codetitles,$idlist,$idlist_titles);
+    $output .= &row_closure();
+    return $output;
+}
+
+sub course_selection {
+    my ($formname,$totcodes,$codetitles,$idlist,$idlist_titles) = @_;
+    my $output = qq|
 <script type="text/javascript">
     function coursePick (formname) {
         for  (var i=0; i<formname.coursepick.length; i++) {
@@ -1534,8 +1553,7 @@ sub course_select_row {
             $output .= '</tr></table><br />';
         }
     }
-    $output .= '<input type="radio" name="coursepick" value="specific" onclick="coursePick(this.form);opencrsbrowser('."'".$formname."'".','."'".'dccourse'."'".','."'".'dcdomain'."'".','."'".'coursedesc'."','','1'".')" />'.&mt('Pick specific course(s):').' '.$courseform.'&nbsp;&nbsp;<input type="text" value="0" size="4" name="coursetotal" /><input type="hidden" name="courselist" value="" />selected.<br />'."\n";
-    $output .= &row_closure();
+    $output .= '<input type="radio" name="coursepick" value="specific" onclick="coursePick(this.form);opencrsbrowser('."'".$formname."','dccourse','dcdomain','coursedesc','','1'".')" />'.&mt('Pick specific course(s):').' '.$courseform.'&nbsp;&nbsp;<input type="text" value="0" size="4" name="coursetotal" /><input type="hidden" name="courselist" value="" />selected.<br />'."\n";
     return $output;
 }
 
@@ -1560,7 +1578,6 @@ sub status_select_row {
 sub email_default_row {
     my ($authtypes,$title,$descrip,$css_class) = @_;
     my $output = &row_title($title,$css_class);
-    my @rowcols = ('#eeeeee','#dddddd');
     $output .= $descrip.
 	&Apache::loncommon::start_data_table().
 	&Apache::loncommon::start_data_table_header_row().
@@ -1831,6 +1848,43 @@ sub set_form_elements {
     return $output;
 }
 
+##############################################
+##############################################
+
+# javascript_valid_email
+#
+# Generates javascript to validate an e-mail address.
+# Returns a javascript function which accetps a form field as argumnent, and
+# returns false if field.value does not satisfy two regular expression matches
+# 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). 
+
+sub javascript_valid_email {
+    my $scripttag .= <<'END';
+function validmail(field) {
+    var str = field.value;
+    if (window.RegExp) {
+        var reg1str = "(@.*@)|(\\.\\.)|(@\\.)|(\\.@)|(^\\.)";
+        var reg2str = "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$"; //"
+        var reg1 = new RegExp(reg1str);
+        var reg2 = new RegExp(reg2str);
+        if (!reg1.test(str) && reg2.test(str)) {
+            return true;
+        }
+        return false;
+    }
+    else
+    {
+        if(str.indexOf("@") >= 0) {
+            return true;
+        }
+        return false;
+    }
+}
+END
+    return $scripttag;
+}
+
 1;
 
 __END__