--- loncom/interface/lonhtmlcommon.pm 2012/01/02 05:07:06 1.298
+++ loncom/interface/lonhtmlcommon.pm 2012/12/18 15:27:46 1.338
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common html routines
#
-# $Id: lonhtmlcommon.pm,v 1.298 2012/01/02 05:07:06 raeburn Exp $
+# $Id: lonhtmlcommon.pm,v 1.338 2012/12/18 15:27:46 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -61,7 +61,7 @@ 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".''.
@@ -95,7 +95,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;
}
@@ -103,7 +103,7 @@ sub direct_parm_link {
##############################################
##############################################
-=item confirm_success
+=item &confirm_success()
Successful completion of an operation message
@@ -129,7 +129,7 @@ sub confirm_success {
=pod
-=item dragmath_button
+=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.
@@ -155,10 +155,11 @@ ENDDRAGMATH
=pod
-=item dragmath_js
+=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 {
@@ -177,13 +178,67 @@ sub dragmath_js {
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;
+ }
+ $link .= (($link=~/\?/)?'&':'?').'title='.
+ &HTML::Entities::encode($title,'<>&"');
+ if ($url) {
+ $link .= '&url='.&HTML::Entities::encode($url,'<>&"');
+ }
+ return <
+ //
+
+ENDJS
+}
##############################################
##############################################
=pod
-=item authorbombs
+=item &authorbombs()
=cut
@@ -317,7 +372,7 @@ sub get_recent_frozen {
=pod
-=item textbox
+=item &textbox()
=cut
@@ -337,7 +392,7 @@ sub textbox {
=pod
-=item checkbox
+=item &checkbox()
=cut
@@ -359,7 +414,7 @@ sub checkbox {
=pod
-=item radiobutton
+=item &radiobutton()
=cut
@@ -383,10 +438,10 @@ sub radio {
=pod
-=item &date_setter
+=item &date_setter()
&date_setter returns html and javascript for a compact date-setting form.
-To retrieve values from it, use &get_date_from_form().
+To retrieve values from it, use &get_date_from_form.
Inputs
@@ -636,7 +691,7 @@ sub build_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.
@@ -895,7 +950,7 @@ of items completed and an estimate of th
=over 4
-=item &Create_PrgWin
+=item &Create_PrgWin()
Writes javascript to the client to open a progress window and returns a
data structure used for bookkeeping.
@@ -906,27 +961,14 @@ Inputs
=item $r Apache request
-=item $title The title of the progress window
-
-=item $heading A description (usually 1 line) of the process being initiated.
-
=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
Returns a hash containing the progress state data structure.
-=item &Update_PrgWin
+=item &Update_PrgWin()
Updates the text in the progress indicator. Does not increment the count.
See &Increment_PrgWin.
@@ -946,7 +988,7 @@ Inputs:
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.
@@ -968,7 +1010,7 @@ Inputs:
Returns: none
-=item Close_PrgWin
+=item &Close_PrgWin()
Closes the progress window.
@@ -1068,10 +1110,13 @@ sub Close_PrgWin {
undef(%$prog_state);
}
+
# ------------------------------------------------------- Puts directory header
sub crumbs {
my ($uri,$target,$prefix,$form,$skiplast)=@_;
+# You cannot crumbnify uploaded or adm resources
+ if ($uri=~/^\/*(uploaded|adm)\//) { return &mt('(Internal Course/Group Content)'); }
if ($target) {
$target = ' target="'.
&Apache::loncommon::escape_single($target).'"';
@@ -1109,6 +1154,7 @@ sub crumbs {
if ($uri !~ m|/$|) { $output=~s|/$||; }
$output.='';
+
return $output;
}
@@ -1170,6 +1216,15 @@ ENDEDITOR
+
+
+
+
+
+
+
+
ENDJQUERY
return $s;
}
@@ -1185,6 +1240,17 @@ sub htmlarea_lang {
return $lang;
}
+# return javacsript to activate elements of .colorchooser with jpicker:
+# Caller is responsible for enclosing this in
+
+END
+}
+##
+# Sets the time at which the problem finished computing.
+# This just updates the serverTime and clientTime variables above.
+# Calling this in e.g. end_problem provides a better estimate of the
+# difference beetween the server and client time setting as
+# the difference contains less of the latency/problem compute time.
+#
+sub set_compute_end_time {
+
+ my $now = time()*1000; # Javascript times are in ms.
+ return <<"END";
+
+
+
+END
+}
+
############################################################
############################################################
=pod
-=item breadcrumbs
+=item &breadcrumbs()
Compiles the previously registered breadcrumbs into an series of links.
Additionally supports a 'component', which will be displayed on the
@@ -1398,11 +1613,11 @@ Inputs: $component (the text on the righ
when including the text on the right.
Returns a string containing breadcrumbs for the current page.
-=item clear_breadcrumbs
+=item &clear_breadcrumbs()
Clears the previously stored breadcrumbs.
-=item add_breadcrumb
+=item &add_breadcrumb()
Pushes a breadcrumb on the stack of crumbs.
@@ -1422,7 +1637,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) = @_;
#
$css_class ||= 'LC_breadcrumbs';
@@ -1446,6 +1662,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',
@@ -1461,12 +1685,14 @@ returns: nothing
}
}
my $links;
- if ((&show_return_link) && (!$CourseBreadcrumbs)) {
- my $alttext = 'Go Back';
- $links=&htmltag( 'a',"",
+ if ((&show_return_link) && (!$CourseBreadcrumbs) && (ref($last) eq 'HASH')) {
+ my $alttext = &mt('Go Back');
+ $links=&htmltag( 'a','',
{ href => '/adm/flip?postdata=return:',
- title => &mt("Back to most recent content resource") });
- $links=&htmltag('li',$links);
+ title => &mt('Back to most recent content resource'),
+ class => 'LC_menubuttons_link',
+ });
+ $links=&htmltag('li',$links);
}
$links.= join "",
map {
@@ -1493,8 +1719,11 @@ 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});
+
+ if ($lasttext ne '') {
+ $links .= &htmltag( 'li', htmltag($CourseBreadcrumbs ? 'b' : 'h1',
+ $lasttext), {title => $lasttext});
+ }
my $icons = '';
$faq = $last->{'faq'} if (exists($last->{'faq'}));
@@ -1513,20 +1742,24 @@ returns: nothing
$faq,$bug);
}
#
-
- 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) {
$links = &htmltag('span',
( $no_mt ? $component : mt($component) ).
( $icons ? $icons : '' ),
{ class => 'LC_breadcrumbs_component' } )
- .$links;
+ .$links
+;
}
&render_tools(\$links);
@@ -1537,7 +1770,12 @@ returns: nothing
# Return the @Crumbs stack to what we started with
push(@Crumbs,$last);
shift(@Crumbs);
+
+
# Return the breadcrumb's line
+
+
+
return "$links";
}
@@ -1550,7 +1788,7 @@ returns: nothing
push(@Crumbs,@_);
}
-=item add_breadcrumb_tool($category, $html)
+=item &add_breadcrumb_tool($category, $html)
Adds $html to $category of the breadcrumb toolbar container.
@@ -1565,7 +1803,7 @@ 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
@@ -1593,7 +1831,7 @@ returns: nothing
push @{$tools{$category}}, @html;
}
-=item clear_breadcrumb_tools()
+=item &clear_breadcrumb_tools()
Clears the breadcrumb toolbar container.
@@ -1605,7 +1843,7 @@ returns: nothing
undef(%tools);
}
-=item render_tools(\$breadcrumbs)
+=item &render_tools(\$breadcrumbs)
Creates html for breadcrumb tools (categories navigation and tools) and inserts
\$breadcrumbs at the correct position.
@@ -1614,6 +1852,7 @@ input: \$breadcrumbs - a reference to th
breadcrumbs.
returns: nothing
+
=cut
#TODO might split this in separate functions for each category
@@ -1629,7 +1868,9 @@ returns: nothing
{ listattr => { class=>'LC_breadcrumb_tools_outerlist' } });
}
-=item render_advtools(\$breadcrumbs)
+=pod
+
+=item &render_advtools(\$breadcrumbs)
Creates html for advanced tools (category advtools) and inserts \$breadcrumbs
at the correct position.
@@ -1638,6 +1879,7 @@ input: \$breadcrumbs - a reference to th
breadcrumbs (after render_tools call).
returns: nothing
+
=cut
sub render_advtools {
@@ -1651,6 +1893,82 @@ returns: nothing
} # End of scope for @Crumbs
+sub docs_breadcrumbs {
+ my ($allowed,$crstype,$contenteditor,$title,$precleared)=@_;
+ my ($folderpath,@folders);
+ my @folders = split('&',$env{'form.folderpath'});
+ 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*)$//;
+ 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 '.$crstype.' Contents');
+ }
+ 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;
+ }
+}
+
############################################################
############################################################
@@ -1711,15 +2029,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;
}
@@ -2003,26 +2325,41 @@ sub course_custom_roles {
sub resource_info_box {
- my ($symb,$onlyfolderflag)=@_;
+ my ($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp)=@_;
my $return='';
+ if ($stuvcurrent ne '') {
+ $return = '
';
+ }
if ($symb) {
- $return=&Apache::loncommon::start_data_table();
+ $return.=&Apache::loncommon::start_data_table();
my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symb);
my $folder=&Apache::lonnet::gettitle($map);
$return.=&Apache::loncommon::start_data_table_row().
- '
';
+ }
return $return;
-
}
##############################################
@@ -2036,15 +2373,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.'
';
}
##############################################
@@ -2508,6 +2849,330 @@ ENDSCRIPT
##############################################
##############################################
+sub resize_scrollbox_js {
+ my ($context,$tabidstr) = @_;
+ 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') {
+ $output .= '
+var activeTab;
+';
+ }
+ $output .= <<"FIRST";
+
+$viewport_js
+
+function resize_scrollbox(scrollboxname,chkw,chkh) {
+ var scrollboxid = 'div_'+scrollboxname;
+ var scrolltableid = 'table_'+scrollboxname;
+ var scrollbox;
+ var scrolltable;
+
+ 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;
+ 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 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 .= '®ister=1';
+ }
+ $jscall = "need_switchserver('$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('$cfile')";
+ }
+ return $jscall;
+}
+
+##############################################
+##############################################
+
# javascript_valid_email
#
# Generates javascript to validate an e-mail address.
@@ -2623,8 +3288,9 @@ sub scripttag {
return htmltag('script', $content, {type => 'text/javascript'});
};
+=pod
-=item list_from_array( \@array, { listattr =>{}, itemattr =>{} } )
+=item &list_from_array( \@array, { listattr =>{}, itemattr =>{} } )
Constructs a XHTML list from \@array.
@@ -2715,7 +3381,8 @@ sub generate_menu {
$$link{alttext} : $$link{linktext})
}), {
href => $$link{url},
- title => mt($$link{linktitle})
+ title => mt($$link{linktitle}),
+ class => 'LC_menubuttons_link'
}).
$a->(mt($$link{linktext}), {
href => $$link{url},
@@ -2749,7 +3416,7 @@ sub generate_menu {
=pod
-=item &start_funclist
+=item &start_funclist()
Start list of available functions
@@ -2789,7 +3456,7 @@ sub start_funclist {
=pod
-=item &add_item_funclist
+=item &add_item_funclist()
Adds an item to the list of available functions
@@ -2815,7 +3482,7 @@ sub add_item_funclist {
=pod
-=item &end_funclist
+=item &end_funclist()
End list of available functions
@@ -2836,7 +3503,7 @@ sub end_funclist {
=pod
-=item funclist_from_array( \@array, {legend => 'text for legend'} )
+=item &funclist_from_array( \@array, {legend => 'text for legend'} )
Constructs a XHTML list from \@array with the first item being visually
highlighted and set to the value of legend or 'Functions' if legend is
@@ -2869,6 +3536,40 @@ sub funclist_from_array {
{ listattr => {class => 'LC_funclist'} });
}
+=pod
+
+=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 Construction 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
+ '