* Added a hook for adding new items in alt_topmenu_dummy.php (requested by Stig N...
authorMichael Stucki <michael.stucki@typo3.org>
Sat, 15 Oct 2005 16:50:31 +0000 (16:50 +0000)
committerMichael Stucki <michael.stucki@typo3.org>
Sat, 15 Oct 2005 16:50:31 +0000 (16:50 +0000)
* Added a JavaScript to the backend which makes it possible to use tabulator keys in textareas. Can be disabled by setting $BE_USER->uc['disableTabInTextarea'].

git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@816 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
NEWS.txt
typo3/alt_topmenu_dummy.php
typo3/tab.js [new file with mode: 0644]
typo3/template.php

index af29dc9..3d1a3f4 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,10 @@
-2005-10-14     Andreas Otto    <andreas.otto@dkd.de>
+2005-10-15  Michael Stucki  <michael@typo3.org>
+
+       * Added a hook for adding new items in alt_topmenu_dummy.php (requested by Stig N. Færch for his "roles" extension)
+       * Added a JavaScript to the backend which makes it possible to use tabulator keys in textareas. Can be disabled by setting $BE_USER->uc['disableTabInTextarea'].
+
+2005-10-14  Andreas Otto  <andreas.otto@dkd.de>
+
        * Fixed bug #1594: In t3lib_matchCondition->match() it could be the case that $this->altRootline was not allways an array, but it is supposed to be an array. Therefore at the beginning of t3lib_matchCondition->match() the variable type is checked and an empty array is created if needed.
 
 2005-10-07  Kasper Skårhøj  <kasper2005@typo3.com>
        * Added initial support for workspaces in core.
        * !!! Notice that all versioning features for tables are now enabled by the [ctrl] directive "versioningWS" and not "versioning". You will have to change this for all custom usages. At the same time you will have to add additional fields that are now mandatory for versioning to work. This is documented in the yet not published TYPO3 Core API for next version. Until the versioning API is final it is recommended to be very careful to apply versioning to custom tables.
 
-2005-10-04 Martin Kutschker  <martin.t.kutschker@blackbox.net>
+2005-10-04  Martin Kutschker  <martin.t.kutschker@blackbox.net>
 
        * Fixed bug #1152: allow for nice filenames in Apache stat file (config.stat_apache_niceTitle)
        * optionally remove the site root from the Apache stat file path (config.stat_apache_noRoot)
        * Fix bug #1516: improper user of mb_strpos()
 
-2005-10-02 Bernhard Kraft  <kraftb@kraftb.at>
+2005-10-02  Bernhard Kraft  <kraftb@kraftb.at>
 
        * Integrated content-slide extension into core
        * Implemented "requestUpdate" feature of TCEforms for Flexform fields
 
-2005-09-19 Martin Kutschker  <martin.t.kutschker@blackbox.net>
+2005-09-19  Martin Kutschker  <martin.t.kutschker@blackbox.net>
 
        * Fixed bug #1287: Detect Opera as Netscape3 (making image roll-overs work)
 
-2005-09-18 Michael Stucki <michael@typo3.org>
+2005-09-18  Michael Stucki <michael@typo3.org>
 
        * If the encryption key is not set, the warning in the backend now contains a link to the according section.
        * be_group can no longer be selected as a subgroup of itself
        * Some typo fixes
        * New property for TYPO3_CONF_VARS[SYS][displayErrors]: If set to 2, display_errors will only be enabled if the devIPmask matches the current clients IP address.
 
-2005-09-14 Karsten Dambekalns <karsten@typo3.org>
+2005-09-14  Karsten Dambekalns <karsten@typo3.org>
 
        * Fixed bug #214 (flexform default values), as it has been reported to work with the existing patch.
 
-2005-09-13 Ingmar Schlecht <ingmar@typo3.org>
+2005-09-13  Ingmar Schlecht <ingmar@typo3.org>
 
        * Fixed bug #1375: Made typo3/mod/tools/em/index.php use preg_quote() on filename before passing it to preg_match()
 
-2005-09-13 Karsten Dambekalns <karsten@typo3.org>
+2005-09-13  Karsten Dambekalns <karsten@typo3.org>
 
        * Fixed the page is being generated page refreshing to the wrong page when query parameters are used.
        * Fixed (part of) bug 1312 (showpic.php).
 
-2005-08-22 Martin Kutschker <martin.t.kutschker@blackbox.net>
+2005-08-22  Martin Kutschker <martin.t.kutschker@blackbox.net>
 
        * Fixed bug #24: Modified the JS layer code so that GMENU_LAYERS work with Opera (3.8 patch port by Michael Stucki)
 
index f0e8921..cd5e78e 100644 (file)
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -1,23 +1,21 @@
-
 ************************************************************************
 CHANGES & IMPROVEMENTS in TYPO3 4.0
 (for technical details see ChangeLog)
 ************************************************************************
 
-Access Control:
----------------
+Access Control
+===============
 
-       * FE-groups are now nested and content elements and pages can have more than one group (Michael Stucki <michael@typo3.org> integrating extension "fenestgrp" by Glen Gibb and extension "ingmar_accessctrl" by Ingmar Schlecht)
+       * FE-groups are now nested and content elements. Additionally, pages can have more than one group assigned. (Michael Stucki <michael@typo3.org> integrating extension "fenestgrp" by Glen Gibb and extension "ingmar_accessctrl" by Ingmar Schlecht)
 
 Compatibility
-------------
+==============
 
        * GMENU_LAYERS and TMENU_LAYERS and image rollovers now work with Opera browsers (Martin Kutschker <martin.t.kutschker@blackbox.net>)
 
-2005-07-02  
+2005-07-02
 
-Security:
----------
+Security
+=========
 
        * A debug script exposed system information provided by phpinfo(). For details, see http://typo3.org /teams/security/security-bulletins/typo3-20050725-1/ (Michael Stucki <michael@typo3.org>)
-
index 24f3345..58413d6 100755 (executable)
@@ -82,8 +82,31 @@ class SC_alt_topmenu_dummy {
        function main() {
                global $BE_USER,$LANG,$BACK_PATH,$TBE_MODULES,$TBE_TEMPLATE;
 
-                       // IF noMenuMode is set to 'icons', then display menu instead of nothingness
-               if (!strcmp($BE_USER->uc['noMenuMode'],'icons'))        {
+                       // Remember if noMenuMode is set to 'icons' or not because the hook will be ignored in this case.
+               if (!strcmp($BE_USER->uc['noMenuMode'],'icons'))        { $iconMenuMode = true; }
+
+                       // Hook for adding content to the topmenu. Only works if noMenuMode is not set to "icons" in the users setup!
+               if (!$iconMenuMode && is_array ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/alt_topmenu_dummy.php']['fetchContentTopmenu']))       {
+                       $contentArray=array();
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/alt_topmenu_dummy.php']['fetchContentTopmenu'] as $classRef)  {
+                               $hookObj = &t3lib_div::getUserObj($classRef);
+                               if (method_exists($hookObj,'fetchContentTopmenu_processContent'))       {
+                                       $tempContent = $hookObj->fetchContentTopmenu_processContent($this);
+
+                                               // Placement priority handling.
+                                       if(is_int($hookObj->priority) and ($hookObj->priority>=1 and $hookObj->priority<=9))    {
+                                               $priority = $hookObj->priority;
+                                       } else $priority = 5;
+
+                                       $overrulestyle = isset($hookObj->overrulestyle) ? $hookObj->overrulestyle : 'padding-top: 4px;';
+                                       $contentArray[$priority][] = '<td class="c-menu" style="'.$overrulestyle.'">'.$tempContent.'</td>';
+                               }
+                       }
+                       ksort($contentArray);
+               }
+
+                       // If noMenuMode is set to 'icons' or if a hook was found, display menu instead of nothingness
+               if ($iconMenuMode || count($contentArray))      {
 
                                // Loading the modules for this backend user:
                        $loadModules = t3lib_div::makeInstance('t3lib_loadModules');
@@ -98,6 +121,14 @@ class SC_alt_topmenu_dummy {
                        $TBE_TEMPLATE->bodyTagId.= '-iconmenu';
                        $this->content.=$TBE_TEMPLATE->startPage('Top frame icon menu');
 
+                       if ($iconMenuMode)      {
+                               $contentArray[0][] = $alt_menuObj->topMenu($loadModules->modules,0,'',3);
+                               if ($BE_USER->isAdmin())        {
+                                       $contentArray[1][] = $alt_menuObj->adminButtons();
+                               }
+                               $contentArray[2][] = $alt_menuObj->topButtons();
+                       }
+
                                // Make menu and add it:
                        $this->content.='
 
@@ -105,10 +136,13 @@ class SC_alt_topmenu_dummy {
                                  Alternative module menu made of icons, displayed in top frame:
                                -->
                                <table border="0" cellpadding="0" cellspacing="0" id="typo3-topMenu">
-                                       <tr>
-                                               <td class="c-menu">'.$alt_menuObj->topMenu($loadModules->modules,0,'',3).'</td>
-                                               '.($BE_USER->isAdmin() ? '<td class="c-admin">'.$alt_menuObj->adminButtons().'</td>' : '').'
-                                               <td class="c-logout">'.$alt_menuObj->topButtons().'</td>
+                                       <tr>';
+
+                       foreach ($contentArray as $key=>$menucontent)   {
+                               $this->content .= implode(chr(10), $menucontent);
+                       }
+
+                       $this->content.='
                                        </tr>
                                </table>';
 
diff --git a/typo3/tab.js b/typo3/tab.js
new file mode 100644 (file)
index 0000000..6c441e6
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * This code has been copied from Project_CMS
+ * Copyright (c) 2005 by Phillip Berndt (www.pberndt.com)
+ *
+ * Extended Textarea for IE and Firefox browsers
+ * Features:
+ *  - Possibility to place tabs in <textarea> elements using a simply <TAB> key
+ *  - Auto-indenting of new lines
+ *
+ * Ported to TYPO3 by Michael Stucki <michael@typo3.org>
+ *
+ * License: GNU General Public License
+ *
+ * TYPO3 CVS ID: $Id$
+ */
+
+function checkBrowser()        {
+       browserName = navigator.appName;
+       browserVer = parseInt(navigator.appVersion);
+
+       ok=false;
+       if (browserName == "Microsoft Internet Explorer" && browserVer >= 4)    ok=true;
+       else if (browserName == "Netscape" && browserVer >= 3)  ok=true;
+
+       return ok;
+}
+
+       // Automatically change all textarea elements
+function changeTextareaElements()      {
+       if(!checkBrowser()) return false;       // Stop unless we're using IE or Netscape (includes Mozilla family)
+
+       document.textAreas = document.getElementsByTagName("textarea");
+
+       for(i=0; i<document.textAreas.length; i++)      {
+                       // Don't change if the class parameter contains "disable-tab"
+               if(document.textAreas[i].className && document.textAreas[i].className.search(/(^| )disable-tab( |$)/) != -1)    {
+                       continue;
+               } else {
+                       document.textAreas[i].textAreaID = i;
+                       makeAdvancedTextArea(document.textAreas[i]);
+                       document.textAreas[i].focus();
+               }
+       }
+}
+
+       // Wait until the document is completely loaded.
+       // Set a timeout instead of using the onLoad() event because it could be used by something else already.
+window.setTimeout("changeTextareaElements();", 200);
+
+       // Turn textarea elements into "better" ones. Actually this is just adding some lines of JavaScript...
+function makeAdvancedTextArea(textArea)        {
+       if(textArea.tagName.toLowerCase() != "textarea") return false;
+
+               // On attempt to leave the element:
+               // Do not leave if this.dontLeave is true
+       textArea.onblur = function(e)   {
+               if(!this.dontLeave) return;
+               this.dontLeave = null;
+               window.setTimeout("document.textAreas[" + this.textAreaID + "].restoreFocus()", 1);
+               return false;
+       }
+
+               // Set the focus back to the element and move the cursor to the correct position.
+       textArea.restoreFocus = function()      {
+               this.focus();
+
+               if(this.caretPos)       {
+                       this.caretPos.collapse(false);
+                       this.caretPos.select();
+               }
+       }
+
+               // Determine the current cursor position
+       textArea.getCursorPos = function()      {
+               if(this.selectionStart) {
+                       currPos = this.selectionStart;
+               } else if(this.caretPos)        {       // This is very tricky in IE :-(
+                       oldText = this.caretPos.text;
+                       finder = "--getcurrpos" + Math.round(Math.random() * 10000) + "--";
+                       this.caretPos.text += finder;
+                       currPos = this.value.indexOf(finder);
+
+                       this.caretPos.moveStart('character', -finder.length);
+                       this.caretPos.text = "";
+
+                       this.caretPos.scrollIntoView(true);
+               } else return;
+
+               return currPos;
+       }
+
+               // On tab, insert a tabulator. Otherwise, check if a slash (/) was pressed.
+       textArea.onkeydown = function(e)        {
+               if(this.selectionStart == null &! this.createTextRange) return;
+               if(!e) e = window.event;
+
+                       // Tabulator
+               if(e.keyCode == 9)      {
+                       this.dontLeave = true;
+                       this.textInsert(String.fromCharCode(9));
+               }
+
+                       // Newline
+               if(e.keyCode == 13)     {
+                       // Get the cursor position
+                       currPos = this.getCursorPos();
+
+                               // Search the last line
+                       lastLine = "";
+                       for(i=currPos-1;i>=0;i--)       {
+                               if(this.value.substring(i, i + 1) == '\n') break;
+                       }
+                       lastLine = this.value.substring(i + 1, currPos);
+
+                               // Search for whitespaces in the current line
+                       whiteSpace = "";
+                       for(i=0;i<lastLine.length;i++)  {
+                               if(lastLine.substring(i, i + 1) == '\t') whiteSpace += "\t";
+                               else if(lastLine.substring(i, i + 1) == ' ') whiteSpace += " ";
+                               else break;
+                       }
+
+                               // Another ugly IE hack
+                       if(navigator.appVersion.match(/MSIE/))  {
+                               whiteSpace = "\\n" + whiteSpace;
+                       }
+
+                               // Insert whitespaces
+                       window.setTimeout("document.textAreas["+this.textAreaID+"].textInsert(\""+whiteSpace+"\");", 1);
+               }
+       }
+
+               // Save the current cursor position in IE
+       textArea.onkeyup = textArea.onclick = textArea.onselect = function(e)   {
+               if(this.createTextRange)        {
+                       this.caretPos = document.selection.createRange().duplicate();
+               }
+       }
+
+               // Insert text at the current cursor position
+       textArea.textInsert = function(insertText)      {
+               if(this.selectionStart != null) {
+                       var savedScrollTop = this.scrollTop;
+                       var begin = this.selectionStart;
+                       var end = this.selectionEnd;
+                       if(end > begin + 1)     {
+                               this.value = this.value.substr(0, begin) + insertText + this.value.substr(end);
+                       } else {
+                               this.value = this.value.substr(0, begin) + insertText + this.value.substr(begin);
+                       }
+
+                       this.selectionStart = begin + insertText.length;
+                       this.selectionEnd = begin + insertText.length;
+                       this.scrollTop = savedScrollTop;
+               } else if(this.caretPos)        {
+                       this.caretPos.text = insertText;
+                       this.caretPos.scrollIntoView(true);
+               } else {
+                       text.value += insertText;
+               }
+
+               this.focus();
+       }
+}
index 39ac394..43dbdf4 100755 (executable)
@@ -629,6 +629,12 @@ class template {
                        break;
                }
 
+               $tabJScode = '';
+               if (!$BE_USER->uc['disableTabInTextarea'])      {
+                               // This loads the tabulator-in-textarea feature. It automatically modifies every textarea which is found.
+                       $tabJScode = '<script src="'.$this->backPath.'typo3/tab.js" type="text/javascript"></script>';
+               }
+
                        // Construct page header.
                $str = $headerStart.'
 <html>
@@ -639,6 +645,7 @@ class template {
        <title>'.htmlspecialchars($title).'</title>
        '.$this->docStyle().'
        '.$this->JScode.'
+       '.$tabJScode.'
        '.$this->wrapScriptTags(implode("\n", $this->JScodeArray)).'
        <!--###POSTJSMARKER###-->
 </head>