[LON-CAPA-cvs] cvs: loncom /homework edit.pm functionplotresponse.pm lonhomework.pm matchresponse.pm optionresponse.pm radiobuttonresponse.pm rankresponse.pm structuretags.pm /html/adm/jQuery/addons jquery-scrolltofixed.js jquery.viewport.mini.js /interface loncommon.pm lonmenu.pm lonpreferences.pm /localize/localize de.pm /publisher loncfile.pm lonpubdir.pm /xml scripttag.pm doc/loncapafiles loncapafiles.lpml

goltermann goltermann at source.lon-capa.org
Mon Jan 19 10:36:17 EST 2015


goltermann		Mon Jan 19 15:36:17 2015 EDT

  Added files:                 
    /loncom/html/adm/jQuery/addons	jquery-scrolltofixed.js 
                                  	jquery.viewport.mini.js 

  Modified files:              
    /doc/loncapafiles	loncapafiles.lpml 
    /loncom/homework	edit.pm functionplotresponse.pm lonhomework.pm 
                    	matchresponse.pm optionresponse.pm 
                    	radiobuttonresponse.pm rankresponse.pm 
                    	structuretags.pm 
    /loncom/interface	loncommon.pm lonmenu.pm lonpreferences.pm 
    /loncom/localize/localize	de.pm 
    /loncom/publisher	loncfile.pm lonpubdir.pm 
    /loncom/xml	scripttag.pm 
  Log:
  authoring space overhaul
  this update tries to improve the user experience of the authoring space.
  
  added codemirror for xml editor and script tags in colorful editor
  added possibility to deactivate codemirror in author settings
  added dropdown menu to insert problem templates into xml editor (thanks to tobias reinhardt)
  added feature of saving current scrollposition on save when editing problems
  added possibility to fold blocks in colorful editor, this state will be saved and restored
  added shortcuts to create empty problems, html files and directories
  
  and other smaller features and bugfixes
  
  
  
-------------- next part --------------
Index: doc/loncapafiles/loncapafiles.lpml
diff -u doc/loncapafiles/loncapafiles.lpml:1.903 doc/loncapafiles/loncapafiles.lpml:1.904
--- doc/loncapafiles/loncapafiles.lpml:1.903	Sat Jan  3 03:00:18 2015
+++ doc/loncapafiles/loncapafiles.lpml	Mon Jan 19 15:35:50 2015
@@ -2,7 +2,7 @@
  "http://lpml.sourceforge.net/DTD/lpml.dtd">
 <!-- loncapafiles.lpml -->
 
-<!-- $Id: loncapafiles.lpml,v 1.903 2015/01/03 03:00:18 raeburn Exp $ -->
+<!-- $Id: loncapafiles.lpml,v 1.904 2015/01/19 15:35:50 goltermann Exp $ -->
 
 <!--
 
@@ -703,7 +703,18 @@
   <categoryname>server readonly</categoryname>
   <description>JQuery countdown timer</description>
 </directory>
-  
+<directory dist='default'>
+  <protectionlevel>modest_delete</protectionlevel>
+  <targetdir dist='default'>/home/httpd/html/adm/codemirror</targetdir>
+  <categoryname>server readonly</categoryname>
+  <description>Codemirror</description>
+</directory>
+<directory dist='default'>
+  <protectionlevel>modest_delete</protectionlevel>
+  <targetdir dist='default'>/home/httpd/html/adm/jQuery/addons</targetdir>
+  <categoryname>server readonly</categoryname>
+  <description>jQuery addons</description>
+</directory>
 <!-- JQuery spellchecker plugin -->
 
 <directory dist='default'>
@@ -5003,8 +5014,15 @@
     countdownLED.png;
   </filenames>
 </fileglob>
-
-
+<fileglob>
+    <glob>*.*</glob>
+    <sourcedir>loncom/html/adm/jQuery/addons/</sourcedir>
+    <targetdir>home/httpd/html/adm/jQuery/addons/</targetdir>
+    <categoryname>script</categoryname>
+    <description>
+Addons for jQuery
+    </description>
+</fileglob>
 <!-- JQuery spellchecker plugin -->
 
 <fileglob>
@@ -8489,6 +8507,17 @@
 create_db_dynamic_64_so.3;
 </filenames>
 </fileglob>
+
+<fileglob>
+    <glob>*.*</glob>
+    <sourcedir>loncom/html/adm/codemirror/</sourcedir>
+    <targetdir>home/httpd/html/adm/codemirror/</targetdir>
+    <categoryname>script</categoryname>
+    <description>
+Codemirror for xml editor and script blocks in colorful editor
+    </description>
+</fileglob>
+
 <file>
 <source>loncom/debugging_tools/compiled/create_db_dynamic</source>
 <target dist='default'>home/httpd/perl/debug/create_db_dynamic</target>
Index: loncom/homework/edit.pm
diff -u loncom/homework/edit.pm:1.152 loncom/homework/edit.pm:1.153
--- loncom/homework/edit.pm:1.152	Fri Nov 28 18:23:03 2014
+++ loncom/homework/edit.pm	Mon Jan 19 15:35:53 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # edit mode helpers
 #
-# $Id: edit.pm,v 1.152 2014/11/28 18:23:03 raeburn Exp $
+# $Id: edit.pm,v 1.153 2015/01/19 15:35:53 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -164,12 +164,9 @@
 	    $description=&mt(&Apache::lonxml::description($token));
 	    if (!$description) { $description="<$tag>"; }
 	}
-	$result.= &start_table($token)."<tr><td>$description</td>
-                      <td>".&mt('Delete?').' '.
-		      &deletelist($target,$token)
-		      ."</td>
-                       <td>".
-		       &insertlist($target,$token);
+    $result.= &start_table($token)."<tr><td>".&Apache::loncommon::insert_folding_button().
+        " $description</td><td>".&mt('Delete?')." ".&deletelist($target,$token).
+        "</td><td>".&insertlist($target,$token);
 #<td>". 
 #  &movebuttons($target,$token).
 #    "</tr><tr><td colspan=\"3\">\n";
@@ -232,7 +229,10 @@
     return $result;
 }
 
-sub start_spanning_row { return '<tr><td colspan="5" bgcolor="#F0F0F0">';}
+sub start_spanning_row {
+    return '<tr name="foldblock_'.$Apache::lonxml::curdepth.
+    '" style="visibility: \'\'"><td colspan="5" bgcolor="#F0F0F0">';
+}
 sub start_row          { return '<tr><td bgcolor="#DDDDDD">';            }
 sub end_row            { return '</td></tr>';          }
 
@@ -788,12 +788,14 @@
 
 sub submit_ask_anyway {
     my ($extra_action) = @_;
-    return ' onclick="still_ask=true;'.$extra_action.'" ';
+    my $resource = $env{'request.ambiguous'};
+    return ' onclick="saveScrollPosition(\''.$resource.'\');still_ask=true;'.$extra_action.';" ';
 }
 
 sub submit_dont_ask {
     my ($extra_action) = @_;
-    return ' onclick="is_submit=true;'.$extra_action.'" ';
+    my $resource = $env{'request.ambiguous'};
+    return ' onclick="saveScrollPosition(\''.$resource.'\');is_submit=true;'.$extra_action.';" ';
 }
 
 sub js_update_linknum {
Index: loncom/homework/functionplotresponse.pm
diff -u loncom/homework/functionplotresponse.pm:1.106 loncom/homework/functionplotresponse.pm:1.107
--- loncom/homework/functionplotresponse.pm:1.106	Thu Aug 14 14:49:49 2014
+++ loncom/homework/functionplotresponse.pm	Mon Jan 19 15:35:53 2015
@@ -1,7 +1,7 @@
 # LearningOnline Network with CAPA
 # Functionplot responses
 #
-# $Id: functionplotresponse.pm,v 1.106 2014/08/14 14:49:49 raeburn Exp $
+# $Id: functionplotresponse.pm,v 1.107 2015/01/19 15:35:53 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1456,7 +1456,7 @@
   my $ylabel=&Apache::lonxml::get_param('ylabel',$parstack,$safeeval);
   if ($target eq 'edit') {
     $result.=&Apache::edit::start_table($token)
-       .'<tr><td><span class="LC_nobreak">'.&mt('Function Plot Question').'</span></td>'
+       .'<tr><td><span class="LC_nobreak">'.&Apache::loncommon::insert_folding_button().&mt('Function Plot Question').'</span></td>'
        .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
        .&Apache::edit::deletelist($target,$token).'   '
        .&Apache::edit::insertlist($target,$token).'   '
@@ -2043,7 +2043,7 @@
    my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
    if ($target eq 'edit') {
       return &Apache::edit::start_table($token).
-        '<tr><td><span class="LC_nobreak">'.&mt('Function Plot Rule Set').'</span></td>'
+        '<tr><td><span class="LC_nobreak">'.&Apache::loncommon::insert_folding_button().&mt('Function Plot Rule Set').'</span></td>'
        .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
        .&Apache::edit::deletelist($target,$token).'   '.
         &Apache::edit::insertlist($target,$token).'   '
@@ -2236,7 +2236,8 @@
 
    if ($target eq 'edit') {
       return &Apache::edit::start_table($token).
-        '<tr><td><span class="LC_nobreak">'.&mt('Function Plot Elements').'</span></td>'
+        '<tr><td><span class="LC_nobreak">'.&Apache::loncommon::insert_folding_button()
+       .&mt('Function Plot Elements').'</span></td>'
        .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
        .&Apache::edit::deletelist($target,$token).'   '.
         &Apache::edit::insertlist($target,$token).'   '
Index: loncom/homework/lonhomework.pm
diff -u loncom/homework/lonhomework.pm:1.346 loncom/homework/lonhomework.pm:1.347
--- loncom/homework/lonhomework.pm:1.346	Thu Dec 11 01:23:55 2014
+++ loncom/homework/lonhomework.pm	Mon Jan 19 15:35:53 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Homework handler
 #
-# $Id: lonhomework.pm,v 1.346 2014/12/11 01:23:55 raeburn Exp $
+# $Id: lonhomework.pm,v 1.347 2015/01/19 15:35:53 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -768,8 +768,7 @@
        .&Apache::loncommon::head_subbox(
                 &Apache::loncommon::CSTR_pageheader());
     $result .= 
-	&Apache::lonxml::message_location().'
-            <form name="lonhomework" method="post" action="'.
+	    '<form name="lonhomework" method="post" action="'.
 	    &HTML::Entities::encode($env{'request.uri'},'<>&"').'">'.
             '<input type="hidden" name="problemmode" value="'.
             $env{'form.problemmode'}.'" />'.
@@ -783,8 +782,9 @@
             <input type="button" name="submitmode" value="'.&mt("View").'" '.
             'onclick="javascript:setmode(this.form,'."'view'".')" />
             <hr />
-            </div>
-            </form>';
+            </div>'
+            .&Apache::lonxml::message_location().
+            '</form>';
     &Apache::lonxml::add_messages(\$result);
     $request->print($result);
     $request->rflush();
@@ -963,9 +963,8 @@
 
 	$problem='';
     }
-
     if (($env{'form.problemmode'} eq 'saveeditxml') ||
-        ($env{'form.problemmode'} eq 'saveviewxml') || 
+        ($env{'form.problemmode'} eq 'saveviewxml') ||
         ($env{'form.problemmode'} eq 'undoxml')) {
 	my $error=&handle_save_or_undo($request,\$problem,
 				       \$env{'form.editxmltext'});
@@ -1011,27 +1010,73 @@
             '<form '.&Apache::edit::form_change_detection().' name="lonhomework" method="post" action="'.
 	    &HTML::Entities::encode($env{'request.uri'},'<>&"').'">'.
 	    &Apache::structuretags::remember_problem_state().'
-            <div class="LC_edit_problem_editxml_header">
-              <table class="LC_edit_problem_header_title"><tr><td>
-               <h2>'.&mt('Problem Editing').' '.&Apache::loncommon::help_open_topic('Problem_Editor_XML_Index').'</h2>
-                </td><td align="right">
-                  '.&Apache::loncommon::helpLatexCheatsheet('Problem_LON-CAPA_Functions','Script Functions').'
-                </td></tr>
-              </table>';
-
-         $result.='<input type="hidden" name="problemmode" value="saveedit" />'.
-                  &Apache::structuretags::problem_edit_buttons('editxml');
+            <div class="LC_edit_problem_header">
+              <div class="LC_edit_problem_header_title">'.
+                &mt('Problem Editing').' '.&Apache::loncommon::help_open_topic('Problem_Editor_XML_Index').
+              '</div><div class="LC_edit_actionbar" id="actionbar">';
+
+        $result.='<input type="hidden" name="problemmode" value="saveedit" />'.
+                  &Apache::structuretags::problem_actionbar_buttons('editxml');
+        $result.='<div class="LC_edit_problem_discards">';
+
+		unless ($env{'environment.nocodemirror'}) {
+		# dropdown menues
+    		$result .= '<ol class="LC_primary_menu LC_floatleft">'.
+    		&Apache::lonmenu::create_submenu("#", "", &mt("Insert Menu"), &Apache::structuretags::insert_menu_datastructure(),"").'</ol>';
+		}
+    $result .= '<ol class="LC_primary_menu LC_floatleft">'.
+    Apache::lonmenu::create_submenu("#", "", &mt("Help"), &Apache::structuretags::helpmenu_datastructure(),"").'</ol>';
+    $result.="</div>";
          
-         $result.='<hr style="clear:both;" />'.&Apache::lonxml::message_location().'</div>'.  
-                  '<textarea '.&Apache::edit::element_change_detection().
+         $result.='<hr style="clear:both;visibility:hidden" /></div></div>'.&Apache::lonxml::message_location().
+                  &Apache::loncommon::xmleditor_js().
+		  '<textarea '.&Apache::edit::element_change_detection().
 	              ' rows="'.$rows.'" cols="'.$cols.'" style="width:100%" '.
 		      ' name="editxmltext" id="LC_editxmltext">'.
 		      &HTML::Entities::encode($problem,'<>&"').'</textarea>
             <div id="LC_aftertextarea">
             </div>
-            </form>'.&Apache::loncommon::end_page();
-	&Apache::lonxml::add_messages(\$result);
-	$request->print($result);
+	        </form>';
+	    my $resource = $env{'request.ambiguous'};
+	    unless($env{'environment.nocodemirror'}){
+	        
+	        $result .= '<link rel="stylesheet" href="/adm/codemirror/codemirror-combined-xml.css">
+	        <script src="/adm/codemirror/codemirror-compressed-xml.js"></script>
+	        <script>
+	            CodeMirror.defineMode("mixedmode", function(config) {
+	                return CodeMirror.multiplexingMode(
+	                    CodeMirror.getMode(config, "xml"),
+	                    {
+	                        open: "\<script type=\"loncapa/perl\"\>", close: "\</script\>",
+	                        mode: CodeMirror.getMode(config, "perl"),
+	                        delimStyle: "tag",
+	                    }
+	              );
+	            });
+	            var cm = CodeMirror.fromTextArea(document.getElementById("LC_editxmltext"),
+	            {
+	                mode: "mixedmode",
+	                lineWrapping: true,
+	                lineNumbers: true,
+	                tabSize: 4,
+	                indentUnit: 4,
+
+	                autoCloseTags: true,
+	                autoCloseBrackets: true,
+	                height: "auto",
+	                styleActiveLine: true,
+	                
+	                extraKeys: {
+	                    "Tab": "indentMore",
+	                    "Shift-Tab": "indentLess",
+	                }
+	            });
+	            restoreScrollPosition("'.$resource.'");
+	        </script>';
+	    }
+        $result .= &Apache::loncommon::end_page();
+        &Apache::lonxml::add_messages(\$result);
+        $request->print($result);
     }
     return '';
 }
@@ -1066,8 +1111,10 @@
 	    $problem='';
 	    my $filename=(split('/',$file))[-1];
 	    my $error =
-                &mt('Unable to find [_1]',
-			   '<span class="LC_filename">'.$filename.'</span>');
+		'<p class="LC_error">'
+               .&mt('Unable to find [_1]',
+			   '<span class="LC_filename">'.$filename.'</span>')
+		."</p>";
 	    $result.=
 		&Apache::loncommon::simple_error_page($request,'Not available',
 						      $error,{'no_auto_mt_msg' => 1});
@@ -1118,7 +1165,25 @@
     undef($Apache::lonhomework::parsing_a_task);
 }
 
-sub get_template_list {
+# function extracted from get_template_html
+# returns "key" -> list
+# key: path of template
+# value 1: title
+# value 2: category
+# value 3: name of help topic ???
+sub get_template_list{
+    my ($extension) = @_;
+    
+    my @files = glob($Apache::lonnet::perlvar{'lonIncludes'}.
+                     '/templates/*.'.$extension);
+    @files = map {[$_,&mt(&Apache::lonnet::metadata($_, 'title')),
+                      (&Apache::lonnet::metadata($_, 'category')?&mt(&Apache::lonnet::metadata($_, 'category')):&mt('Miscellaneous')),
+                      &mt(&Apache::lonnet::metadata($_, 'help'))]} (@files);
+    @files = sort {$a->[2].$a->[1] cmp $b->[2].$b->[1]} (@files);
+    return @files;
+}
+
+sub get_template_html {
     my ($extension) = @_;
     my $result;
     my @allnames;
@@ -1127,12 +1192,7 @@
     if ($extension eq 'survey' || $extension eq 'exam') {
 	$glob_extension = 'problem';
     }
-    my @files = glob($Apache::lonnet::perlvar{'lonIncludes'}.
-		     '/templates/*.'.$glob_extension);
-    @files = map {[$_,&mt(&Apache::lonnet::metadata($_, 'title')),
-                      (&Apache::lonnet::metadata($_, 'category')?&mt(&Apache::lonnet::metadata($_, 'category')):&mt('Miscellaneous')),
-                      &Apache::lonnet::metadata($_, 'help')]} (@files);
-    @files = sort {$a->[2].$a->[1] cmp $b->[2].$b->[1]} (@files);
+    my @files = &get_template_list($extension);
     my ($midpoint,$seconddiv,$numfiles);
     my @noexamplelink = ('blank.problem','blank.library','script.library');
     $numfiles = 0;
@@ -1194,6 +1254,12 @@
 sub newproblem {
     my ($request) = @_;
 
+	if ($env{'form.mode'} eq 'blank'){
+        my $dest = &Apache::lonnet::filelocation("",$request->uri);
+        &File::Copy::copy('/home/httpd/html/res/adm/includes/templates/blank.problem',$dest);
+        &renderpage($request,$dest);
+        return;
+    }
     if ($env{'form.template'}) {
 	my $file = $env{'form.template'};
 	my $dest = &Apache::lonnet::filelocation("",$request->uri);
@@ -1204,7 +1270,7 @@
 
     my ($extension) = ($request->uri =~ m/\.(\w+)$/);
     &Apache::lonxml::debug("Looking for :$extension:");
-    my $templatelist=&get_template_list($extension);
+    my $templatelist=&get_template_html($extension);
     if ($env{'form.newfile'} && !$templatelist) {
 	# no templates found
 	my $templatefilename =
@@ -1316,6 +1382,8 @@
 		&renderpage($request,$file);
 	    }
 	} else {
+		&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
+						    ['mode']);
 	    # requested file doesn't exist in contruction space
 	    &newproblem($request);
 	}
Index: loncom/homework/matchresponse.pm
diff -u loncom/homework/matchresponse.pm:1.91 loncom/homework/matchresponse.pm:1.92
--- loncom/homework/matchresponse.pm:1.91	Mon May  5 17:40:54 2014
+++ loncom/homework/matchresponse.pm	Mon Jan 19 15:35:53 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Full matching style response
 #
-# $Id: matchresponse.pm,v 1.91 2014/05/05 17:40:54 bisitz Exp $
+# $Id: matchresponse.pm,v 1.92 2015/01/19 15:35:53 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -55,7 +55,7 @@
 	$result=&Apache::response::meta_package_write('matchresponse');
     } elsif ($target eq 'edit' ) {
 	$result.=&Apache::edit::start_table($token).
-	    '<tr><td>'.&Apache::lonxml::description($token).'</td>'
+	    '<tr><td>'.&Apache::loncommon::insert_folding_button().&Apache::lonxml::description($token).'</td>'
            .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
 	   .&Apache::edit::deletelist($target,$token)
            .'</span></td>'
@@ -319,7 +319,8 @@
     &Apache::response::pushrandomnumber(undef,$target);
     if ($target eq 'edit') {
 	$result.=&Apache::edit::start_table($token)
-	    .'<tr><td>'.&mt('Collection Of Foils').'</td>'
+	    .'<tr><td>'.&Apache::loncommon::insert_folding_button()
+            .&mt('Collection Of Foils').'</td>'
             .'<td><span class="LC_nobreak">'.&mt('Delete?')
 	    .&Apache::edit::deletelist($target,$token)
 	    .'</span></td>'
Index: loncom/homework/optionresponse.pm
diff -u loncom/homework/optionresponse.pm:1.195 loncom/homework/optionresponse.pm:1.196
--- loncom/homework/optionresponse.pm:1.195	Fri Nov 28 18:23:04 2014
+++ loncom/homework/optionresponse.pm	Mon Jan 19 15:35:53 2015
@@ -1,7 +1,7 @@
 # LearningOnline Network with CAPA
 # option list style responses
 #
-# $Id: optionresponse.pm,v 1.195 2014/11/28 18:23:04 raeburn Exp $
+# $Id: optionresponse.pm,v 1.196 2015/01/19 15:35:53 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -51,7 +51,8 @@
   undef(%Apache::response::foilnames);
   if ($target eq 'edit') {
     $result.=&Apache::edit::start_table($token)
-       .'<tr><td><span class="LC_nobreak">'.&mt('Multiple Option Response Question').'</span> '
+       .'<tr><td><span class="LC_nobreak">'.&Apache::loncommon::insert_folding_button().' '
+       .&mt('Multiple Option Response Question').'</span> '
        .&Apache::loncommon::help_open_topic('Option_Response_Problems')."</td>"
        .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
        .&Apache::edit::deletelist($target,$token)
@@ -127,8 +128,8 @@
         maxcheck => 'Enter maximum number students may check (e.g., 3)',
         mincheck => 'Enter minimum number students need to check (e.g., 1)',
     );
-    $result.= (<<ENDTABLE);
-      <tr><td>$lt{'sel'}</td>
+    $result.= (<<ENDTABLE, &Apache::loncommon::insert_folding_button());
+      <tr><td>%s $lt{'sel'}</td>
         <td>
 	  $lt{'add'} <input type="text" name="$Apache::lonxml::curdepth.options" />
         </td>
Index: loncom/homework/radiobuttonresponse.pm
diff -u loncom/homework/radiobuttonresponse.pm:1.157 loncom/homework/radiobuttonresponse.pm:1.158
--- loncom/homework/radiobuttonresponse.pm:1.157	Tue Apr 30 03:03:34 2013
+++ loncom/homework/radiobuttonresponse.pm	Mon Jan 19 15:35:53 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # mutliple choice style responses
 #
-# $Id: radiobuttonresponse.pm,v 1.157 2013/04/30 03:03:34 raeburn Exp $
+# $Id: radiobuttonresponse.pm,v 1.158 2015/01/19 15:35:53 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -80,7 +80,8 @@
 	$result=&Apache::response::meta_package_write('radiobuttonresponse');
     } elsif ($target eq 'edit' ) {
 	$result.=&Apache::edit::start_table($token)
-           .'<tr><td>'.&Apache::lonxml::description($token)
+           .'<tr><td>'.&Apache::loncommon::insert_folding_button()
+           .&Apache::lonxml::description($token)
            .&Apache::loncommon::help_open_topic('Radio_Response_Problems')
            .'</td>'
            .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
Index: loncom/homework/rankresponse.pm
diff -u loncom/homework/rankresponse.pm:1.71 loncom/homework/rankresponse.pm:1.72
--- loncom/homework/rankresponse.pm:1.71	Mon May  5 17:40:54 2014
+++ loncom/homework/rankresponse.pm	Mon Jan 19 15:35:53 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # rank style response
 #
-# $Id: rankresponse.pm,v 1.71 2014/05/05 17:40:54 bisitz Exp $
+# $Id: rankresponse.pm,v 1.72 2015/01/19 15:35:53 goltermann Exp $
 # Copyright Michigan State University Board of Trustees
 #
 # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
@@ -51,7 +51,8 @@
 	$result=&Apache::response::meta_package_write('rankresponse');
     } elsif ($target eq 'edit' ) {
 	$result.=&Apache::edit::start_table($token)
-           .'<tr><td>'.&Apache::lonxml::description($token).'</td>'
+           .'<tr><td>'.&Apache::loncommon::insert_folding_button()
+           .&Apache::lonxml::description($token).'</td>'
            .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
            .&Apache::edit::deletelist($target,$token)
            .'</span></td>'
Index: loncom/homework/structuretags.pm
diff -u loncom/homework/structuretags.pm:1.526 loncom/homework/structuretags.pm:1.527
--- loncom/homework/structuretags.pm:1.526	Mon Dec 15 18:44:20 2014
+++ loncom/homework/structuretags.pm	Mon Jan 19 15:35:53 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: structuretags.pm,v 1.526 2014/12/15 18:44:20 raeburn Exp $
+# $Id: structuretags.pm,v 1.527 2015/01/19 15:35:53 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -225,6 +225,7 @@
 
 sub homework_js {
     return &Apache::loncommon::resize_textarea_js().
+                &Apache::loncommon::colorfuleditor_js().
            &setmode_javascript().
 	<<'JS';
 <script type="text/javascript">
@@ -678,28 +679,259 @@
    return $result;
 }
 
+sub insert_menu_datastructure {
+
+	my $template_menu = &template_dropdown_datastructure();
+	my $responseblock_menu = &responseblock_dropdown_datastructure();
+	my $conditional_scripting = &conditional_scripting_datastructure();
+	my $misc = &misc_datastructure();
+	
+	my @menu = ($template_menu, $responseblock_menu, $conditional_scripting, $misc);
+	return \@menu;
+
+}
+
+sub template_dropdown_datastructure {
+    # gathering the all templates and their path, title, category and help topic
+    my @templates = &Apache::lonhomework::get_template_list('problem');
+    # template category => title
+    my %tmplthash = ();
+    # template title => path
+    my %tmpltcontent = ();
+	
+    foreach my $template (@templates){
+        # put in hash if the template is not empty
+        unless ($template->[1] eq ''){
+            push(@{$tmplthash{$template->[2]}}, $template->[1]);
+            push(@{$tmpltcontent{$template->[1]}},$template->[0]);
+        }
+    }
+
+	my $catList = [];
+    foreach my $cat (sort keys %tmplthash) {
+		my $catItems = [];
+        foreach my $title (sort @{$tmplthash{$cat}}) {
+            my $path = $tmpltcontent{$title}->[0];
+            my $code;
+            open(FH, "<$path");
+            while(<FH>){
+                $code.= $_ unless $_ =~ /(<problem>)|(<\/problem>)/;
+            }
+            close(FH);
+
+			if ($code ne '') {				
+				my $href = 'javascript:insertText(\'' . &convert_for_js(&HTML::Entities::encode($code)) . '\')';
+				my $currItem = [$href, $title, undef];
+				push @{$catItems}, $currItem;
+			}
+        }
+		push @{$catList}, [$catItems, $cat, undef];
+    }
+
+	my $templDropdown = [$catList, &mt("Complete Problem Templates"), undef];
+    return $templDropdown;
+}
+
+sub responseblock_dropdown_datastructure {
+	
+	my $mathCat = [
+		[
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_formularesponse())) . "\')", &mt("Formula Response"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_functionplotresponse())) . "\')", &mt("Function Plot Response"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_mathresponse())) . "\')", &mt("Math Response"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_numericalresponse())) . "\')", &mt("Numerical Response"), undef]
+		], 
+		&mt("Math"), 
+		undef
+	];
+
+	my $miscCat = [		
+		[
+            ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_imageresponse())) . "\')", &mt("Click on Image"), undef],
+            ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_customresponse())) . "\')", &mt("Custom Response"), undef],
+            ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_externalresponse())) . "\')", &mt("External Response"), undef],
+            ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_matchresponse())) . "\')", &mt("Match Response"), undef],
+            ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_radiobuttonresponse())) . "\')", &mt("One out of N Statement"), undef],
+            ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_optionresponse())) . "\')", &mt("Optionresponse"), undef], 
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_rankresponse())) . "\')", &mt("Rank Values"), undef]
+		],
+		&mt("Misc"),
+		undef
+	];
+
+	my $chemCat = [
+		[
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_reactionresponse())) . "\')", &mt("Chemical Reaction"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicresponse())) . "\')", &mt("Organic Structure"), undef]
+		],
+		&mt("Chemical"),
+		undef
+	];
+
+	my $textCat = [
+		[
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_stringresponse())) . "\')", &mt("String Response"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_essayresponse())) . "\')", &mt("Essay"), undef]
+		],
+		&mt("Text"),
+		undef
+	];
+
+	my $cats = [[$mathCat, $miscCat, $chemCat, $textCat], &mt("Response Types"), undef];
+	return $cats;
+}
+
+
+sub conditional_scripting_datastructure {
+# TODO: corresponding routines should be used for the javascript:insertText parts
+# instead of the placeholder routine default_xml_tag with the tags
+# e.g. &default_xml_tag("postanswerdate") should be replaced with a routine which
+# returns the corresponding content for this case
+
+#TODO translated is currently temporarily here, another solution should be found where the
+# needed string can be retrieved
+
+	my $translatedTag = '
+<translated>
+    <lang which="en"></lang>
+    <lang which="default"></lang>
+</translated>';
+
+	my $cat = [
+		[
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode($translatedTag)) . "\')", &mt("Translated Tag"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("block"))) . "\')", &mt("Conditional Block"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("postanswerdate"))) . "\')", &mt("After Answer Block"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("preduedate"))) . "\')", &mt("Before Due Date Block"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("solved"))) . "\')", &mt("Block For After Solved"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("notsolved"))) . "\')", &mt("Block For When Not Solved"), undef]
+		],
+		&mt("Contitional Scripting"),
+		undef
+	];
+
+	return $cat;
+}
+
+sub misc_datastructure {
+	
+	my $graphicalCat = [
+		[
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_img())) . "\')", &mt("Image"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::lonplot::insert_gnuplot())) . "\')", &mt("GNU Plot"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicstructure())) . "\')", &mt("Organic Structure"), undef]
+		],
+		"Graphical",
+		undef
+	];
+
+	my $advancedCat = [
+		[
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_script())) . "\')", &mt("Script Block"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("allow"))) . "\')", &mt("File Dependencies"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("import"))) . "\')", &mt("Import a File"), undef],
+			["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::londefdef::insert_meta())) . "\')", &mt("Custom Metadata"), undef]
+		],
+		"advanced",
+		undef
+	];
+	
+	my $cats = [[$graphicalCat, $advancedCat], &mt("misc"), undef];
+	return $cats;
+}
+
+# helper routine for the datastructure building subroutines
+sub default_xml_tag {
+	my ($tag) = @_;
+	return "\n<$tag></$tag>";
+}
+
+
+sub helpmenu_datastructure {
+
+	my $width = 500;
+	my $height = 600;
+
+	my $helpers = [
+		['Problem_LON-CAPA_Functions', &mt('Script Functions')],
+		['Greek_Symbols', &mt('Greek Symbols')],
+ 		['Other_Symbols', &mt('Other Symbols')],
+		['Authoring_Output_Tags', &mt('Output Tags')],
+		['Authoring_Multilingual_Problems', 
+			&mt('How to create problems in different languages')]
+	];
+
+	my $help_structure = [];
+
+	foreach my $count (0..(scalar(@{$helpers})-1)) {
+		my $filename = $helpers->[$count]->[0];
+		my $title = $helpers->[$count]->[1];
+		my $href = &HTML::Entities::encode("javascript:openMyModal('/adm/help/$filename.hlp',$width,$height,'yes');");
+		push @{$help_structure}, [$href, $title, undef];
+	}
+
+	return $help_structure;
+}
+
+# we need substitution to not break javascript code
+sub convert_for_js {
+    my $return = shift;
+        $return =~ s|script|ESCAPEDSCRIPT|g;
+        $return =~ s|\n|\\r\\n|g;
+        $return =~ s|'|\\'|g;
+		$return =~ s|'|\\'|g;
+    return $return;
+}
+
 sub problem_edit_header {
-    return '<input type="hidden" name="submitted" value="edit" />'.
+    my ($mode)=@_;
+    my $return = '<input type="hidden" name="submitted" value="edit" />'.
 	&remember_problem_state('edit').'
-<div class="LC_edit_problem_header">
-<div class="LC_edit_problem_header_title">
-'.&mt('Problem Editing').&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').'
-</div>'.
-'<input type="hidden" name="problemmode" value="saveedit" />'.
-&problem_edit_buttons().'
-<hr style="clear:both;" />
-'.&Apache::lonxml::message_location().'
-</div>
-'.
-       '<table id="LC_edit_problem_colorful" border="0" width="100%"><tr><td bgcolor="#F8F8F8">';
+        <div class="LC_edit_problem_header">
+        <div class="LC_edit_problem_header_title">
+        '.&mt('Problem Editing').$mode.&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').'
+        </div><div class="LC_edit_actionbar" id="actionbar">'.
+        '<input type="hidden" name="problemmode" value="saveedit" />'.
+        &problem_edit_buttons();
+
+    $return.='<hr style="clear:both;visibility:hidden;" />
+    </div></div>'
+    .&Apache::lonxml::message_location();
+    $return .= '<link rel="stylesheet" href="/adm/codemirror/codemirror-combined.css" />
+    <script type="text/javascript" src="/adm/codemirror/codemirror-compressed-colorful.js"></script>';
+
+    $return .= '<script type="text/javascript" src="/adm/jQuery/addons/jquery-scrolltofixed.js"></script>
+        <script type="text/javascript">
+            // unless internet explorer
+            if (!(window.navigator.appName == "Microsoft Internet Explorer" && (document.documentMode || document.compatMode))){
+                $(document).ready(
+                    function() {
+                        $(\'.LC_edit_actionbar\').scrollToFixed(
+                            {
+                                fixed: function(){
+                                    $(this).find(\'.LC_edit_actionbar\').css(\'height\', \'31px\');
+                                }
+                            }
+                        );
+                    }
+                );
+            }
+        </script>
+        <table id="LC_edit_problem_colorful" border="0" width="100%"><tr><td bgcolor="#F8F8F8">';
+    return $return;
 }
 
 sub problem_edit_footer {
+    my $resource = $env{'request.ambiguous'};
     return '</td></tr></table><br />
 <div class="LC_edit_problem_footer">
   <hr />'.
 &problem_edit_buttons().'
   <hr style="clear:both;" />
+  <script type="text/javascript">
+      restoreState("'.$resource.'");
+      restoreScrollPosition("'.$resource.'");
+  </script>
 </div>
 '.
     "\n</form>\n".&Apache::loncommon::end_page();
@@ -2764,7 +2996,8 @@
     if ($target eq 'edit') {
 	my $areaid = 'homework_edit_'.$Apache::lonxml::curdepth;
 	$text=&Apache::lonxml::get_all_text("endouttext",$parser,$style);
-	$result.=&Apache::edit::start_table($token)."<tr><td>".&mt('Text Block')."</td>"
+        $result.=&Apache::edit::start_table($token)."<tr><td>".&Apache::loncommon::insert_folding_button()
+                 ." ".&mt('Text Block')."</td>"
                  .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
                  .&Apache::edit::deletelist($target,$token)
                  .'</span></td>'
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1204 loncom/interface/loncommon.pm:1.1205
--- loncom/interface/loncommon.pm:1.1204	Sun Dec 21 16:26:31 2014
+++ loncom/interface/loncommon.pm	Mon Jan 19 15:36:00 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1204 2014/12/21 16:26:31 raeburn Exp $
+# $Id: loncommon.pm,v 1.1205 2015/01/19 15:36:00 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1757,6 +1757,241 @@
 
 }
 
+sub colorfuleditor_js {
+    return <<"COLORFULEDIT"
+<script type="text/javascript">
+// <![CDATA[>
+    function fold_box(curDepth, lastresource){
+
+    // we need a list because there can be several blocks you need to fold in one tag
+        var block = document.getElementsByName('foldblock_'+curDepth);
+    // but there is only one folding button per tag
+        var foldbutton = document.getElementById('folding_btn_'+curDepth);
+
+        if(block.item(0).style.display == 'none'){
+
+            foldbutton.value = '@{[&mt("Hide")]}';
+            for (i = 0; i < block.length; i++){
+                block.item(i).style.display = '';
+            }
+        }else{
+
+            foldbutton.value = '@{[&mt("Show")]}';
+            for (i = 0; i < block.length; i++){
+                // block.item(i).style.visibility = 'collapse';
+                block.item(i).style.display = 'none';
+            }
+        };
+        saveState(lastresource);
+    }
+
+    function saveState (lastresource) {
+
+        var tag_list = getTagList();
+        if(tag_list != null){
+            var timestamp = new Date().getTime();
+            var key = lastresource;
+
+            // the value pattern is: 'time;key1,value1;key2,value2; ... '
+            // starting with timestamp
+            var value = timestamp+';';
+
+            // building the list of key-value pairs
+            for(var i = 0; i < tag_list.length; i++){
+                value += tag_list[i]+',';
+                value += document.getElementsByName(tag_list[i])[0].style.display+';';
+            }
+
+            // only iterate whole storage if nothing to override
+            if(localStorage.getItem(key) == null){        
+
+                // prevent storage from growing large
+                if(localStorage.length > 50){
+                    var regex_getTimestamp = /^(?:\d)+;/;
+                    var oldest_timestamp = regex_getTimestamp.exec(localStorage.key(0));
+                    var oldest_key;
+                    
+                    for(var i = 1; i < localStorage.length; i++){
+                        if (regex_getTimestamp.exec(localStorage.key(i)) < oldest_timestamp) {
+                            oldest_key = localStorage.key(i);
+                            oldest_timestamp = regex_getTimestamp.exec(oldest_key);
+                        }
+                    }
+                    localStorage.removeItem(oldest_key);
+                }
+            }
+            localStorage.setItem(key,value);
+        }
+    }
+
+    // restore folding status of blocks (on page load)
+    function restoreState (lastresource) {
+        if(localStorage.getItem(lastresource) != null){
+            var key = lastresource;
+            var value = localStorage.getItem(key);
+            var regex_delTimestamp = /^\d+;/;
+
+            value.replace(regex_delTimestamp, '');
+
+            var valueArr = value.split(';');
+            var pairs;
+            var elements;
+            for (var i = 0; i < valueArr.length; i++){
+                pairs = valueArr[i].split(',');
+                elements = document.getElementsByName(pairs[0]);
+
+                for (var j = 0; j < elements.length; j++){  
+                    elements[j].style.display = pairs[1];
+                    if (pairs[1] == "none"){
+                        var regex_id = /([_\\d]+)\$/;
+                        regex_id.exec(pairs[0]);
+                        document.getElementById("folding_btn"+RegExp.\$1).value = "Show";
+                    }
+                }
+            }
+        }
+    }
+
+    function getTagList () {
+        
+        var stringToSearch = document.lonhomework.innerHTML;
+
+        var ret = new Array();
+        var regex_findBlock = /(foldblock_.*?)"/g;
+        var tag_list = stringToSearch.match(regex_findBlock);
+
+        if(tag_list != null){
+            for(var i = 0; i < tag_list.length; i++){            
+                ret.push(tag_list[i].replace(/"/, ''));
+            }
+        }
+        return ret;
+    }
+
+    function saveScrollPosition (resource) {
+        var tag_list = getTagList();
+
+        // we dont always want to jump to the first block
+        // 170 is roughly above the "Problem Editing" header. we just want to save if the user scrolled down further than this
+        if(\$(window).scrollTop() > 170){
+            if(tag_list != null){
+                var result;
+                for(var i = 0; i < tag_list.length; i++){
+                    if(isElementInViewport(tag_list[i])){
+                        result += tag_list[i]+';';
+                    }
+                }
+                sessionStorage.setItem('anchor_'+resource, result);
+            }
+        } else {
+            // we dont need to save zero, just delete the item to leave everything tidy
+            sessionStorage.removeItem('anchor_'+resource);
+        }
+    }
+
+    function restoreScrollPosition(resource){
+
+        var elem = sessionStorage.getItem('anchor_'+resource);
+        if(elem != null){
+            var tag_list = elem.split(';');
+            var elem_list;
+
+            for(var i = 0; i < tag_list.length; i++){
+                elem_list = document.getElementsByName(tag_list[i]);
+                
+                if(elem_list.length > 0){
+                    elem = elem_list[0];
+                    break;
+                }
+            }
+            elem.scrollIntoView();
+        }
+    }
+
+    function isElementInViewport(el) {
+
+        // change to last element instead of first
+        var elem = document.getElementsByName(el);
+        var rect = elem[0].getBoundingClientRect();
+
+        return (
+            rect.top >= 0 &&
+            rect.left >= 0 &&
+            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
+            rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
+        );
+    }
+    
+    function autosize(depth){
+        var cmInst = window['cm'+depth];
+        var fitsizeButton = document.getElementById('fitsize'+depth);
+
+        // is fixed size, switching to dynamic
+        if (sessionStorage.getItem("autosized_"+depth) == null) {
+            cmInst.setSize("","auto");
+            fitsizeButton.value = "@{[&mt('Fixed size')]}";
+            sessionStorage.setItem("autosized_"+depth, "yes");
+
+        // is dynamic size, switching to fixed
+        } else {
+            cmInst.setSize("","300px");
+            fitsizeButton.value = "@{[&mt('Dynamic size')]}";
+            sessionStorage.removeItem("autosized_"+depth);
+        }
+    }
+
+
+
+// ]]>
+</script>
+COLORFULEDIT
+}
+
+sub xmleditor_js {
+    return <<XMLEDIT
+<script type="text/javascript" src="/adm/jQuery/addons/jquery-scrolltofixed.js"></script>
+<script type="text/javascript">
+// <![CDATA[>
+
+    function saveScrollPosition (resource) {
+
+        var scrollPos = \$(window).scrollTop();
+        sessionStorage.setItem(resource,scrollPos);
+    }
+
+    function restoreScrollPosition(resource){
+
+        var scrollPos = sessionStorage.getItem(resource);
+        \$(window).scrollTop(scrollPos);
+    }
+
+    // unless internet explorer
+    if (!(window.navigator.appName == "Microsoft Internet Explorer" && (document.documentMode || document.compatMode))){
+
+        \$(document).ready(function() {
+             \$(".LC_edit_actionbar").scrollToFixed(\{zIndex: 100\});
+        });
+    }
+
+    // inserts text at cursor position into codemirror (xml editor only)
+    function insertText(text){
+        cm.focus();
+        var curPos = cm.getCursor();
+        cm.replaceRange(text.replace(/ESCAPEDSCRIPT/g,'script'), {line: curPos.line,ch: curPos.ch});
+    }
+// ]]>
+</script>
+XMLEDIT
+}
+
+sub insert_folding_button {
+    my $curDepth = $Apache::lonxml::curdepth;
+    my $lastresource = $env{'request.ambiguous'};
+
+    return "<input type=\"button\" id=\"folding_btn_$curDepth\" 
+            value=\"".&mt('Hide')."\" onclick=\"fold_box('$curDepth','$lastresource')\">";
+}
+
 =pod
 
 =head1 Excel and CSV file utility routines
@@ -6555,6 +6790,7 @@
 div.LC_edit_problem_editxml_header,
 div.LC_edit_problem_editxml_header div {
   margin-top: 5px;
+  z-index: 100;
 }
 
 div.LC_edit_problem_header_title {
@@ -6572,7 +6808,12 @@
 
 div.LC_edit_problem_discards {
   float: left;
-  padding-bottom: 5px;
+}
+
+div.LC_edit_actionbar {
+    margin: -5px 0px 0px 0px !important;
+    background-color: $sidebg;
+    height: 31px;
 }
 
 div.LC_edit_problem_saves {
@@ -6593,6 +6834,10 @@
     margin-left: 40px;
 }
 
+#LC_edit_problem_codemirror div{
+    margin-left: 0px;
+}
+
 img.stift {
   border-width: 0;
   vertical-align: middle;
@@ -6707,7 +6952,6 @@
 ol.LC_primary_menu {
   margin: 0;
   padding: 0;
-  background-color: $pgbg_or_bgcolor;
 }
 
 ol#LC_PathBreadcrumbs {
@@ -6719,23 +6963,48 @@
   vertical-align: middle;
   text-align: left;
   list-style: none;
+  position: relative;
   float: left;
+  z-index: 100; /* will be displayed above codemirror and underneath the help-layer */
+  line-height: 1.5em;
 }
 
-ol.LC_primary_menu li a {
+ol.LC_primary_menu li a,
+ol.LC_primary_menu li p {
   display: block;
   margin: 0;
   padding: 0 5px 0 10px;
   text-decoration: none;
 }
 
-ol.LC_primary_menu li ul {
+ol.LC_primary_menu li p span.LC_primary_menu_innertitle {
+  display: inline-block;
+  width: 95%;
+  text-align: left;
+}
+
+ol.LC_primary_menu li p span.LC_primary_menu_innerarrow {
+  display: inline-block;	
+  width: 5%;
+  float: right;
+  text-align: right;
+  font-size: 70%;
+}
+
+ol.LC_primary_menu ul {
   display: none;
-  width: 10em;
+  width: 15em;
   background-color: $data_table_light;
+  position: absolute;
+  top: 100%;
 }
 
-ol.LC_primary_menu li:hover ul, ol.LC_primary_menu li.hover ul {
+ol.LC_primary_menu ul ul {
+  left: 100%;
+  top: 0;
+}
+
+ol.LC_primary_menu li:hover > ul, ol.LC_primary_menu li.hover > ul {
   display: block;
   position: absolute;
   margin: 0;
@@ -6744,15 +7013,21 @@
 }
 
 ol.LC_primary_menu li:hover li, ol.LC_primary_menu li.hover li {
+/* First Submenu -> size should be smaller than the menu title of the whole menu */
   font-size: 90%;
   vertical-align: top;
   float: none;
   border-left: 1px solid black;
   border-right: 1px solid black;
+/* A dark bottom border to visualize different menu options; 
+overwritten in the create_submenu routine for the last border-bottom of the menu */
+  border-bottom: 1px solid $data_table_dark; 
 }
 
-ol.LC_primary_menu li:hover li a, ol.LC_primary_menu li.hover li a {
-  background-color:$data_table_light;
+ol.LC_primary_menu li li p:hover {
+  color:$button_hover;
+  text-decoration:none;
+  background-color:$data_table_dark;
 }
 
 ol.LC_primary_menu li li a:hover {
@@ -6760,6 +7035,11 @@
    background-color:$data_table_dark;
 }
 
+/* Font-size equal to the size of the predecessors*/
+ol.LC_primary_menu li:hover li li {
+  font-size: 100%;
+}
+
 ol.LC_primary_menu li img {
   vertical-align: bottom;
   height: 1.1em;
Index: loncom/interface/lonmenu.pm
diff -u loncom/interface/lonmenu.pm:1.430 loncom/interface/lonmenu.pm:1.431
--- loncom/interface/lonmenu.pm:1.430	Sat Dec 20 15:35:40 2014
+++ loncom/interface/lonmenu.pm	Mon Jan 19 15:36:01 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines to control the menu
 #
-# $Id: lonmenu.pm,v 1.430 2014/12/20 15:35:40 raeburn Exp $
+# $Id: lonmenu.pm,v 1.431 2015/01/19 15:36:01 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -128,6 +128,33 @@
             (c) title for text wrapped by anchor tag in top level item.
             (d) reference to array of arrays of sub-menu items.
 
+ The underlying datastructure used in (d) contains data from mydesk.tab.
+ It consists of an array which has an array for each item appearing in
+ the menu (e.g. [["link", "title", "condition"]] for a single-item menu).
+ create_submenu() supports also the creation of XHTML for nested dropdown
+ menus represented by unordered lists. This is done by replacing the
+ scalar used for the link with an arrayreference containing the menuitems
+ for the nested menu. This can be done recursively so that the next menu
+ may also contain nested submenus.
+
+ Example:
+ [											# begin of datastructure
+	["/home/", "Home", "condition1"], 		# 1st item of the 1st layer menu
+	[										# 2nd item of the 1st layer menu
+		[									# anon. array for nested menu
+			["/path1", "Path1", undef], 	# 1st item of the 2nd layer menu
+			["/path2", "Path2", undef], 	# 2nd item of the 2nd layer menu
+			[								# 3rd item of the 2nd layer menu
+				[[...], [...], ..., [...]],	# containing another menu layer
+				"Sub-Sub-Menu",				# title for this container
+				undef
+			]
+		],									# end of array/nested menu
+		"Sub-Menu",							# title for the container item
+		undef
+	]										# end of 2nd item of the 1st layer menu
+]
+
 =item innerregister()
 
 This gets called in order to register a URL in the body of the document
@@ -499,35 +526,74 @@
                '<span class="LC_fontsize_small" style="font-weight:normal;">'.
                ' ▼</span></span></a>'.
                '<ul>';
+
+    # $link and $title are only used in the initial string written in $menu
+    # as seen above, not needed for nested submenus
+    $menu .= &build_submenu($target, $submenu, $translate, '1');
+    $menu .= '</ul></li>';
+
+    return $menu;
+}
+
+# helper routine for create_submenu
+# build the dropdown (and nested submenus) recursively
+# see perldoc create_submenu documentation for further information
+sub build_submenu {
+    my ($target, $submenu, $translate, $first_level) = @_; 
+    if (!defined(@{$submenu})) {
+        return '';
+    }
+
+    my $menu = '';
     my $count = 0;
     my $numsub = scalar(@{$submenu});
     foreach my $item (@{$submenu}) {
         $count ++;
         if (ref($item) eq 'ARRAY') {
             my $href = $item->[0];
-            if ($href =~ /(aboutme|rss\.html)$/) {
-                next unless (($env{'user.name'} ne '') && ($env{'user.domain'} ne ''));
-                $href =~ s/\[domain\]/$env{'user.domain'}/g;
-                $href =~ s/\[user\]/$env{'user.name'}/g;
-            }
+            my $bordertop;
             my $borderbot;
-            if ($count == $numsub) {
-                $borderbot = 'border-bottom:1px solid black;';
-            }
-            unless (($href eq '') || ($href =~ /^\#/)) {
-                $target = ' target="_top"';
-            }
-            $menu .= '<li style="margin:0;padding:0;'.
-                     $borderbot.'"><a href="'.$href.'"'.$target.'>';
+            my $title;
+
             if ($translate) {
-                $menu .= &mt($item->[1]);
+                 $title = &mt($item->[1]);
             } else {
-                $menu .= $item->[1];
+                $title = $item->[1];
+            }
+
+            if ($count == 1 && !$first_level) {
+                $bordertop = 'border-top: 1px solid black;';
+            }
+            if ($count == $numsub) {
+                $borderbot = 'border-bottom: 1px solid black;';
+            }
+
+            # href is a reference to another submenu
+            if (ref($href) eq 'ARRAY') {
+                $menu .= '<li style="margin:0;padding:0;'.$bordertop . $borderbot . '">';
+                $menu .= '<p><span class="LC_primary_menu_innertitle">'
+					. $title . '</span><span class="LC_primary_menu_innerarrow">▶</span></p>';
+                $menu .= '<ul>';
+                $menu .= &build_submenu($target, $href, $translate);
+                $menu .= '</ul>';
+                $menu .= '</li>';    
+            } else {    # href is the actual hyperlink and does not represent another submenu
+                        # for the current menu title
+                if ($href =~ /(aboutme|rss\.html)$/) {
+                    next unless (($env{'user.name'} ne '') && ($env{'user.domain'} ne ''));
+                    $href =~ s/\[domain\]/$env{'user.domain'}/g;
+                    $href =~ s/\[user\]/$env{'user.name'}/g;
+                }
+                unless (($href eq '') || ($href =~ /^\#/)) {
+                    $target = ' target="_top"';
+                }
+
+                $menu .= '<li style="margin:0;padding:0;'. $bordertop . $borderbot .'">';
+                $menu .= '<a href="'.$href.'"'.$target.'>' .  $title . '</a>';
+                $menu .= '</li>';
             }
-            $menu .= '</a></li>';
         }
     }
-    $menu .= '</ul></li>';
     return $menu;
 }
 
@@ -752,7 +818,7 @@
                 # wishlist is only available for users with access to resource-pool
                 # and links can only be set for resources within the resource-pool
                 $menuitems .= (<<ENDMENUITEMS);
-s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink('',currentURL)&Save a link for this resource in my personal Stored Links repository&&1
+s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in my personal Stored Links repository&&1
 ENDMENUITEMS
                 $got_wishlist = 1;
             }
@@ -803,7 +869,7 @@
                 if (($env{'user.adv'}) && (!$env{'request.enc'})) {
                     # wishlist is only available for users with access to resource-pool
                     $menuitems .= (<<ENDMENUITEMS);
-s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink('',currentURL)&Save a link for this resource in your personal Stored Links repository&&1
+s&9&1&wishlist-link.png&Stored Links&wishlistlink[_2]&set_wishlistlink()&Save a link for this resource in your personal Stored Links repository&&1
 ENDMENUITEMS
                     $got_wishlist = 1;
                 }
Index: loncom/interface/lonpreferences.pm
diff -u loncom/interface/lonpreferences.pm:1.214 loncom/interface/lonpreferences.pm:1.215
--- loncom/interface/lonpreferences.pm:1.214	Fri Dec 12 14:32:09 2014
+++ loncom/interface/lonpreferences.pm	Mon Jan 19 15:36:01 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Preferences
 #
-# $Id: lonpreferences.pm,v 1.214 2014/12/12 14:32:09 raeburn Exp $
+# $Id: lonpreferences.pm,v 1.215 2015/01/19 15:36:01 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1876,6 +1876,58 @@
     &print_main_menu($r,$message);
 }
 
+sub author_space_settings {
+    my $r = shift;
+    &Apache::lonhtmlcommon::add_breadcrumb(
+            {   href => '/adm/preferences?action=authorsettings',
+                text => 'Authoring Space Settings'});
+    my $user       = $env{'user.name'};
+    my $domain     = $env{'user.domain'};
+    my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au','ca','aa']);
+    if (keys(%author_roles) > 0) {
+            $r->print(Apache::loncommon::start_page('Authoring Space Settings'));
+            $r->print(Apache::lonhtmlcommon::breadcrumbs('Authoring Space Settings'));
+            my %userenv = &Apache::lonnet::get('environment',['nocodemirror']);
+            my $constchecked='';
+            if ($env{'environment.nocodemirror'}) {
+               $constchecked=' checked="checked"';
+            }
+            my $text=&mt('By default, Codemirror is activated for authors.');
+            my $cmoff=&mt('Deactivate Codemirror. This can improve the performance on slow computers.');
+            my $change=&mt('Save');
+            $r->print(<<ENDSCREEN);
+        <form name="prefs" action="/adm/preferences" method="post">
+        <input type="hidden" name="action" value="change_authoring_settings" />
+        $text<br />
+        <label><input type="checkbox" name="cmoff"$constchecked />$cmoff</label><br />
+        <input type="submit" value="$change" />
+        </form>
+ENDSCREEN
+    }
+}
+
+sub change_authoring_settings {
+    my $r = shift;
+    my $user       = $env{'user.name'};
+    my $domain     = $env{'user.domain'};
+    my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au','ca','aa']);
+    if (keys(%author_roles) > 0) {
+            my %ausettings=('environment.nocodemirror' => '');
+            if ($env{'form.cmoff'}) { $ausettings{'environment.nocodemirror'}='yes'; }
+            &Apache::lonnet::put('environment',\%ausettings);
+            &Apache::lonnet::appenv({'environment.nocodemirror' => $ausettings{'environment.nocodemirror'}});
+            my $status='';
+            if ($ausettings{'environment.nocodemirror'} eq 'yes') {
+                $status=&mt('on');
+            } else {
+                $status=&mt('off');
+            }
+            my $message=&Apache::lonhtmlcommon::confirm_success(&mt('Set [_1] to [_2]','<i>'.&mt('Deactivate Codemirror in Authoring Space').'</i>','<tt>'.$status.'</tt>'));
+            $message=&Apache::loncommon::confirmwrapper($message);
+            &print_main_menu($r,$message);
+    }
+}
+
 sub lockednameschanger {
     my $r = shift;
     &Apache::lonhtmlcommon::add_breadcrumb(
@@ -2117,6 +2169,18 @@
 	});
 
     }
+
+    my %author_roles = &Apache::lonnet::get_my_roles($user,$domain,'userroles','',['au','ca','aa']);
+    if (keys(%author_roles) > 0) {
+        push(@{ $menu[4]->{items} }, {
+            linktext => 'Authoring Space Configuration',
+            url => '/adm/preferences?action=authorsettings',
+            permission => 'F',
+            icon => 'course_ini.png',
+            linktitle => 'Settings for your authoring space.',
+        });
+    }
+
     if (&can_toggle_debug()) {
 push(@{ $menu[4]->{items} }, {
 	linktext => 'Toggle Debug Messages (Currently '.($env{'user.debug'} ? 'on)' : 'off)'),
@@ -2225,6 +2289,10 @@
         &coursedisplaychanger($r);
     }elsif($env{'form.action'} eq 'verify_and_change_coursepage'){
         &verify_and_change_coursepage($r);
+    }elsif($env{'form.action'} eq 'authorsettings'){
+        &author_space_settings($r);
+    }elsif($env{'form.action'} eq 'change_authoring_settings'){
+        &change_authoring_settings($r);
     }elsif($env{'form.action'} eq 'debugtoggle'){
         if (&can_toggle_debug()) {
             &toggle_debug();
Index: loncom/localize/localize/de.pm
diff -u loncom/localize/localize/de.pm:1.598 loncom/localize/localize/de.pm:1.599
--- loncom/localize/localize/de.pm:1.598	Mon Oct 13 14:50:38 2014
+++ loncom/localize/localize/de.pm	Mon Jan 19 15:36:05 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # German Localization Lexicon
 #
-# $Id: de.pm,v 1.598 2014/10/13 14:50:38 goltermann Exp $
+# $Id: de.pm,v 1.599 2015/01/19 15:36:05 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -29724,7 +29724,13 @@
 => 'andere Benutzer',
 
    'Quick Search'
-=> 'Schnellsuche'
+=> 'Schnellsuche',
+
+   'Dynamic size'
+=> 'Dynamische Größe',
+
+   'Fixed size'
+=> 'Feste Größe'
 
 #SYNCMARKER
 );
Index: loncom/publisher/loncfile.pm
diff -u loncom/publisher/loncfile.pm:1.122 loncom/publisher/loncfile.pm:1.123
--- loncom/publisher/loncfile.pm:1.122	Sat Jun 14 21:40:05 2014
+++ loncom/publisher/loncfile.pm	Mon Jan 19 15:36:11 2015
@@ -9,7 +9,7 @@
 #  and displays a page showing the results of the action.
 #
 #
-# $Id: loncfile.pm,v 1.122 2014/06/14 21:40:05 raeburn Exp $
+# $Id: loncfile.pm,v 1.123 2015/01/19 15:36:11 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -895,16 +895,21 @@
                 '</span></form></p>'.
                 '<p><form action="'.&url($fn).
                 '" method="post"><p><input type="submit" value="'.&mt('Cancel').'" /></form></p>');
-            return;
+        } elsif ($type ne 'warning') {
+            my $query = "";
+            $query .= "?mode=" . $env{'form.mode'} unless (!exists($env{'form.mode'}) || !length($env{'form.mode'}));
+            $request->print('
+                <script type="text/javascript">
+                    window.location = "'.&url($newfilename). $query .'";
+                </script>');
+        } else {
+            $request->print('<p>'.&mt('Make new file').' '.&display($newfilename).'?</p>');
+            $request->print('</form>');
+            $request->print('<form action="'.&url($newfilename).
+                        '" method="post"><p><input type="submit" value="'.&mt('Continue').'" /></p></form>');
+            $request->print('<form action="'.&url($fn).
+                        '" method="post"><p><input type="submit" value="'.&mt('Cancel').'" /></p></form>');
         }
-
-	$request->print('<p>'.&mt('Make new file').' '.&display($newfilename).'?</p>');
-	$request->print('</form>');
-
-	$request->print('<form action="'.&url($newfilename).
-			'" method="post"><p><input type="submit" value="'.&mt('Continue').'" /></p></form>');
-	$request->print('<form action="'.&url($fn).
-			'" method="post"><p><input type="submit" value="'.&mt('Cancel').'" /></p></form>');
     }
     return;
 }
@@ -1421,7 +1426,7 @@
 
     $r=shift;
 
-    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['decompress','action','filename','newfilename']);
+    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['decompress','action','filename','newfilename','mode']);
 
     &Debug($r, "loncfile.pm - handler entered");
     &Debug($r, " filename: ".$env{'form.filename'});
Index: loncom/publisher/lonpubdir.pm
diff -u loncom/publisher/lonpubdir.pm:1.162 loncom/publisher/lonpubdir.pm:1.163
--- loncom/publisher/lonpubdir.pm:1.162	Fri Oct 17 13:00:39 2014
+++ loncom/publisher/lonpubdir.pm	Mon Jan 19 15:36:11 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Authoring Space Directory Lister
 #
-# $Id: lonpubdir.pm,v 1.162 2014/10/17 13:00:39 goltermann Exp $
+# $Id: lonpubdir.pm,v 1.163 2015/01/19 15:36:11 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -586,7 +586,44 @@
                     <option value="newtaskfile">$lt{'nbt'}:</option>
                     <option value="newlibraryfile">$lt{'nlib'}:</option>
 	            <option value="newdir">$lt{'nsub'}:</option>
-		  </select> <input type="text" name="newfilename" value="$lt{'type'}" onfocus="if (this.value == '$mytype') this.value=''" /> <input type="button" value="Go" onclick="validate_go();" />
+		  </select> <input type="text" name="newfilename" placeholder="$lt{'type'}" value="" onfocus="if (this.value == is.empty()) this.value=''" /> <input type="button" value="Go" onclick="validate_go();" />
+		<br />
+                <span>Quickactions:
+                 <input type="hidden" name="mode"/>
+                 <a href="javascript:void(0)" onclick="javascript:validate_action('blank')">
+		    <img src="/adm/lonIcons/unknown.gif" title="Create blank problem file"></a>
+                 <a href="javascript:void(0)" onclick="javascript:validate_action('problemtempl')"> 
+                    <img src="/adm/lonIcons/problem.gif" title="Create new problem from template"></a>
+                 <a href="javascript:void(0)" onclick="javascript:validate_action('blankhtml')"> 
+                    <img src="/adm/lonIcons/html.gif" title="Create new blank HTML file"></a>
+                 <a href="javascript:void(0)" onclick="javascript:validate_action('folder')"> 
+		    <img src="/adm/lonIcons/navmap.folder.closed.gif" title="Create new subdirectory"></a>
+                </span>
+                 <script type="text/javascript">
+                     function validate_action(action){
+
+                         if (document.getElementsByName(\'newfilename\')[0].value != \'\'){
+                             if (action == "blank") {
+								 document.fileaction.action.value=\'newproblemfile\';
+								 document.fileaction.mode.value=\'blank\';
+							 } else if (action == "problemtempl") {
+								 document.fileaction.action.value=\'newproblemfile\';
+                                 validate_go();
+                             } else if (action == "blankhtml") {
+                                 document.fileaction.action.value=\'newhtmlfile\';
+                                 validate_go();
+                             } else if (action == "folder") {
+                                 document.fileaction.action.value=\'newdir\';
+                                 document.fileaction.mode.value=\'folder\';
+                             }
+                             fileaction.submit();
+                         } else {
+                             alert(\'Please specify file name.\');
+                             // TODO: ask for filename? if so, do some refactoring
+
+                         }
+                     }
+                 </script>
 		 </span>
       </fieldset>
     </form>
Index: loncom/xml/scripttag.pm
diff -u loncom/xml/scripttag.pm:1.172 loncom/xml/scripttag.pm:1.173
--- loncom/xml/scripttag.pm:1.172	Mon Aug 25 00:20:19 2014
+++ loncom/xml/scripttag.pm	Mon Jan 19 15:36:16 2015
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # <script> definiton
 #
-# $Id: scripttag.pm,v 1.172 2014/08/25 00:20:19 raeburn Exp $
+# $Id: scripttag.pm,v 1.173 2015/01/19 15:36:16 goltermann Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -118,9 +118,43 @@
     } elsif ($target eq "edit" ) {
       #&Apache::run::run($bodytext,$safeeval);
       #$result="<br /> <$token->[1]> output: <br />$bodytext<br />Source:<br />";
-	my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/script",$parser);
-	$result=&Apache::edit::tag_start($target,$token,'Script');
-	$result.=&Apache::edit::editfield($token->[1],$bodytext,'',80,4);
+    	my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/script",$parser);
+    	$result=&Apache::edit::tag_start($target,$token,'Script');
+
+        my $depth = $Apache::lonxml::curdepth;
+        $result.='<span id="LC_edit_problem_codemirror">';
+        unless ($env{'environment.nocodemirror'}) {
+            # only show button if codemirror activated
+            $result.='<input type="button" id="fitsize'.$depth.'" value="'.&mt("Dynamic size").
+            '" onclick="autosize(\''.$depth.'\')" />';
+        }
+        $result.=&Apache::edit::editfield($token->[1],$bodytext,'',80,4).'</span>';
+
+        unless ($env{'environment.nocodemirror'}) {
+            $result.='<script type="text/javascript">
+                var cm'.$depth.' = CodeMirror.fromTextArea(document.getElementById("homework_edit_'.$depth.'"),
+                {
+                    mode: "perl",
+                    lineWrapping: true,
+                    lineNumbers: true,
+                    tabSize: 4,
+                    indentUnit: 4,
+                    autoCloseBrackets: true,
+                    styleActiveLine: true,
+                    
+                    extraKeys: {
+                        "Tab": "indentMore",
+                        "Shift-Tab": "indentLess"
+                    }
+                });
+                if(sessionStorage.getItem("autosized_'.$depth.'") != null) {
+                    document.getElementById("fitsize'.$depth.'").value = "'.&mt("Fixed size").'";
+                    cm'.$depth.'.setSize("","auto");
+                }
+            </script>';
+        }
+                
+
     } elsif ($target eq 'meta') {
 	my $bodytext=&Apache::lonxml::get_all_text_unbalanced("/script",$parser);
     }

Index: loncom/html/adm/jQuery/addons/jquery-scrolltofixed.js
+++ loncom/html/adm/jQuery/addons/jquery-scrolltofixed.js
(function(a){a.isScrollToFixed=function(b){return !!a(b).data("ScrollToFixed")};a.ScrollToFixed=function(d,h){var k=this;k.$el=a(d);k.el=d;k.$el.data("ScrollToFixed",k);var c=false;var F=k.$el;var G;var D;var p;var C=0;var q=0;var i=-1;var e=-1;var t=null;var y;var f;function u(){F.trigger("preUnfixed.ScrollToFixed");j();F.trigger("unfixed.ScrollToFixed");e=-1;C=F.offset().top;q=F.offset().left;if(k.options.offsets){q+=(F.offset().left-F.position().left)}if(i==-1){i=q}G=F.css("position");c=true;if(k.options.bottom!=-1){F.trigger("preFixed.ScrollToFixed");w();F.trigger("fixed.ScrollToFixed")}}function m(){var H=k.options.limit;if(!H){return 0}if(typeof(H)==="function"){return H.apply(F)}return H}function o(){return G==="fixed"}function x(){return G==="absolute"}function g(){return !(o()||x())}function w(){if(!o()){t.css({display:F.css("display"),width:F.outerWidth(true),height:F.outerHeight(true),"float":F.css("float")});cssOptions={position:"fixed",top:k.options.bottom==-1?s!
 ():"",bottom:k.options.bottom==-1?"":k.options.bottom,"margin-left":"0px"};if(!k.options.dontSetWidth){cssOptions.width=F.width()}F.css(cssOptions);F.addClass("scroll-to-fixed-fixed");if(k.options.className){F.addClass(k.options.className)}G="fixed"}}function b(){var I=m();var H=q;if(k.options.removeOffsets){H=0;I=I-C}cssOptions={position:"absolute",top:I,left:H,"margin-left":"0px",bottom:""};if(!k.options.dontSetWidth){cssOptions.width=F.width()}F.css(cssOptions);G="absolute"}function j(){if(!g()){e=-1;t.css("display","none");F.css({width:"",position:D,left:"",top:p.top,"margin-left":""});F.removeClass("scroll-to-fixed-fixed");if(k.options.className){F.removeClass(k.options.className)}G=null}}function v(H){if(H!=e){F.css("left",q-H);e=H}}function s(){var H=k.options.marginTop;if(!H){return 0}if(typeof(H)==="function"){return H.apply(F)}return H}function z(){if(!a.isScrollToFixed(F)){return}var J=c;if(!c){u()}var H=a(window).scrollLeft();var K=a(window).scrollTop();var I=m(!
 );if(k.options.minWidth&&a(window).width()<k.options.minWidth){if(!g()
||!J){n();F.trigger("preUnfixed.ScrollToFixed");j();F.trigger("unfixed.ScrollToFixed")}}else{if(k.options.bottom==-1){if(I>0&&K>=I-s()){if(!x()||!J){n();F.trigger("preAbsolute.ScrollToFixed");b();F.trigger("unfixed.ScrollToFixed")}}else{if(K>=C-s()){if(!o()||!J){n();F.trigger("preFixed.ScrollToFixed");w();e=-1;F.trigger("fixed.ScrollToFixed")}v(H)}else{if(!g()||!J){n();F.trigger("preUnfixed.ScrollToFixed");j();F.trigger("unfixed.ScrollToFixed")}}}}else{if(I>0){if(K+a(window).height()-F.outerHeight(true)>=I-(s()||-l())){if(o()){n();F.trigger("preUnfixed.ScrollToFixed");if(D==="absolute"){b()}else{j()}F.trigger("unfixed.ScrollToFixed")}}else{if(!o()){n();F.trigger("preFixed.ScrollToFixed");w()}v(H);F.trigger("fixed.ScrollToFixed")}}else{v(H)}}}}function l(){if(!k.options.bottom){return 0}return k.options.bottom}function n(){var H=F.css("position");if(H=="absolute"){F.trigger("postAbsolute.ScrollToFixed")}else{if(H=="fixed"){F.trigger("postFixed.ScrollToFixed")}else{F.trigger("!
 postUnfixed.ScrollToFixed")}}}var B=function(H){if(F.is(":visible")){c=false;z()}};var E=function(H){z()};var A=function(){var I=document.body;if(document.createElement&&I&&I.appendChild&&I.removeChild){var K=document.createElement("div");if(!K.getBoundingClientRect){return null}K.innerHTML="x";K.style.cssText="position:fixed;top:100px;";I.appendChild(K);var L=I.style.height,M=I.scrollTop;I.style.height="3000px";I.scrollTop=500;var H=K.getBoundingClientRect().top;I.style.height=L;var J=(H===100);I.removeChild(K);I.scrollTop=M;return J}return null};var r=function(H){H=H||window.event;if(H.preventDefault){H.preventDefault()}H.returnValue=false};k.init=function(){k.options=a.extend({},a.ScrollToFixed.defaultOptions,h);k.$el.css("z-index",k.options.zIndex);t=a("<div />");G=F.css("position");D=F.css("position");p=a.extend({},F.offset());if(g()){k.$el.after(t)}a(window).bind("resize.ScrollToFixed",B);a(window).bind("scroll.ScrollToFixed",E);if(k.options.preFixed){F.bind("preFixed!
 .ScrollToFixed",k.options.preFixed)}if(k.options.postFixed){F.bind("po
stFixed.ScrollToFixed",k.options.postFixed)}if(k.options.preUnfixed){F.bind("preUnfixed.ScrollToFixed",k.options.preUnfixed)}if(k.options.postUnfixed){F.bind("postUnfixed.ScrollToFixed",k.options.postUnfixed)}if(k.options.preAbsolute){F.bind("preAbsolute.ScrollToFixed",k.options.preAbsolute)}if(k.options.postAbsolute){F.bind("postAbsolute.ScrollToFixed",k.options.postAbsolute)}if(k.options.fixed){F.bind("fixed.ScrollToFixed",k.options.fixed)}if(k.options.unfixed){F.bind("unfixed.ScrollToFixed",k.options.unfixed)}if(k.options.spacerClass){t.addClass(k.options.spacerClass)}F.bind("resize.ScrollToFixed",function(){t.height(F.height())});F.bind("scroll.ScrollToFixed",function(){F.trigger("preUnfixed.ScrollToFixed");j();F.trigger("unfixed.ScrollToFixed");z()});F.bind("detach.ScrollToFixed",function(H){r(H);F.trigger("preUnfixed.ScrollToFixed");j();F.trigger("unfixed.ScrollToFixed");a(window).unbind("resize.ScrollToFixed",B);a(window).unbind("scroll.ScrollToFixed",E);F.unbind(".Sc!
 rollToFixed");k.$el.removeData("ScrollToFixed")});B()};k.init()};a.ScrollToFixed.defaultOptions={marginTop:0,limit:0,bottom:-1,zIndex:1000};a.fn.scrollToFixed=function(b){return this.each(function(){(new a.ScrollToFixed(this,b))})}})(jQuery);
Index: loncom/html/adm/jQuery/addons/jquery.viewport.mini.js
+++ loncom/html/adm/jQuery/addons/jquery.viewport.mini.js

(function($){$.belowthefold=function(element,settings){var fold=$(window).height()+$(window).scrollTop();return fold<=$(element).offset().top-settings.threshold;};$.abovethetop=function(element,settings){var top=$(window).scrollTop();return top>=$(element).offset().top+$(element).height()-settings.threshold;};$.rightofscreen=function(element,settings){var fold=$(window).width()+$(window).scrollLeft();return fold<=$(element).offset().left-settings.threshold;};$.leftofscreen=function(element,settings){var left=$(window).scrollLeft();return left>=$(element).offset().left+$(element).width()-settings.threshold;};$.inviewport=function(element,settings){return!$.rightofscreen(element,settings)&&!$.leftofscreen(element,settings)&&!$.belowthefold(element,settings)&&!$.abovethetop(element,settings);};$.extend($.expr[':'],{"below-the-fold":function(a,i,m){return $.belowthefold(a,{threshold:0});},"above-the-top":function(a,i,m){return $.abovethetop(a,{threshold:0});},"left-of-screen":fu!
 nction(a,i,m){return $.leftofscreen(a,{threshold:0});},"right-of-screen":function(a,i,m){return $.rightofscreen(a,{threshold:0});},"in-viewport":function(a,i,m){return $.inviewport(a,{threshold:0});}});})(jQuery);


More information about the LON-CAPA-cvs mailing list