--- loncom/interface/lonhtmlcommon.pm 2012/04/16 19:24:59 1.309 +++ loncom/interface/lonhtmlcommon.pm 2016/04/02 04:30:20 1.371 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common html routines # -# $Id: lonhtmlcommon.pm,v 1.309 2012/04/16 19:24:59 raeburn Exp $ +# $Id: lonhtmlcommon.pm,v 1.371 2016/04/02 04:30:20 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -61,12 +61,18 @@ use Time::HiRes; use Apache::lonlocal; use Apache::lonnet; use HTML::Entities(); -use LONCAPA; +use LONCAPA qw(:DEFAULT :match); sub java_not_enabled { - return "\n".''. - &mt('The required Java applet could not be started. Please make sure to have Java installed and active in your browser.'). - "\n"; + 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 { @@ -95,7 +101,7 @@ sub direct_parm_link { $filter=&entity_encode($filter); $part=&entity_encode($part); if (($symb) && (&Apache::lonnet::allowed('opa')) && ($target ne 'tex')) { - return "$linktext"; + return "$linktext"; } else { return $linktext; } @@ -170,7 +176,7 @@ sub dragmath_js { function mathedit(textarea, doc) { targetEntry = textarea; 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"); } // ]]> @@ -209,9 +215,21 @@ dependencies for a web page uploaded dir =cut sub dependencycheck_js { - my ($symb,$title) = @_; - my $link = '/adm/dependencies?symb='.&HTML::Entities::encode($symb,'<>&"'). - '&title='.&HTML::Entities::encode($title,'<>&"'); + 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 < // }; my $secondselector= qq{}; my $cal_link; - if (!$nolink) { + unless (($nolink) || ($state eq 'disabled')) { $cal_link = qq{}; } # @@ -631,17 +682,26 @@ ENDJS $result .= &mt('[_1] [_2] [_3] ', $monthselector,$dayselector,$yearselector). $tzone; - if (!$nolink) { - $result .= &mt('[_1]Select Date[_2]',$cal_link,''); - } + } elsif ($no_mm_ss) { + $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 { $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,''); - } + } + unless (($nolink) || ($state eq 'disabled')) { + $result .= &mt('[_1]Select Date[_2]',$cal_link,''); } $result .= "\n\n"; return $result; @@ -685,7 +745,9 @@ sub build_url { get_date_from_form retrieves the date specified in an &date_setter form. -Inputs: +=over + +=item Inputs: =over 4 @@ -699,6 +761,8 @@ The unix time to use as the default in c =back +=back + Returns: Unix time represented in the form. =cut @@ -870,7 +934,9 @@ sub javascript_docopen { Returns html for a selection box which allows the user to choose the enrollment status of students. The selection box name is 'Status'. -Inputs: +=over + +=item Inputs: $status: the currently selected status. If undefined the value of $env{'form.Status'} is taken. If that is undefined, a value of 'Active' @@ -884,6 +950,8 @@ $size: the size (number of lines) of the $onchange: javascript to use when the value is changed. Enclosed in double quotes, ""s, not single quotes. +=back + Returns: a perl string as described. =cut @@ -931,7 +999,7 @@ sub StatusOptions { =pod -=item Progess Window Handling Routines +=item Progress Window Handling Routines These routines handle the creation, update, increment, and closure of progress windows. The progress window reports to the user the number @@ -945,38 +1013,30 @@ of items completed and an estimate of th Writes javascript to the client to open a progress window and returns a data structure used for bookkeeping. -Inputs - -=over 4 +=over -=item $r Apache request +=item Inputs -=item $title The title of the progress window +=over -=item $heading A description (usually 1 line) of the process being initiated. +=item $r Apache request =item $number_to_do The total number of items being processed. -=item $type Either 'popup' or 'inline' (popup is assumed if nothing is - specified) - -=item $width Specify the width in charaters of the input field. - -=item $formname Only useful in the inline case, if a form already exists, this needs to be used and specfiy the name of the form, otherwise the Progress line will be created in a new form of it's own - -=item $inputname Only useful in the inline case, if a form and an input of type text exists, use this to specify the name of the input field +=back =back Returns a hash containing the progress state data structure. - =item &Update_PrgWin() Updates the text in the progress indicator. Does not increment the count. See &Increment_PrgWin. -Inputs: +=over + +=item Inputs: =over 4 @@ -988,25 +1048,38 @@ Inputs: =back +=back + Returns: none -=item Increment_PrgWin() +=item &Increment_PrgWin() Increment the count of items completed for the progress window by $step or 1 if no step is provided. -Inputs: +=over + +=item Inputs: =over 4 -=item $r Apache request +=item $r -=item $prog_state Pointer to the data structure returned by Create_PrgWin +Apache request + +=item $prog_state -=item $extraInfo A description of the items being iterated over. Typically -'student'. +Pointer to the data structure returned by Create_PrgWin -=item $step (optional) counter step. Will be set to default 1 if ommited. step must be greater than 0 or empty. +=item $extraInfo + +A description of the items being iterated over. Typically 'student'. + +=item $step + +(optional) counter step. Will be set to default 1 if ommited. step must be greater than 0 or empty. + +=back =back @@ -1017,7 +1090,9 @@ Returns: none Closes the progress window. -Inputs: +=over + +=item Inputs: =over 4 @@ -1027,6 +1102,8 @@ Inputs: =back +=back + Returns: none =back @@ -1113,6 +1190,7 @@ sub Close_PrgWin { undef(%$prog_state); } + # ------------------------------------------------------- Puts directory header sub crumbs { @@ -1215,14 +1293,19 @@ sub htmlareaheaders { ENDEDITOR } $s.=(< - - + + + - - + + + + + + + ENDJQUERY return $s; } @@ -1238,13 +1321,25 @@ sub htmlarea_lang { return $lang; } +# return javacsript to activate elements of .colorchooser with jpicker: +# Caller is responsible for enclosing this in '; return $output; @@ -1458,8 +1702,10 @@ sub show_return_link { unless ($env{'request.course.id'}) { return 0; } 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'); + return if (($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement') && + (!$env{'request.role.adv'})); if (($env{'request.noversionuri'} =~ m{^/adm/(viewclasslist|navmaps)($|\?)}) || ($env{'request.noversionuri'} =~ m{^/adm/.*/aboutme($|\?)})) { @@ -1473,7 +1719,7 @@ sub show_return_link { (($env{'request.noversionuri'}=~/^\/adm\//) && ($env{'request.noversionuri'}!~/^\/adm\/wrapper\//) && ($env{'request.noversionuri'}!~ - m{^/adm/.*/(smppg|bulletinboard)($|\?)}) + m{^/adm/.*/(smppg|bulletinboard|exttools?)($|\?)}) )); } @@ -1497,8 +1743,9 @@ sub set_due_date { # The code should correct for gross differences between the server # and client's time setting - my $js = " - -"; - return $js; +END } ## # Sets the time at which the problem finished computing. @@ -1521,17 +1767,16 @@ var dueDate = new Date(serverDueDa sub set_compute_end_time { my $now = time()*1000; # Javascript times are in ms. - my $js = " - -"; - return $js; - +END } ############################################################ @@ -1548,13 +1793,55 @@ A link to help for the component will be All inputs can be undef without problems. -Inputs: $component (the text on the right side of the breadcrumbs trail), - $component_help - $menulink (boolean, controls whether to include a link to /adm/menu) - $helplink (if 'nohelp' don't include the orange help link) - $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 - when including the text on the right. +=over + +=item Inputs: + +=over + +=item $component + +the text on the right side of the breadcrumbs trail + +=item $component_help + +the help item filename (without .tex extension). + +=item $menulink + +boolean, controls whether to include a link to /adm/menu + +=item $helplink + +if 'nohelp' don't include the orange help link + +=item $css_class + +optional name for the class to apply to the table for CSS + +=item $no_mt + +optional flag, 1 if &mt() is _not_ to be applied to $component when including the text on the right + +=item $CourseBreadcrumbs + +optional flag, 1 if &breadcrumbs called from &docs_breadcrumbs, because breadcrumbs are being +used to display hierarchy for current folder shown in the Course Editor. + +=item $topic_help + +optional help item to be displayed on right side of the breadcrumbs row, using +loncommon::help_open_topic() to generate the link. + +=item $topic_help_text + +text to include in the link in the optional help item ($topic_help) on the right +side of the breadcrumbs row. + +=back + +=back + Returns a string containing breadcrumbs for the current page. =item &clear_breadcrumbs() @@ -1581,7 +1868,8 @@ returns: nothing my %tools = (); 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,$crstype) = @_; # $css_class ||= 'LC_breadcrumbs'; @@ -1596,6 +1884,11 @@ returns: nothing # # The first one should be the course or a menu link if (!defined($menulink)) { $menulink=1; } + if ((($crstype eq 'Placement') || (($env{'request.course.id'}) && + ($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement'))) && + (!$env{'request.role.adv'})) { + undef($menulink); + } if ($menulink) { my $description = 'Menu'; my $no_mt_descr = 0; @@ -1605,6 +1898,14 @@ returns: nothing $description = $env{'course.'.$env{'request.course.id'}.'.description'}; $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', title =>'Go to main menu', @@ -1620,11 +1921,17 @@ returns: nothing } } my $links; - if ((&show_return_link) && (!$CourseBreadcrumbs)) { + if ((&show_return_link) && (!$CourseBreadcrumbs) && (ref($last) eq 'HASH')) { my $alttext = &mt('Go Back'); - $links=&htmltag( 'a',"$alttext", - { href => '/adm/flip?postdata=return:', - title => &mt("Back to most recent content resource") }); + my $hashref = { href => '/adm/flip?postdata=return:', + 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',''.$alttext.'', + $hashref); $links=&htmltag('li',$links); } $links.= join "", @@ -1653,10 +1960,10 @@ returns: nothing # last breadcrumb is the first order heading of a page # for course breadcrumbs it's just bold - $links .= &htmltag( 'li', htmltag($CourseBreadcrumbs ? 'b' : 'h1', - $lasttext), {title => $lasttext}); - - $links .= '
  • '; + if ($lasttext ne '') { + $links .= &htmltag( 'li', htmltag($CourseBreadcrumbs ? 'b' : 'h1', + $lasttext), {title => $lasttext}); + } my $icons = ''; $faq = $last->{'faq'} if (exists($last->{'faq'})); @@ -1674,18 +1981,23 @@ returns: nothing $component_help, $faq,$bug); } + if ($topic_help && $topic_help_text) { + $icons .= ' '.&Apache::loncommon::help_open_topic($topic_help,&mt($topic_help_text),'', + undef,600); + } # - - unless ($CourseBreadcrumbs) { - $links = &htmltag('ol', $links, { id => "LC_MenuBreadcrumbs" }); - } else { - $links = &htmltag('ul', $links, { class => "LC_CourseBreadcrumbs" }); + if ($links ne '') { + unless ($CourseBreadcrumbs) { + $links = &htmltag('ol', $links, { id => "LC_MenuBreadcrumbs" }); + } else { + $links = &htmltag('ul', $links, { class => "LC_CourseBreadcrumbs" }); + } } - if ($component) { + if (($component) || ($topic_help && $topic_help_text)) { $links = &htmltag('span', ( $no_mt ? $component : mt($component) ). ( $icons ? $icons : '' ), @@ -1693,11 +2005,24 @@ returns: nothing .$links ; } - - &render_tools(\$links); - $links = &htmltag('div', $links, - { id => "LC_breadcrumbs" }) unless ($CourseBreadcrumbs) ; - &render_advtools(\$links); + my $nav_and_tools = 0; + foreach my $item ('navigation','tools') { + if (ref($tools{$item}) eq 'ARRAY') { + $nav_and_tools += scalar(@{$tools{$item}}) + } + } + 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 push(@Crumbs,$last); @@ -1727,7 +2052,9 @@ Adds $html to $category of the breadcrum $html is usually a link to a page that invokes a function on the currently displayed data (e.g. print when viewing a problem) -Currently there are 3 possible values for $category: +=over + +=item Currently there are 3 possible values for $category: =over @@ -1735,13 +2062,15 @@ Currently there are 3 possible values fo left of breadcrumbs line =item tools -right of breadcrumbs line +remaining items in right of breadcrumbs line =item advtools advanced tools shown in a separate box below breadcrumbs line =back - + +=back + returns: nothing =cut @@ -1775,13 +2104,32 @@ returns: nothing undef(%tools); } +=item ¤t_breadcrumb_tools() + +returns: a hash containing the current breadcrumb tools. + +=cut + + sub current_breadcrumb_tools { + return %tools; + } + =item &render_tools(\$breadcrumbs) Creates html for breadcrumb tools (categories navigation and tools) and inserts \$breadcrumbs at the correct position. -input: \$breadcrumbs - a reference to the string containing prepared -breadcrumbs. +=over + +=item input: + +=over + +=item \$breadcrumbs - a reference to the string containing prepared breadcrumbs. + +=back + +=back returns: nothing @@ -1807,8 +2155,17 @@ returns: nothing Creates html for advanced tools (category advtools) and inserts \$breadcrumbs at the correct position. -input: \$breadcrumbs - a reference to the string containing prepared -breadcrumbs (after render_tools call). +=over + +=item input: + +=over + +=item \$breadcrumbs - a reference to the string containing prepared breadcrumbs (after render_tools call). + +=back + +=back returns: nothing @@ -1825,6 +2182,87 @@ returns: nothing } # 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.' > '; + } + 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/\>\;\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; + } +} + ############################################################ ############################################################ @@ -1885,15 +2323,19 @@ returns: nothing my @row_count; sub start_pick_box { - my ($css_class) = @_; + my ($css_class,$id) = @_; if (defined($css_class)) { $css_class = 'class="'.$css_class.'"'; } else { $css_class= 'class="LC_pick_box"'; } + my $table_id; + if (defined($id)) { + $table_id = ' id="'.$id.'"'; + } unshift(@row_count,0); my $output = <<"END"; - +
    END return $output; } @@ -2048,14 +2490,14 @@ sub course_selection { my $courseform=''.&Apache::loncommon::selectcourse_link ($formname,'pickcourse','pickdomain','coursedesc','',1,$crstype).''; - $output .= ''.$allcrs.'
    '; + $output .= '
    '; if ($totcodes > 0) { my $numtitles = @$codetitles; if ($numtitles > 0) { - $output .= ''.&mt('Pick courses by category:').'
    '; + $output .= '
    '; $output .= '
    '; @@ -2093,7 +2535,15 @@ sub course_selection { $output .= '
    '.$$codetitles[0].'
    '."\n". '
    '.$$codetitles[$i].'
    '."\n". ''."\n". '

    '; } } - $output .= ''.$pickspec.' '.$courseform.'  selected.
    '."\n"; + $output .= + '' + .' '.$courseform.'  ' + .&mt('[_1] selected.', + '' + .'') + .'
    '."\n"; return $output; } @@ -2214,6 +2664,49 @@ sub resource_info_box { 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) = @_; + my $usage = $current_disk_usage/1000; + my $quota = $disk_quota/1000; + 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; + } + return ' +
    '.&mt('Currently using [_1] of the [_2] available.',$usage.' MB ('.$percent.'%)',$quota.' MB')."\n". +'
    '."\n". +'
    '."\n". +'
    '."\n". +'
    '; +} + ############################################## ############################################## @@ -2225,15 +2718,19 @@ sub resource_info_box { # 1. number to display. # If input for number is empty only the title will be displayed. # 2. title text to display. +# 3. optional id for the
    # Outputs - a scalar containing html mark-up for the div. sub topic_bar { - my ($num,$title) = @_; + my ($num,$title,$id) = @_; my $number = ''; if ($num ne '') { $number = ''.$num.''; } - return '
    '.$number.$title.'
    '; + if ($id ne '') { + $id = 'id="'.$id.'"'; + } + return '
    '.$number.$title.'
    '; } ############################################## @@ -2454,10 +2951,12 @@ sub set_form_elements { sub file_submissionchk_js { 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)?'); - 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?'); + &js_escape(\$delfilewarn); my ($turninpathtext,$multtext,$arrayindexofjs); if (ref($turninpaths) eq 'HASH') { foreach my $key (sort(keys(%{$turninpaths}))) { @@ -2697,6 +3196,355 @@ 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 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 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)&'); + if ($symb) { + $cfile .= '&symb='.&HTML::Entities::encode($symb,'"<>&'); + } elsif ($folderpath) { + $cfile .= '&folderpath='.&HTML::Entities::encode($folderpath,'"<>&'); + } + if ($forceedit) { + $cfile .= '&forceedit=1'; + } + if ($forcereg) { + $cfile .= '&register=1'; + } + $jscall = "need_switchserver('".&Apache::loncommon::escape_single($cfile)."');"; + } + } else { + unless ($cfile =~ m{^/priv/}) { + if ($symb) { + $cfile .= (($cfile=~/\?/)?'&':'?')."symb=$symb"; + } elsif ($folderpath) { + $cfile .= (($cfile=~/\?/)?'&':'?'). + 'folderpath='.&HTML::Entities::encode(&escape($folderpath),'"<>&'); + if ($title) { + $cfile .= (($cfile=~/\?/)?'&':'?'). + 'title='.&HTML::Entities::encode(&escape($title),'"<>&'); + } + if ($idx) { + $cfile .= (($cfile=~/\?/)?'&':'?').'idx='.$idx; + } + if ($suppurl) { + $cfile .= (($cfile=~/\?/)?'&':'?'). + 'suppurl='.&HTML::Entities::encode(&escape($suppurl)); + } + } + if ($forceedit) { + $cfile .= (($cfile=~/\?/)?'&':'?').'forceedit=1'; + } + if ($forcereg) { + $cfile .= (($cfile=~/\?/)?'&':'?').'register=1'; + } + if ($todocs) { + $cfile .= (($cfile=~/\?/)?'&':'?').'todocs=1'; + } + } + $jscall = "go('".&Apache::loncommon::escape_single($cfile)."')"; + } + return $jscall; +} + +############################################## +############################################## + # javascript_valid_email # # Generates javascript to validate an e-mail address. @@ -2756,7 +3604,7 @@ END sub htmltag{ return qq|<$_[0]| - . join( '', map { qq| $_="${$_[2]}{$_}"| if ${$_[2]}{$_} } keys %{ $_[2] } ) + . join( '', map { qq| $_="${$_[2]}{$_}"| if ${$_[2]}{$_} } keys(%{ $_[2] }) ) . ($_[1] ? qq|>$_[1]| : qq|/>|). "\n"; }; @@ -2818,7 +3666,9 @@ sub scripttag { Constructs a XHTML list from \@array. -input: +=over + +=item input: =over @@ -2832,7 +3682,9 @@ Attributes for
      and
    • passed in a See htmltag() for more details. =back - + +=back + returns: XHTML list as String. =cut @@ -2951,13 +3803,19 @@ should be included in this list. If the optional headline text is not provided, a default text will be used. +=over + +=item Related routines: -Related routines: =over 4 -add_item_funclist -end_funclist + +=item add_item_funclist + +=item end_funclist + =back +=back Inputs: (optional) headline text @@ -2984,10 +3842,18 @@ sub start_funclist { Adds an item to the list of available functions -Related routines: +=over + +=item Related routines: + =over 4 -start_funclist -end_funclist + +=item start_funclist + +=item end_funclist + +=back + =back Inputs: content item with text and link to function @@ -3010,15 +3876,19 @@ sub add_item_funclist { End list of available functions -Related routines: -=over 4 -start_funclist -add_item_funclist +=over + +=item Related routines: + + start_funclist + add_item_funclist + =back Inputs: ./. Returns: HTML code with function list end + =cut sub end_funclist { @@ -3045,7 +3915,7 @@ A string that's used as visually highlig it's value evaluates to false. =back - + returns: XHTML list as string. =back @@ -3058,7 +3928,43 @@ sub funclist_from_array { $args->{legend} ||= mt('Functions'); return list_from_array( [$args->{legend}, @$items], { 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 + '
      ' + .&funclist_from_array($items, {legend => &mt('Actions')}) + .'
      '; +} 1;