added feature #7334: Feature: New Pagetree Styling, credits Steffen Kamper
authorIngo Renner <ingo.renner@typo3.org>
Tue, 5 Feb 2008 19:34:38 +0000 (19:34 +0000)
committerIngo Renner <ingo.renner@typo3.org>
Tue, 5 Feb 2008 19:34:38 +0000 (19:34 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@3083 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/config_default.php
typo3/alt_db_navframe.php
typo3/js/tree.js [new file with mode: 0644]
typo3/stylesheet.css
typo3/sysext/lang/locallang_misc.xml
typo3/template.php
typo3/templates/alt_db_navframe.html [new file with mode: 0644]
typo3/tree.js [deleted file]

index a4f4e6b..42a4d7e 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,3 @@
-
 2008-02-04  Martin Kutschker  <martin.t.kutschker@blackbox.net>
 
        * Fixed #7391: cannot set key in $_GET with t3lib_div::_GETset()
@@ -7,11 +6,13 @@
 
        * fixed: backend.php closed body and html elements two times
        * removd ugly background color from buttons in the docheader
+       * moved t3skin arrow icons to main typo3/gfx folder
+       * added feature #7334: Feature: New Pagetree Styling, credits Steffen Kamper
 
 2008-02-05  Oliver Hader  <oh@inpublica.de>
 
        * (tweak) Followup to #6472: Some small changes to the new hooks
-       * !!! (feature) Added feature #7370: Remove page doktypes '2' & '5' ('advanced' & 'not in menu') and merge them with 'normal' doktype '1' (patch by Steffen Kamper) 
+       * !!! (feature) Added feature #7370: Remove page doktypes '2' & '5' ('advanced' & 'not in menu') and merge them with 'normal' doktype '1' (patch by Steffen Kamper)
        * (feature) Added feature #7369: Hook for manipulating the cHash
 
 2008-02-04 Jeff Segars <jeff@webempoweredchurch.org>
index 9c58b88..7940610 100755 (executable)
@@ -173,18 +173,19 @@ $TYPO3_CONF_VARS = Array(
                'explicitConfirmationOfTranslation' => FALSE,   // If set, the the diff-data of localized records is not saved automatically when updated by requires that a translator clicks the special finish_translation/save/close button that becomes available.
                'elementVersioningOnly' => FALSE,               // If true, only element versioning is allowed in the backend. This is recommended for new installations of TYPO3 4.2+ since "page" and "branch" versioning types are known for the drawbacks of loosing ids and "element" type versions supports moving now.
                'AJAX' => array(                                // array of key-value pairs for a unified use of AJAX calls in the TYPO3 backend. Keys are the unique ajaxIDs where the value will be resolved to call a method in an object. See ajax.php and the classes/class.typo3ajax.php for more information.
-                       'SC_alt_db_navframe::expandCollapse'   => 'typo3/alt_db_navframe.php:SC_alt_db_navframe->ajaxExpandCollapse',
-                       'SC_alt_file_navframe::expandCollapse' => 'typo3/alt_file_navframe.php:SC_alt_file_navframe->ajaxExpandCollapse',
-                       't3lib_TCEforms_inline::createNewRecord'                => 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
+                       'SC_alt_db_navframe::expandCollapse'                => 'typo3/alt_db_navframe.php:SC_alt_db_navframe->ajaxExpandCollapse',
+                       'SC_alt_db_navframe::saveFilterboxStatus'           => 'typo3/alt_db_navframe.php:SC_alt_db_navframe->ajaxSaveFilterboxStatus',
+                       'SC_alt_file_navframe::expandCollapse'              => 'typo3/alt_file_navframe.php:SC_alt_file_navframe->ajaxExpandCollapse',
+                       't3lib_TCEforms_inline::createNewRecord'                    => 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
                        't3lib_TCEforms_inline::synchronizeLocalizeRecords'     => 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
                        't3lib_TCEforms_inline::setExpandedCollapsedState'      => 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
-                       'ShortcutMenu::getGroups'              => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->getAjaxShortcutGroups',
-                       'ShortcutMenu::saveShortcut'           => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->setAjaxShortcut',
-                       'ShortcutMenu::render'                 => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->renderAjax',
-                       'ShortcutMenu::delete'                 => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->deleteAjaxShortcut',
-                       'ShortcutMenu::create'                 => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->createAjaxShortcut',
-                       'ModuleMenu::saveMenuState'            => 'typo3/classes/class.modulemenu.php:ModuleMenu->saveMenuState',
-                       'ModuleMenu::render'                   => 'typo3/classes/class.modulemenu.php:ModuleMenu->renderAjax'
+                       'ShortcutMenu::getGroups'    => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->getAjaxShortcutGroups',
+                       'ShortcutMenu::saveShortcut' => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->setAjaxShortcut',
+                       'ShortcutMenu::render'       => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->renderAjax',
+                       'ShortcutMenu::delete'       => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->deleteAjaxShortcut',
+                       'ShortcutMenu::create'       => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->createAjaxShortcut',
+                       'ModuleMenu::saveMenuState'  => 'typo3/classes/class.modulemenu.php:ModuleMenu->saveMenuState',
+                       'ModuleMenu::render'         => 'typo3/classes/class.modulemenu.php:ModuleMenu->renderAjax'
                ),
        ),
        'FE' => Array(                  // Configuration for the TypoScript frontend (FE). Nothing here relates to the administration backend!
index ae6638f..f785787 100755 (executable)
@@ -85,6 +85,8 @@ class SC_alt_db_navframe {
        var $cMR;
        var $setTempDBmount;                    // If not '' (blank) then it will clear (0) or set (>0) Temporary DB mount.
 
+       var $template;                                  // a static HTML template, usually in templates/alt_db_navframe.html
+       var $hasFilterBox;                              //depends on userTS-setting
 
        /**
         * Initialiation of the class
@@ -102,6 +104,9 @@ class SC_alt_db_navframe {
                $this->currentSubScript = t3lib_div::_GP('currentSubScript');
                $this->setTempDBmount = t3lib_div::_GP('setTempDBmount');
 
+                       // look for User setting
+               $this->hasFilterBox = !$BE_USER->getTSConfigVal('options.pageTree.hideFilter');
+
                        // Create page tree object:
                $this->pagetree = t3lib_div::makeInstance('webPageTree');
                $this->pagetree->ext_IconMode = $BE_USER->getTSConfigVal('options.pageTree.disableIconLinkToContextmenu');
@@ -146,11 +151,14 @@ class SC_alt_db_navframe {
                $this->doc->backPath = $BACK_PATH;
                $this->doc->docType  = 'xhtml_trans';
 
+                       // get HTML-Template
+               $this->template = $this->doc->getHtmlTemplate('templates/alt_db_navframe.html');
+
 
                        // Adding javascript code for AJAX (prototype), drag&drop and the pagetree as well as the click menu code
                $this->doc->getDragDropCode('pages');
                $this->doc->getContextMenuCode();
-
+               $this->doc->loadJavascriptLib('contrib/scriptaculous/scriptaculous.js?load=effects');
 
                $this->doc->JScode .= $this->doc->wrapScriptTags(
                ($this->currentSubScript?'top.currentSubScript=unescape("'.rawurlencode($this->currentSubScript).'");':'').'
@@ -169,12 +177,9 @@ class SC_alt_db_navframe {
                        '.(!$GLOBALS['CLIENT']['FORMSTYLE'] ? '' : 'if (linkObj) linkObj.blur(); ').'
                        return false;
                }
-               '.($this->cMR?"jumpTo(top.fsMod.recentIds['web'],'');":'').'
+               '.($this->cMR?"jumpTo(top.fsMod.recentIds['web'],'');":'').
 
-                       Event.observe(window, "load", function() {
-                               Event.observe(PageTreeFilter.field, "keyup", PageTreeFilter.filter.bindAsEventListener(PageTreeFilter));
-                               Event.observe(PageTreeFilter.resetfield, "click", PageTreeFilter.resetSearchField.bindAsEventListener(PageTreeFilter) );
-                       });
+                       ($this->hasFilterBox ? 'var TYPO3PageTreeFilter = new PageTreeFilter();' : '') . '
 
                ');
 
@@ -210,6 +215,42 @@ class SC_alt_db_navframe {
                                break;
                        }
 
+                       $showWorkspaceInfo = true;
+               }
+
+               //prepare onclick links
+               $onclickNewPageWizard = 'top.content.list_frame.location.href=top.TS.PATH_typo3+\'db_new.php?id=1&pagesOnly=1\';"';
+
+               $docheader = t3lib_parsehtml::getSubpart($this->template, '###DOCHEADER###');
+
+               $markers['BUTTONSLEFT'] =
+                               // Filter switch
+                       ($this->hasFilterBox ? '
+                                       <a href="#" id="toggleTreeFilter">
+                                               <img'.t3lib_iconWorks::skinImg('',$GLOBALS['BE_USER']->uc['moduleData']['pageTree']['filterBox'] ? 'gfx/arrowright.gif' : 'gfx/arrowdown.gif','width="16" height="16"').' title="show filter" alt="" />
+                                               <span>'.$LANG->sL('LLL:EXT:lang/locallang_misc.xml:pageTree_filter',1).'</span>
+                                       </a>' : '')
+               ;
+
+               $markers['BUTTONSRIGHT'] =
+                               // New Page
+                       '<a href="#" onclick="'.$onclickNewPageWizard.'"><img'.t3lib_iconWorks::skinImg('','gfx/new_page.gif','width="13" height="12"').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.refresh',1).'" alt="" /></a>'.
+
+                               // Refresh-Icon
+                       '<a href="'.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'"><img'.t3lib_iconWorks::skinImg('','gfx/refresh_n.gif','width="14" height="14"').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.refresh',1).'" alt="" /></a>'.
+
+                               // CSH-Icon
+                       t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'pagetree', $GLOBALS['BACK_PATH'])
+
+               ;
+
+               $markers['STYLE'] = $GLOBALS['BE_USER']->uc['moduleData']['pageTree']['filterBox'] ? ' style="display:none;"' : '';
+               $markers['IMG_RESET'] = '<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/search_reset.png', ' width="11" height="11"').' id="treeFilterReset" alt="Reset Filter" />';
+
+               $this->content .= t3lib_parsehtml::substituteMarkerArray($docheader, $markers, '###|###');
+
+
+               if($showWorkspaceInfo) {
                        $this->content.= '
                                <div class="bgColor4 workspace-info">'.
                                        '<a href="'.htmlspecialchars('mod/user/ws/index.php').'" target="content">'.
@@ -219,26 +260,6 @@ class SC_alt_db_navframe {
                        ';
                }
 
-                       // adding tree options
-                       $this->content .= '
-       <div id="treeOptions">';
-               if (!$GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.hideFilter'))        {
-                       $this->content .= '
-               <div id="treeFilterBox">
-                       <input type="text" value="" name="treeFilter" id="treeFilter" />
-                       <img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/search_reset.png', ' width="11" height="11"').' id="treeFilterReset" alt="Reset Filter" />
-               </div>';
-
-               }
-
-               $this->content .= '
-               <div id="treeOptionButtons">
-                       <a href="'.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'"><img'.t3lib_iconWorks::skinImg('','gfx/refresh_n.gif','width="14" height="14"').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.refresh',1).'" alt="" /></a>'.
-                               // CSH icon:
-                       t3lib_BEfunc::cshItem('xMOD_csh_corebe', 'pagetree', $GLOBALS['BACK_PATH']).'
-               </div>
-       </div>';
-
 
                        // Outputting Temporary DB mount notice:
                if ($this->active_tempMountPoint)       {
@@ -255,7 +276,7 @@ class SC_alt_db_navframe {
 
 
                        // Outputting page tree:
-               $this->content .= $tree;
+               $this->content .= '<div id="PageTreeDiv">'.$tree.'</div>';
 
                        // Adding javascript for drag & drop activation and highlighting
                $this->content .= $this->doc->wrapScriptTags('
@@ -355,6 +376,22 @@ class SC_alt_db_navframe {
                        $ajaxObj->addContent('tree', $tree);
                }
        }
+
+       /**
+        * Makes the AJAX call to expand or collapse the filterbox.
+        * Called by typo3/ajax.php
+        *
+        * @param       array           $params: additional parameters (not used here)
+        * @param       TYPO3AJAX       &$ajaxObj: reference of the TYPO3AJAX object of this request
+        * @return      void
+        */
+       public function ajaxSaveFilterboxStatus(array $params, &$ajaxObj) {
+               $state = t3lib_div::_POST('state') === 'true' ? 1 : 0;
+
+               $GLOBALS['BE_USER']->uc['moduleData']['pageTree']['filterBox'] = $state;
+               $GLOBALS['BE_USER']->writeUC();
+       }
+
 }
 
 
diff --git a/typo3/js/tree.js b/typo3/js/tree.js
new file mode 100644 (file)
index 0000000..a83d8bc
--- /dev/null
@@ -0,0 +1,315 @@
+/***************************************************************
+*
+*  javascript functions regarding the page & folder tree
+*  relies on the javascript library "prototype"
+*
+*
+*  Copyright notice
+*
+*  (c) 2006-2008       Benjamin Mack <www.xnos.org>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 t3lib/ library provided by
+*  Kasper Skaarhoj <kasper@typo3.com> together with TYPO3
+*
+*  Released under GNU/GPL (see license file in tslib/)
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+*
+*  This copyright notice MUST APPEAR in all copies of this script
+*
+*  TYPO3 SVN ID: $Id: tree.js 2911 2008-01-15 22:49:57Z ingorenner $
+*
+***************************************************************/
+
+
+
+/**
+ *
+ * @author     Benjamin Mack
+ */
+var Tree = {
+       thisScript: 'ajax.php',
+       ajaxID: 'SC_alt_db_navframe::expandCollapse',   // has to be either "SC_alt_db_navframe::expandCollapse" or "SC_alt_file_navframe::expandCollapse"
+       frameSetModule: null,
+       activateDragDrop: true,
+       highlightClass: 'active',
+
+       // reloads a part of the page tree (useful when "expand" / "collapse")
+       load: function(params, isExpand, obj) {
+                       // fallback if AJAX is not possible (e.g. IE < 6)
+               if (typeof Ajax.getTransport() != 'object') {
+                       window.location.href = this.thisScript + '?ajaxID=' + this.ajaxID + '&PM=' + params;
+                       return;
+               }
+
+               // immediately collapse the subtree and change the plus to a minus when collapsing
+               // without waiting for the response
+               if (!isExpand) {
+                       var ul = obj.parentNode.getElementsByTagName('ul')[0];
+                       obj.parentNode.removeChild(ul); // no remove() directly because of IE 5.5
+                       var pm = Selector.findChildElements(obj.parentNode, ['.pm'])[0]; // Getting pm object by CSS selector (because document.getElementsByClassName() doesn't seem to work on Konqueror)
+                       if (pm) {
+                               pm.onclick = null;
+                               Element.cleanWhitespace(pm);
+                               pm.firstChild.src = pm.firstChild.src.replace('minus', 'plus');
+                       }
+               } else {
+                       obj.style.cursor = 'wait';
+               }
+
+               new Ajax.Request(this.thisScript, {
+                       method: 'get',
+                       parameters: 'ajaxID=' + this.ajaxID + '&PM=' + params,
+                       onComplete: function(xhr) {
+                               // the parent node needs to be overwritten, not the object
+                               $(obj.parentNode).replace(xhr.responseText);
+                               this.registerDragDropHandlers();
+                               this.reSelectActiveItem();
+                               filter($('_livesearch').value);
+                       }.bind(this),
+                       onT3Error: function(xhr) {
+                               // if this is not a valid ajax response, the whole page gets refreshed
+                               this.refresh();
+                       }.bind(this)
+               });
+       },
+
+       // does the complete page refresh (previously known as "_refresh_nav()")
+       refresh: function() {
+               var r = new Date();
+               // randNum is useful so pagetree does not get cached in browser cache when refreshing
+               window.location.href = '?randNum=' + r.getTime();
+       },
+
+       // attaches the events to the elements needed for the drag and drop (for the titles and the icons)
+       registerDragDropHandlers: function() {
+               if (!this.activateDragDrop) return;
+               this._registerDragDropHandlers('dragTitle');
+               this._registerDragDropHandlers('dragIcon');
+       },
+
+       _registerDragDropHandlers: function(className) {
+               var elements = Selector.findChildElements($('tree'), ['.'+className]); // using Selector because document.getElementsByClassName() doesn't seem to work on Konqueror
+               for (var i = 0; i < elements.length; i++) {
+                       Event.observe(elements[i], 'mousedown', function(event) { DragDrop.dragElement(event); }, true);
+                       Event.observe(elements[i], 'dragstart', function(event) { DragDrop.dragElement(event); }, false);
+                       Event.observe(elements[i], 'mouseup',   function(event) { DragDrop.dropElement(event); }, false);
+               }
+       },
+
+       // selects the activated item again, in case it collapsed and got expanded again
+       reSelectActiveItem: function() {
+               obj = $(top.fsMod.navFrameHighlightedID[this.frameSetModule]);
+               if (obj) Element.addClassName(obj, this.highlightClass);
+       },
+
+       // highlights an active list item in the page tree and registers it to the top-frame
+       // used when loading the page for the first time
+       highlightActiveItem: function(frameSetModule, highlightID) {
+               this.frameSetModule = frameSetModule;
+
+               // Remove all items that are already highlighted
+               obj = $(top.fsMod.navFrameHighlightedID[frameSetModule]);
+               if (obj) {
+                       var classes = $w(this.highlightClass);
+                       for (var i = 0; i < classes.length; i++)
+                               Element.removeClassName(obj, classes[i]);
+               }
+
+               // Set the new item
+               top.fsMod.navFrameHighlightedID[frameSetModule] = highlightID;
+               if ($(highlightID)) Element.addClassName(highlightID, this.highlightClass);
+       }
+};
+
+
+
+// new object-oriented drag and drop - code,
+// tested in IE 6, Firefox 2, Opera 9
+var DragDrop = {
+       dragID: null,
+
+       // options needed for doing the changes when dropping
+       table: null,    // can be "pages" or "folders"
+       changeURL: null,
+       backPath: null,
+
+
+       dragElement: function(event, elementID) {
+               Event.stop(event); // stop bubbling
+               this.dragID = this.getIdFromEvent(event);
+               if (this.dragID == 0) return false;
+
+               if (!elementID) elementID = this.dragID;
+               if (!$('dragIcon')) this.addDragIcon();
+
+               $('dragIcon').innerHTML = $('dragIconID_'+elementID).innerHTML
+                                                               + $('dragTitleID_'+elementID).firstChild.innerHTML;
+
+               document.onmouseup   = function(event) { DragDrop.cancelDragEvent(event); };
+               document.onmousemove = function(event) { DragDrop.mouseMoveEvent(event); };
+               return false;
+       },
+
+       dropElement: function(event) {
+               var dropID = this.getIdFromEvent(event);
+               if ((this.dragID) && (this.dragID != dropID)) {
+                       var url = this.changeURL
+                                   + '?dragDrop=' + this.table
+                                       + '&srcId=' + this.dragID
+                                       + '&dstId=' + dropID;
+                                       + '&backPath=' + this.backPath;
+                       showClickmenu_raw(url);
+               }
+               this.cancelDragEvent();
+               return false;
+       },
+
+
+       cancelDragEvent: function(event) {
+               this.dragID = null;
+               if ($('dragIcon') && $('dragIcon').style.visibility == 'visible') {
+                       $('dragIcon').style.visibility = 'hidden';
+               }
+
+               document.onmouseup = null;
+               document.onmousemove = null;
+       },
+
+       mouseMoveEvent: function(event) {
+               if (!event) {
+                       event = window.event;
+               }
+               $('dragIcon').style.left = (Event.pointerX(event) + 5) + 'px';
+               $('dragIcon').style.top  = (Event.pointerY(event) - 5) + 'px';
+               $('dragIcon').style.visibility = 'visible';
+               return false;
+       },
+
+
+       // -- helper functions --
+       getIdFromEvent: function(event) {
+               var obj = Event.element(event);
+               while (obj.id == false && obj.parentNode) { obj = obj.parentNode; }
+               return obj.id.substring(obj.id.indexOf('_')+1);
+       },
+
+       // dynamically manipulates the DOM to add the div needed for drag&drop at the bottom of the <body>-tag
+       addDragIcon: function() {
+               var code = '<div id="dragIcon" style="visibility: hidden;">&nbsp;</div>';
+               new Insertion.Bottom(document.getElementsByTagName('body')[0], code);
+       }
+};
+
+
+
+/**
+ *
+ * @author     Ingo Renner <ingo@typo3.org>
+ **/
+var PageTreeFilter = Class.create({
+       field: 'treeFilter',
+       resetfield: 'treeFilterReset',
+       togglelink: 'toggleTreeFilter',
+
+       /**
+        * constructor with event listener
+        */
+       initialize: function() {
+                       // event listener
+               Event.observe(document, 'dom:loaded', function(){
+                       Event.observe(this.field, "keyup", this.filter.bindAsEventListener(this));
+                       Event.observe(this.resetfield, "click", this.resetSearchField.bindAsEventListener(this) );
+
+                       this.toggleFilterBoxIcon = $$('#toggleTreeFilter img')[0];
+                       Event.observe(this.togglelink, "click", this.toggleFilter.bindAsEventListener(this) );
+               }.bind(this));
+       },
+
+       /**
+        * Toggles visability of the filter box
+        */
+       toggleFilter: function() {
+               var filterBox = $('typo3-docheader-row2');
+               var state     = filterBox.visible();
+
+                       // save state
+               new Ajax.Request('ajax.php', {
+                       parameters : 'ajaxID=SC_alt_db_navframe::saveFilterboxStatus&state=' + state
+               });
+
+               if (state) {
+                       Effect.BlindUp(filterBox, {duration : 0.2});
+                       this.toggleFilterBoxIcon.src = 'gfx/arrowright.gif';
+                       this.resetSearchField();
+               } else {
+                       Effect.BlindDown(filterBox, {duration : 0.1});
+                       this.toggleFilterBoxIcon.src = 'gfx/arrowdown.gif';
+               }
+       },
+
+
+
+       /**
+        * Filters the tree by setting a class on items not matching search input string
+        * tested in FF2, S3, IE6, IE7
+        */
+       filter: function() {
+               var searchString = $F(this.field).toLowerCase();
+
+               var pages = $$('#treeRoot .dragTitle a');
+               pages.each(function(el) {
+                       if (el.innerHTML.toLowerCase().include(searchString)) {
+                               el.up().removeClassName('not-found');
+                       } else {
+                               el.up().addClassName('not-found');
+                       }
+               });
+               this.toggleReset();
+
+       },
+
+
+       /**
+        * toggles the visibility of the reset button
+        */
+       toggleReset: function() {
+               var searchFieldContent = $F(this.field);
+               var resetButton = $(this.resetfield);
+
+               if (searchFieldContent != '' && resetButton.getStyle('visibility') == 'hidden') {
+                       resetButton.setStyle({ visibility: 'visible'} );
+               } else if (searchFieldContent == '' && resetButton.getStyle('visibility') == 'visible') {
+                       resetButton.setStyle( {visibility: 'hidden'} );
+               }
+       },
+
+       /**
+        * resets the search field
+        */
+       resetSearchField: function() {
+               if ($(this.resetfield).getStyle('visibility') == 'visible') {
+                       $(this.field).value = '';
+                       this.filter('');
+               }
+       }
+});
+
+
+// Call this function, refresh_nav(), from another script in the backend if you want
+// to refresh the navigation frame (eg. after having changed a page title or moved pages etc.)
+//             See t3lib_BEfunc::getSetUpdateSignal()
+// please use the function in the "Tree" object for future implementations
+function refresh_nav() {
+       window.setTimeout('Tree.refresh();',0);
+}
+
+// Deprecated since 4.1.
+// Another JS function, for highlighting rows in the page tree, kept alive for backwards
+// compatibility. Please use the function in the "Tree" object for future implementations.
+function hilight_row(frameSetModule, highLightID) {
+       Tree.highlightActiveItem(frameSetModule, highlightID);
+}
index 43b316e..e1c5cb8 100755 (executable)
@@ -289,14 +289,15 @@ UL.tree LI.active, UL.tree UL LI.active   { background-color: #ebebeb !important;
 UL.tree LI.active UL, UL.tree UL LI.active UL  { background-color: #f7f3ef; }
 #dragIcon { z-index: 1; position: absolute; visibility: hidden; filter: alpha(opacity=50); -moz-opacity:0.5; opacity:0.5; white-space: nowrap; }
 
-div#treeOptions, div#treeOptions * { float: left; }
-div#treeOptions                { width: 100%; height: 24px; background: #fff; margin: 0 0 5px; border-bottom: 1px solid #ccc; }
-div#treeFilterBox      { width: 158px; margin-top: 2px; height: 22px; background: #fff url('gfx/search_bubble.png') no-repeat 8px 0; padding-left: 10px; }
-input#treeFilter       { height: 14px; width: 120px; margin: 4px 0 0 18px !important; border: 0; }
+div#treeFilterBox      { background: url('gfx/search_bubble.png') no-repeat 8px 0; padding-left: 10px; }
+input#treeFilter       { height: 12px; width: 120px; margin: 4px 0 0 18px !important; border: 0; }
 img#treeFilterReset    { border: 0; margin: 5px 0 0 !important; cursor: pointer; visibility: hidden; }
-div#treeOptionButtons  { float: right; }
-div#treeOptionButtons a        { margin: 5px 1px 0; }
+#toggleTreeFilter span {font-weight:bold; margin-left:-4px; font-size:12px;}
+#typo3-pagetree #typo3-docheader img {margin:2px 1px;}
 
+#treeRoot {
+       margin-top: 6px;
+}
 
 /* TCEforms */
 table.typo3-TCEforms { width: 93%; border-collapse: collapse; }
@@ -370,6 +371,10 @@ BODY#typo3-alt-doc-nodoc-php { margin-left: 5px; }
 
 /* Record editing (alt_doc.php) */
 div#typo3-docheader { postion: absolute; top: 0; left: 0; z-index: 5; min-width: 260px; }
+#typo3-pagetree #typo3-docheader {
+       min-width: 0px;
+}
+
 div#typo3-docheader-row1 { height: 22px; background: #cbc7c3; }
 div#typo3-docheader-row2 { background: #e4e0db; height: 27px; line-height: 27px; border-bottom: 1px solid #000; }
 div#typo3-docheader div.buttonsleft  { margin: 0 0 0 3px; line-height: 16px; float: left; }
@@ -500,7 +505,7 @@ DL.typo3-tstemplate-ceditor-constant dd { margin-left: 0px; }
 DL.typo3-tstemplate-ceditor-constant dt { display: inline; margin-right: 5px; }
 DT.typo3-tstemplate-ceditor-label { font-size: 11px; font-weight: bold; }
 
+
 /* File > List */
 TABLE#typo3-filelist IMG { vertical-align: middle; }
 TABLE#typo3-filelist TR TD { padding-left: 1px; padding-right: 6px; }
@@ -551,7 +556,11 @@ BODY#typo3-mod-tools-em-index-php TR TD.extstate { color: #fff; font-weight: bol
 
 
 /* Workspace */
-DIV.workspace-info { padding: 0px 2px 0px 2px; margin: 0px 0px 4px 0px; border: 1px solid #999; }
+div.workspace-info {
+       padding: 0px 2px 0px 2px;
+       margin: 2px 0px 4px 0px;
+       border: 1px solid #999;
+}
 .ver-element, UL.tree UL LI.ver-element { background-color: #ccddcc; }
 .ver-page, UL.tree UL LI.ver-page { background-color: #ccccff; }
 .ver-branch, UL.tree UL LI.ver-branch { background-color: #ffcccc; }
@@ -689,5 +698,3 @@ PRE.ts-hl .ts-linenum { background-color: #eee; }
 H2,H3,H4,DIV { border: 1px dotted #666; }
 */
 
-
-
index 22864ab..48910c6 100755 (executable)
@@ -61,6 +61,7 @@
                        <label index="localize.wasRemovedInOriginal">Record was removed in original language</label>
                        <label index="localizeAllRecords">Localize all records</label>
                        <label index="synchronizeWithOriginalLanguage">Synchronize with original language</label>
+                       <label index="pageTree_filter">Filter</label>
                </languageKey>
        </data>
 </T3locallang>
\ No newline at end of file
index 1e3918f..cce2b24 100755 (executable)
@@ -1290,7 +1290,7 @@ $str.=$this->docBodyTagBegin().
        function getDragDropCode($table)        {
                $this->loadJavascriptLib('contrib/prototype/prototype.js');
                $this->loadJavascriptLib('js/common.js');
-               $this->loadJavascriptLib('tree.js');
+               $this->loadJavascriptLib('js/tree.js');
 
                        // setting prefs for drag & drop
                $this->JScodeArray['dragdrop'] = '
diff --git a/typo3/templates/alt_db_navframe.html b/typo3/templates/alt_db_navframe.html
new file mode 100644 (file)
index 0000000..a895c96
--- /dev/null
@@ -0,0 +1,16 @@
+
+<!-- ###DOCHEADER### -->
+       <!-- Page header with buttons for saving & closing and path details -->
+       <div id="typo3-docheader">
+               <div id="typo3-docheader-row1">
+            <div class="buttonsleft">###BUTTONSLEFT###</div>
+                       <div class="buttonsright">###BUTTONSRIGHT###</div>
+               </div>
+               <div id="typo3-docheader-row2"###STYLE###>
+                       <div id="treeFilterBox">
+                               <input type="text" value="" name="treeFilter" id="treeFilter" />
+                               ###IMG_RESET###
+                       </div>
+               </div>
+       </div>
+<!-- ###DOCHEADER### -->
diff --git a/typo3/tree.js b/typo3/tree.js
deleted file mode 100755 (executable)
index c86f6c7..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-/***************************************************************
-*
-*  javascript functions regarding the page & folder tree
-*  relies on the javascript library "prototype"
-*
-*
-*  Copyright notice
-*
-*  (c) 2006    Benjamin Mack <www.xnos.org>
-*  All rights reserved
-*
-*  This script is part of the TYPO3 t3lib/ library provided by
-*  Kasper Skaarhoj <kasper@typo3.com> together with TYPO3
-*
-*  Released under GNU/GPL (see license file in tslib/)
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-*
-*  This copyright notice MUST APPEAR in all copies of this script
-*
-*  TYPO3 SVN ID: $Id$
-*
-***************************************************************/
-
-
-var Tree = {
-       thisScript: 'ajax.php',
-       ajaxID: 'SC_alt_db_navframe::expandCollapse',   // has to be either "SC_alt_db_navframe::expandCollapse" or "SC_alt_file_navframe::expandCollapse"
-       frameSetModule: null,
-       activateDragDrop: true,
-       highlightClass: 'active',
-
-       // reloads a part of the page tree (useful when "expand" / "collapse")
-       load: function(params, isExpand, obj) {
-                       // fallback if AJAX is not possible (e.g. IE < 6)
-               if (typeof Ajax.getTransport() != 'object') {
-                       window.location.href = this.thisScript + '?ajaxID=' + this.ajaxID + '&PM=' + params;
-                       return;
-               }
-
-               // immediately collapse the subtree and change the plus to a minus when collapsing
-               // without waiting for the response
-               if (!isExpand) {
-                       var ul = obj.parentNode.getElementsByTagName('ul')[0];
-                       obj.parentNode.removeChild(ul); // no remove() directly because of IE 5.5
-                       var pm = Selector.findChildElements(obj.parentNode, ['.pm'])[0]; // Getting pm object by CSS selector (because document.getElementsByClassName() doesn't seem to work on Konqueror)
-                       if (pm) {
-                               pm.onclick = null;
-                               Element.cleanWhitespace(pm);
-                               pm.firstChild.src = pm.firstChild.src.replace('minus', 'plus');
-                       }
-               } else {
-                       obj.style.cursor = 'wait';
-               }
-
-               new Ajax.Request(this.thisScript, {
-                       method: 'get',
-                       parameters: 'ajaxID=' + this.ajaxID + '&PM=' + params,
-                       onComplete: function(xhr) {
-                               // the parent node needs to be overwritten, not the object
-                               $(obj.parentNode).replace(xhr.responseText);
-                               this.registerDragDropHandlers();
-                               this.reSelectActiveItem();
-                               filter($('_livesearch').value);
-                       }.bind(this),
-                       onT3Error: function(xhr) {
-                               // if this is not a valid ajax response, the whole page gets refreshed
-                               this.refresh();
-                       }.bind(this)
-               });
-       },
-
-       // does the complete page refresh (previously known as "_refresh_nav()")
-       refresh: function() {
-               var r = new Date();
-               // randNum is useful so pagetree does not get cached in browser cache when refreshing
-               window.location.href = '?randNum=' + r.getTime();
-       },
-
-       // attaches the events to the elements needed for the drag and drop (for the titles and the icons)
-       registerDragDropHandlers: function() {
-               if (!this.activateDragDrop) return;
-               this._registerDragDropHandlers('dragTitle');
-               this._registerDragDropHandlers('dragIcon');
-       },
-
-       _registerDragDropHandlers: function(className) {
-               var elements = Selector.findChildElements($('tree'), ['.'+className]); // using Selector because document.getElementsByClassName() doesn't seem to work on Konqueror
-               for (var i = 0; i < elements.length; i++) {
-                       Event.observe(elements[i], 'mousedown', function(event) { DragDrop.dragElement(event); }, true);
-                       Event.observe(elements[i], 'dragstart', function(event) { DragDrop.dragElement(event); }, false);
-                       Event.observe(elements[i], 'mouseup',   function(event) { DragDrop.dropElement(event); }, false);
-               }
-       },
-
-       // selects the activated item again, in case it collapsed and got expanded again
-       reSelectActiveItem: function() {
-               obj = $(top.fsMod.navFrameHighlightedID[this.frameSetModule]);
-               if (obj) Element.addClassName(obj, this.highlightClass);
-       },
-
-       // highlights an active list item in the page tree and registers it to the top-frame
-       // used when loading the page for the first time
-       highlightActiveItem: function(frameSetModule, highlightID) {
-               this.frameSetModule = frameSetModule;
-
-               // Remove all items that are already highlighted
-               obj = $(top.fsMod.navFrameHighlightedID[frameSetModule]);
-               if (obj) {
-                       var classes = $w(this.highlightClass);
-                       for (var i = 0; i < classes.length; i++)
-                               Element.removeClassName(obj, classes[i]);
-               }
-
-               // Set the new item
-               top.fsMod.navFrameHighlightedID[frameSetModule] = highlightID;
-               if ($(highlightID)) Element.addClassName(highlightID, this.highlightClass);
-       }
-};
-
-
-
-// new object-oriented drag and drop - code,
-// tested in IE 6, Firefox 2, Opera 9
-var DragDrop = {
-       dragID: null,
-
-       // options needed for doing the changes when dropping
-       table: null,    // can be "pages" or "folders"
-       changeURL: null,
-       backPath: null,
-
-
-       dragElement: function(event, elementID) {
-               Event.stop(event); // stop bubbling
-               this.dragID = this.getIdFromEvent(event);
-               if (this.dragID == 0) return false;
-
-               if (!elementID) elementID = this.dragID;
-               if (!$('dragIcon')) this.addDragIcon();
-
-               $('dragIcon').innerHTML = $('dragIconID_'+elementID).innerHTML
-                                                               + $('dragTitleID_'+elementID).firstChild.innerHTML;
-
-               document.onmouseup   = function(event) { DragDrop.cancelDragEvent(event); };
-               document.onmousemove = function(event) { DragDrop.mouseMoveEvent(event); };
-               return false;
-       },
-
-       dropElement: function(event) {
-               var dropID = this.getIdFromEvent(event);
-               if ((this.dragID) && (this.dragID != dropID)) {
-                       var url = this.changeURL
-                                   + '?dragDrop=' + this.table
-                                       + '&srcId=' + this.dragID
-                                       + '&dstId=' + dropID;
-                                       + '&backPath=' + this.backPath;
-                       showClickmenu_raw(url);
-               }
-               this.cancelDragEvent();
-               return false;
-       },
-
-
-       cancelDragEvent: function(event) {
-               this.dragID = null;
-               if ($('dragIcon') && $('dragIcon').style.visibility == 'visible') {
-                       $('dragIcon').style.visibility = 'hidden';
-               }
-
-               document.onmouseup = null;
-               document.onmousemove = null;
-       },
-
-       mouseMoveEvent: function(event) {
-               if (!event) {
-                       event = window.event;
-               }
-               $('dragIcon').style.left = (Event.pointerX(event) + 5) + 'px';
-               $('dragIcon').style.top  = (Event.pointerY(event) - 5) + 'px';
-               $('dragIcon').style.visibility = 'visible';
-               return false;
-       },
-
-
-       // -- helper functions --
-       getIdFromEvent: function(event) {
-               var obj = Event.element(event);
-               while (obj.id == false && obj.parentNode) { obj = obj.parentNode; }
-               return obj.id.substring(obj.id.indexOf('_')+1);
-       },
-
-       // dynamically manipulates the DOM to add the div needed for drag&drop at the bottom of the <body>-tag
-       addDragIcon: function() {
-               var code = '<div id="dragIcon" style="visibility: hidden;">&nbsp;</div>';
-               new Insertion.Bottom(document.getElementsByTagName('body')[0], code);
-       }
-};
-
-
-
-/**
- *
- * @author     Ingo Renner <ingo@typo3.org>
- **/
-var PageTreeFilter = {
-       field: 'treeFilter',
-       resetfield: 'treeFilterReset',
-
-       /**
-        * Filters the tree by setting a class on items not matching search input string
-        * tested in FF2, S3, IE6, IE7
-        */
-       filter: function() {
-               var searchString = $F(this.field).toLowerCase();
-               var pages = $$('#treeRoot .dragTitle a');
-               pages.each(function(el) {
-                       if (el.innerHTML.toLowerCase().include(searchString)) {
-                               el.up().removeClassName('not-found');
-                       } else {
-                               el.up().addClassName('not-found');
-                       }
-               });
-               this.toggleReset();
-       },
-
-
-       /**
-        * toggles the visibility of the reset button
-        */
-       toggleReset: function() {
-               var searchFieldContent = $F(this.field);
-               var resetButton = $(this.resetfield);
-
-               if (searchFieldContent != '' && resetButton.getStyle('visibility') == 'hidden') {
-                       resetButton.setStyle({ visibility: 'visible'} );
-               } else if (searchFieldContent == '' && resetButton.getStyle('visibility') == 'visible') {
-                       resetButton.setStyle( {visibility: 'hidden'} );
-               }
-       },
-
-       /**
-        * resets the search field
-        */
-       resetSearchField: function() {
-               if ($(this.resetfield).getStyle('visibility') == 'visible') {
-                       $(this.field).value = '';
-                       PageTreeFilter.filter('');
-               }
-       }
-};
-
-
-// Call this function, refresh_nav(), from another script in the backend if you want
-// to refresh the navigation frame (eg. after having changed a page title or moved pages etc.)
-//             See t3lib_BEfunc::getSetUpdateSignal()
-// please use the function in the "Tree" object for future implementations
-function refresh_nav() {
-       window.setTimeout('Tree.refresh();',0);
-}
-
-// Deprecated since 4.1.
-// Another JS function, for highlighting rows in the page tree, kept alive for backwards
-// compatibility. Please use the function in the "Tree" object for future implementations.
-function hilight_row(frameSetModule, highLightID) {
-       Tree.highlightActiveItem(frameSetModule, highlightID);
-}
-