--- loncom/interface/lonhtmlcommon.pm 2012/01/02 20:38:18 1.299 +++ loncom/interface/lonhtmlcommon.pm 2012/10/08 10:47:34 1.327 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # a pile of common html routines # -# $Id: lonhtmlcommon.pm,v 1.299 2012/01/02 20:38:18 raeburn Exp $ +# $Id: lonhtmlcommon.pm,v 1.327 2012/10/08 10:47:34 foxr Exp $ # # Copyright Michigan State University Board of Trustees # @@ -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 "<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&filter=$filter&part=$part'><span class='LC_setting'>$linktext</span></a>"; } 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,58 @@ 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"; + <input type="button" value="$buttontext" onclick="javascript:dependencycheck();" /> +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) = @_; + my $link = '/adm/dependencies?symb='.&HTML::Entities::encode($symb,'<>&"'). + '&title='.&HTML::Entities::encode($title,'<>&"'). + '&url='.&HTML::Entities::encode($url,'<>&"'); + return <<ENDJS; + <script type="text/javascript"> + // <![CDATA[ + function dependencycheck() { + depwin = window.open("$link","","width=750,height=500,resizable,scrollbars=yes"); + } + // ]]> + </script> +ENDJS +} ############################################## ############################################## =pod -=item authorbombs +=item &authorbombs() =cut @@ -317,7 +363,7 @@ sub get_recent_frozen { =pod -=item textbox +=item &textbox() =cut @@ -337,7 +383,7 @@ sub textbox { =pod -=item checkbox +=item &checkbox() =cut @@ -359,7 +405,7 @@ sub checkbox { =pod -=item radiobutton +=item &radiobutton() =cut @@ -383,10 +429,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 +682,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 +941,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 +952,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 +979,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 +1001,7 @@ Inputs: Returns: none -=item Close_PrgWin +=item &Close_PrgWin() Closes the progress window. @@ -1068,10 +1101,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 +1145,7 @@ sub crumbs { if ($uri !~ m|/$|) { $output=~s|/$||; } $output.='</span>'; + return $output; } @@ -1170,6 +1207,15 @@ ENDEDITOR <script type="text/javascript" src="/adm/jQuery/js/jquery-1.6.2.min.js"></script> <script type="text/javascript" src="/adm/jQuery/js/jquery-ui-1.8.16.custom.min.js"></script> <link rel="stylesheet" type="text/css" href="/adm/jQuery/css/smoothness/jquery-ui-1.8.16.custom.css" /> +<script type="text/javascript" src="/adm/jpicker/js/jpicker-1.1.6.min.js" > +</script> +<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> +<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" /> + ENDJQUERY return $s; } @@ -1185,6 +1231,17 @@ sub htmlarea_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 sub htmlareaselectactive { @@ -1298,8 +1355,100 @@ sub htmlareaselectactive { $(this).before("<div><a href=\"#\" id=\"LC_rt_"+id+"\" title=\"Enable rich text formatting (bold, italic, etc.)\" class=\"LC_enable_rt\"><b>Rich formatting »</b></a></div>"); $("#LC_rt_"+id).click(editorHandler); }); + + }); '; + $output .= &color_picker; + + # Code to put a due date countdown in 'duedatecountdown' span. + # This is currently located in the breadcrumb headers. + # note that the dueDateLayout is internatinoalized below. + # Here document is used to support the substitution into the javascript below. + # ..which unforunately necessitates escaping the $'s in the javascript. + # There are several times of importance + # + # serverDueDate - The absolute time at which the problem expires. + # serverTime - The server's time when the problem finished computing. + # clientTime - The client's time...as close to serverTime as possible. + # The clientTime will be slightly later due to + # 1. The latency between problem computation and + # the first network action. + # 2. The time required between the page load-start and the actual + # initial javascript execution that got clientTime. + # These are used as follows: + # The difference between clientTime and serverTime are used to + # correct for differences in clock settings between the browser's system and the + # server's. + # + # The difference between clientTime and the time at which the ready() method + # starts executing is used to estimate latencies for page load and submission. + # Since this is an estimate, it is doubled. The latency estimate + one minute + # is used to determine when the countdown timer turns red to warn the user + # to think about submitting. + + 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; + + var documentReadyTime; + +\$(document).ready(function() { + if (typeof(dueDate) != "undefined") { + documentReadyTime = (new Date()).getTime(); + \$("#duedatecountdown").countdown({until: dueDate, compact: true, + layout: "$dueDateLayout", + onTick: function (periods) { + 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)) { + \$(this).css("color", "red"); //Highlight last minute. + } + } + }); + } +}); + + /* 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 if ($dragmath_prefix ne '') { $output .= ' @@ -1355,7 +1504,7 @@ 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; } if (($env{'request.noversionuri'} =~ m{^/adm/(viewclasslist|navmaps)($|\?)}) || ($env{'request.noversionuri'} =~ m{^/adm/.*/aboutme($|\?)})) { @@ -1375,12 +1524,67 @@ sub show_return_link { } +## +# Set the dueDate variable...note this is done in the timezone +# of the browser. +# +# @param epoch relative time at which the problem is due. +# +# @return the javascript fragment to set the date: +# +sub set_due_date { + my $dueStamp = shift; + my $duems = $dueStamp * 1000; # Javascript Date object needs ms not seconds. + + my $now = time()*1000; + + # This slightly obscure bit of javascript sets the dueDate variable + # to the time in the browser at which the problem was due. + # The code should correct for gross differences between the server + # and client's time setting + + return <<"END"; + +<script type="text/javascript"> + //<![CDATA[ +var serverDueDate = $duems; +var serverTime = $now; +var clientTime = (new Date()).getTime(); +var dueDate = new Date(serverDueDate + (clientTime - serverTime)); + + //]]> +</script> + +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"; + +<script type="text/javascript"> +//<![CDATA[ +serverTime = $now; +clientTime = (new Date()).getTime(); +//]]> +</script> + +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 +1602,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 +1626,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'; @@ -1463,9 +1668,11 @@ returns: nothing my $links; if ((&show_return_link) && (!$CourseBreadcrumbs)) { my $alttext = &mt('Go Back'); - $links=&htmltag( 'a',"<img src='/res/adm/pages/reload.png' border='0' style='vertical-align:middle;' alt='$alttext' />", + $links=&htmltag( 'a','<img src="/res/adm/pages/tolastloc.png" alt="'.$alttext.'" class="LC_icon" />', { 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', + }); $links=&htmltag('li',$links); } $links.= join "", @@ -1493,6 +1700,7 @@ 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}); @@ -1513,6 +1721,7 @@ returns: nothing $faq,$bug); } # + unless ($CourseBreadcrumbs) { @@ -1521,12 +1730,14 @@ returns: nothing $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 +1748,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 +1766,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 +1781,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 +1809,7 @@ returns: nothing push @{$tools{$category}}, @html; } -=item clear_breadcrumb_tools() +=item &clear_breadcrumb_tools() Clears the breadcrumb toolbar container. @@ -1605,7 +1821,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 +1830,7 @@ input: \$breadcrumbs - a reference to th breadcrumbs. returns: nothing + =cut #TODO might split this in separate functions for each category @@ -1629,7 +1846,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 +1857,7 @@ input: \$breadcrumbs - a reference to th breadcrumbs (after render_tools call). returns: nothing + =cut sub render_advtools { @@ -1711,15 +1931,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"; - <table $css_class> + <table $css_class $table_id> END return $output; } @@ -2003,26 +2227,41 @@ sub course_custom_roles { sub resource_info_box { - my ($symb,$onlyfolderflag)=@_; + my ($symb,$onlyfolderflag,$stuvcurrent,$stuvdisp)=@_; my $return=''; + if ($stuvcurrent ne '') { + $return = '<div class="LC_left_float">'; + } 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(). - '<th>'.&mt('Folder:').'</th><td>'.$folder.'</td>'. + '<th align="left">'.&mt('Folder:').'</th><td>'.$folder.'</td>'. &Apache::loncommon::end_data_table_row(); unless ($onlyfolderflag) { $return.=&Apache::loncommon::start_data_table_row(). - '<th>'.&mt('Resource:').'</th><td>'.&Apache::lonnet::gettitle($symb).'</td>'. + '<th align="left">'.&mt('Resource:').'</th><td>'.&Apache::lonnet::gettitle($symb).'</td>'. + &Apache::loncommon::end_data_table_row(); + } + if ($stuvcurrent ne '') { + $return .= &Apache::loncommon::start_data_table_row(). + '<th align="left">'.&mt("Student's current version:").'</th><td>'.$stuvcurrent.'</td>'. + &Apache::loncommon::end_data_table_row(); + } + if ($stuvdisp ne '') { + $return .= &Apache::loncommon::start_data_table_row(). + '<th align="left">'.&mt("Student's version displayed:").'</th><td>'.$stuvdisp.'</td>'. &Apache::loncommon::end_data_table_row(); } $return.=&Apache::loncommon::end_data_table(); } else { $return='<p><span class="LC_error">'.&mt('No context provided.').'</span></p>'; } + if ($stuvcurrent ne '') { + $return .= '</div>'; + } return $return; - } ############################################## @@ -2036,15 +2275,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 <div> # 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 = '<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>'; } ############################################## @@ -2508,6 +2751,270 @@ 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<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 (itemid.offsetWidth != itemwstart) { + listwchange = 1; + } +THIRD + if ($context eq 'docs') { + $output .= <<"DOCSTWO"; + if (activeTab == 'cc1') { + if (document.getElementById('cc_hrule') != null) { + document.getElementById('cc_hrule').style.width=actabw+"px"; + } + } else { + if (activeTab == 'bb1') { + if (document.getElementById('bb_hrule') != null) { + document.getElementById('bb_hrule').style.width=actabw+"px"; + } + } else { + if (activeTab == 'ee2') { + if (document.getElementById('ee_hrule') != null) { + document.getElementById('ee_hrule').style.width=actabw+"px"; + } + } + } + } +DOCSTWO + } + $output .= <<"FOURTH"; + } + if ((chkh == 1) || (listwchange)) { + var primaryheight = document.getElementById('LC_nav_bar').offsetHeight; + var 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 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"; + } + } + } + return; +} + +function callResize() { + var timer; + clearTimeout(timer); + timer=setTimeout('resize_scrollbox("$names{'scroll'}","1","1")',500); +} + +FOURTH + return $output; +} + + +############################################## +############################################## + # javascript_valid_email # # Generates javascript to validate an e-mail address. @@ -2623,8 +3130,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 +3223,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 +3258,7 @@ sub generate_menu { =pod -=item &start_funclist +=item &start_funclist() Start list of available functions @@ -2789,7 +3298,7 @@ sub start_funclist { =pod -=item &add_item_funclist +=item &add_item_funclist() Adds an item to the list of available functions @@ -2815,7 +3324,7 @@ sub add_item_funclist { =pod -=item &end_funclist +=item &end_funclist() End list of available functions @@ -2836,7 +3345,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