--- loncom/interface/lonhtmlcommon.pm 2004/06/04 16:05:47 1.74 +++ loncom/interface/lonhtmlcommon.pm 2013/07/22 11:46:23 1.352 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common html routines # -# $Id: lonhtmlcommon.pm,v 1.74 2004/06/04 16:05:47 www Exp $ +# $Id: lonhtmlcommon.pm,v 1.352 2013/07/22 11:46:23 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -55,17 +55,198 @@ html. package Apache::lonhtmlcommon; +use strict; use Time::Local; use Time::HiRes; use Apache::lonlocal; -use strict; +use Apache::lonnet; +use HTML::Entities(); +use LONCAPA qw(:DEFAULT :match); + +sub java_not_enabled { + if (($env{'browser.mobile'}) && ($env{'browser.mobile'} =~ /^ipad|ipod|iphone$/i)) { + return "\n".''. + &mt('The required Java applet could not be started, because Java is not supported by your mobile device.'). + "\n"; + } else { + return "\n".''. + &mt('The required Java applet could not be started. Please make sure to have Java installed and active in your browser.'). + "\n"; + } +} + +sub coursepreflink { + my ($text,$category)=@_; + if (&Apache::lonnet::allowed('opa',$env{'request.course.id'})) { + return '&"').'">'.$text.''; + } else { + return ''; + } +} + +sub raw_href_to_link { + my ($message)=@_; + $message=~s/(https?\:\/\/[^\s\'\"\<]+)([\s\<]|$)/$1<\/tt><\/a>$2/gi; + return $message; +} + +sub entity_encode { + my ($text)=@_; + return &HTML::Entities::encode($text, '<>&"'); +} + +sub direct_parm_link { + my ($linktext,$symb,$filter,$part,$target)=@_; + $symb=&entity_encode($symb); + $filter=&entity_encode($filter); + $part=&entity_encode($part); + if (($symb) && (&Apache::lonnet::allowed('opa')) && ($target ne 'tex')) { + return "$linktext"; + } else { + return $linktext; + } +} +############################################## +############################################## + +=item &confirm_success() + +Successful completion of an operation message + +=cut + +sub confirm_success { + my ($message,$failure)=@_; + if ($failure) { + return ''."\n" + .''.&mt('Error').' '."\n" + .$message."\n" + .''."\n"; + } else { + return ''."\n" + .''.&mt('OK').' '."\n" + .$message."\n" + .''."\n"; + } +} + +############################################## +############################################## + +=pod + +=item &dragmath_button() + +Creates a button that launches a dragmath popup-window, in which an +expression can be edited and pasted as LaTeX into a specified textarea. + + textarea - Name of the textarea to edit. + helpicon - If true, show a help icon to the right of the button. + +=cut + +sub dragmath_button { + my ($textarea,$helpicon) = @_; + my $help_text; + if ($helpicon) { + $help_text = &Apache::loncommon::help_open_topic('Authoring_Math_Editor',undef,undef,undef,undef,'mathhelpicon_'.$textarea); + } + my $buttontext=&mt('Edit Math'); + return <$help_text +ENDDRAGMATH +} + +############################################## + +=pod + +=item &dragmath_js() + +Javascript used to open pop-up window containing dragmath applet which +can be used to paste LaTeX into a textarea. + +=cut + +sub dragmath_js { + my ($popup) = @_; + return < + // + + +ENDDRAGMATHJS +} + +############################################## +############################################## + +=pod + +=item &dependencies_button() + +Creates a button that launches a popup-window, in which dependencies +for the web page in the main window can be added to, replaced or deleted. + +=cut + +sub dependencies_button { + my $buttontext=&mt('Manage Dependencies'); + return <<"END"; + +END +} + +############################################## + +=pod + +=item &dependencycheck_js() + +Javascript used to open pop-up window containing interface to manage +dependencies for a web page uploaded diretcly to a course. + +=cut + +sub dependencycheck_js { + my ($symb,$title,$url,$folderpath,$uri) = @_; + my $link; + 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=~/\?/)?'&':'?').'title='. + &HTML::Entities::encode($title,'<>&"'); + if ($url) { + $link .= '&url='.&HTML::Entities::encode($url,'<>&"'); + } + return < + // + +ENDJS +} ############################################## ############################################## =pod -=item authorbombs +=item &authorbombs() =cut @@ -75,12 +256,12 @@ use strict; 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\//) { + foreach my $bomb (keys(%bombs)) { + if ($bomb =~ /^$udom\/$uname\//) { return ''. + '">'.&mt('Bomb').''. &Apache::loncommon::help_open_topic('About_Bombs'); } } @@ -92,41 +273,58 @@ sub authorbombs { sub recent_filename { my $area=shift; - return 'nohist_recent_'.&Apache::lonnet::escape($area); + return 'nohist_recent_'.&escape($area); } sub store_recent { - my ($area,$name,$value)=@_; + my ($area,$name,$value,$freeze)=@_; my $file=&recent_filename($area); my %recent=&Apache::lonnet::dump($file); - if (scalar(keys(%recent))>10) { + if (scalar(keys(%recent))>20) { # remove oldest value - my $oldest=time; + my $oldest=time(); my $delkey=''; - foreach (keys %recent) { - my $thistime=(split(/\&/,$recent{$_}))[0]; - if ($thistime<$oldest) { + foreach my $item (keys(%recent)) { + my $thistime=(split(/\&/,$recent{$item}))[0]; + if (($thistime ne "always_include") && ($thistime<$oldest)) { $oldest=$thistime; - $delkey=$_; + $delkey=$item; } } &Apache::lonnet::del($file,[$delkey]); } # store new value + my $timestamp; + if ($freeze) { + $timestamp = "always_include"; + } else { + $timestamp = time(); + } &Apache::lonnet::put($file,{ $name => - time.'&'.&Apache::lonnet::escape($value) }); + $timestamp.'&'.&escape($value) }); +} + +sub remove_recent { + my ($area,$names)=@_; + my $file=&recent_filename($area); + return &Apache::lonnet::del($file,$names); } sub select_recent { my ($area,$fieldname,$event)=@_; my %recent=&Apache::lonnet::dump(&recent_filename($area)); my $return="\n'; return $Str; @@ -156,7 +400,7 @@ sub textbox { =pod -=item checkbox +=item &checkbox() =cut @@ -169,7 +413,29 @@ sub checkbox { $Str .= 'value="'.$value.'"'; } if ($checked) { - $Str .= ' checked="1"'; + $Str .= ' checked="checked"'; + } + $Str .= ' />'; + return $Str; +} + + +=pod + +=item &radiobutton() + +=cut + +############################################## +############################################## +sub radio { + my ($name,$checked,$value) = @_; + my $Str = ' + ENDJS - $result .= " }; # Month my @Months = qw/January February March April May June July August September October November December/; # Pad @Months with a bogus value to make indexing easier unshift(@Months,'If you can read this an error occurred'); - if ($includeempty) { $result.=""; } + if ($includeempty) { $monthselector.=""; } for(my $m = 1;$m <=$#Months;$m++) { - $result .= " \n\n"; + # + my $tzone = ' '.$tzname.' '; + if ($no_hh_mm_ss) { + $result .= &mt('[_1] [_2] [_3] ', + $monthselector,$dayselector,$yearselector). + $tzone; + if (!$nolink) { + $result .= &mt('[_1]Select Date[_2]',$cal_link,''); + } + } else { + $result .= &mt('[_1] [_2] [_3] [_4] [_5]m [_6]s ', + $monthselector,$dayselector,$yearselector, + $hourselector,$minuteselector,$secondselector). + $tzone; + if (!$nolink) { + $result .= &mt('[_1]Select Date[_2]',$cal_link,''); + } + } + $result .= "\n\n"; return $result; } +sub get_timedates { + my ($epoch) = @_; + my $dt = DateTime->from_epoch(epoch => $epoch) + ->set_time_zone(&Apache::lonlocal::gettimezone()); + my $tzname = $dt->time_zone_short_name(); + my $sec = $dt->second; + my $min = $dt->minute; + my $hour = $dt->hour; + my $mday = $dt->day; + my $month = $dt->month; + if ($month) { + $month --; + } + my $year = $dt->year; + return ($tzname,$sec,$min,$hour,$mday,$month,$year); +} + +sub build_url { + my ($base, $fields)=@_; + my $url; + $url = $base.'?'; + foreach my $key (keys(%$fields)) { + $url.=&escape($key).'='.&escape($$fields{$key}).'&'; + } + $url =~ s/&$//; + return $url; +} + + ############################################## ############################################## =pod -=item &get_date_from_form +=item &get_date_from_form() get_date_from_form retrieves the date specified in an &date_setter form. @@ -388,7 +709,7 @@ Inputs: =item $dname -The name passed to &datesetter, which prefixes the form elements. +The name passed to &date_setter, which prefixes the form elements. =item $defaulttime @@ -406,8 +727,8 @@ sub get_date_from_form { my ($dname) = @_; my ($sec,$min,$hour,$day,$month,$year); # - if (defined($ENV{'form.'.$dname.'_second'})) { - my $tmpsec = $ENV{'form.'.$dname.'_second'}; + if (defined($env{'form.'.$dname.'_second'})) { + my $tmpsec = $env{'form.'.$dname.'_second'}; if (($tmpsec =~ /^\d+$/) && ($tmpsec >= 0) && ($tmpsec < 60)) { $sec = $tmpsec; } @@ -415,8 +736,8 @@ sub get_date_from_form { } else { $sec = 0; } - if (defined($ENV{'form.'.$dname.'_minute'})) { - my $tmpmin = $ENV{'form.'.$dname.'_minute'}; + if (defined($env{'form.'.$dname.'_minute'})) { + my $tmpmin = $env{'form.'.$dname.'_minute'}; if (($tmpmin =~ /^\d+$/) && ($tmpmin >= 0) && ($tmpmin < 60)) { $min = $tmpmin; } @@ -424,37 +745,50 @@ sub get_date_from_form { } else { $min = 0; } - if (defined($ENV{'form.'.$dname.'_hour'})) { - my $tmphour = $ENV{'form.'.$dname.'_hour'}; + if (defined($env{'form.'.$dname.'_hour'})) { + my $tmphour = $env{'form.'.$dname.'_hour'}; if (($tmphour =~ /^\d+$/) && ($tmphour >= 0) && ($tmphour < 24)) { $hour = $tmphour; } } else { $hour = 0; } - if (defined($ENV{'form.'.$dname.'_day'})) { - my $tmpday = $ENV{'form.'.$dname.'_day'}; + if (defined($env{'form.'.$dname.'_day'})) { + my $tmpday = $env{'form.'.$dname.'_day'}; if (($tmpday =~ /^\d+$/) && ($tmpday > 0) && ($tmpday < 32)) { $day = $tmpday; } } - if (defined($ENV{'form.'.$dname.'_month'})) { - my $tmpmonth = $ENV{'form.'.$dname.'_month'}; + if (defined($env{'form.'.$dname.'_month'})) { + my $tmpmonth = $env{'form.'.$dname.'_month'}; if (($tmpmonth =~ /^\d+$/) && ($tmpmonth > 0) && ($tmpmonth < 13)) { - $month = $tmpmonth - 1; + $month = $tmpmonth; } } - if (defined($ENV{'form.'.$dname.'_year'})) { - my $tmpyear = $ENV{'form.'.$dname.'_year'}; - if (($tmpyear =~ /^\d+$/) && ($tmpyear > 1900)) { - $year = $tmpyear - 1900; + if (defined($env{'form.'.$dname.'_year'})) { + my $tmpyear = $env{'form.'.$dname.'_year'}; + if (($tmpyear =~ /^\d+$/) && ($tmpyear >= 1970)) { + $year = $tmpyear; } } - if (($year<70) || ($year>137)) { return undef; } + if (($year<1970) || ($year>2037)) { return undef; } if (defined($sec) && defined($min) && defined($hour) && - defined($day) && defined($month) && defined($year) && - eval(&timelocal($sec,$min,$hour,$day,$month,$year))) { - return &timelocal($sec,$min,$hour,$day,$month,$year); + defined($day) && defined($month) && defined($year)) { + my $timezone = &Apache::lonlocal::gettimezone(); + my $dt = DateTime->new( year => $year, + month => $month, + day => $day, + hour => $hour, + minute => $min, + second => $sec, + time_zone => $timezone, + ); + my $epoch_time = $dt->epoch; + if ($epoch_time ne '') { + return $epoch_time; + } else { + return undef; + } } else { return undef; } @@ -476,12 +810,13 @@ parameter setting wizard. ############################################## sub pjump_javascript_definition { my $Str = <'. - &mt('Currently Enrolled').''."\n"; - $Str .= ''."\n"; - $Str .= ''."\n"; + 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 .= '