[FEATURE] Streamline element browser in tree, upload & create folder form
[Packages/TYPO3.CMS.git] / typo3 / class.browse_links.php
old mode 100755 (executable)
new mode 100644 (file)
index eea9726..9a050c7
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  * Used from TCEFORMS an other elements
  * In other words: This is the ELEMENT BROWSER!
  *
- * $Id$
- * Revised for TYPO3 3.6 November/2003 by Kasper Skaarhoj
+ * Revised for TYPO3 3.6 November/2003 by Kasper Skårhøj
  * XHTML compliant
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  */
 /**
  * [CLASS/FUNCTION INDEX of SCRIPT]
  *
  */
 
-require_once (PATH_t3lib.'class.t3lib_browsetree.php');
-require_once (PATH_t3lib.'class.t3lib_foldertree.php');
-require_once (PATH_t3lib.'class.t3lib_stdgraphic.php');
-require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
-
 
        // Include classes
-require_once (PATH_t3lib.'class.t3lib_page.php');
-require_once (PATH_t3lib.'class.t3lib_recordlist.php');
 require_once (PATH_typo3.'/class.db_list.inc');
 require_once (PATH_typo3.'/class.db_list_extra.inc');
-require_once (PATH_t3lib.'/class.t3lib_pagetree.php');
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
 
 
 
@@ -149,7 +125,7 @@ require_once (PATH_t3lib.'/class.t3lib_pagetree.php');
 /**
  * Local version of the record list.
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
@@ -161,7 +137,8 @@ class TBE_browser_recordList extends localRecordList {
         *
         * @return      void
         */
-       function TBE_browser_recordList () {
+       function __construct() {
+               parent::__construct();
                $this->thisScript = t3lib_div::getIndpEnv('SCRIPT_NAME');
        }
 
@@ -210,17 +187,13 @@ class TBE_browser_recordList extends localRecordList {
         * @return      string
         */
        function linkWrapItems($table,$uid,$code,$row)  {
-               global $TCA, $BACK_PATH;
-
                if (!$code) {
                        $code = '<i>['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.no_title',1).']</i>';
                } else {
-                       $code = htmlspecialchars(t3lib_div::fixed_lgd_cs($code,$this->fixedL));
+                       $code = t3lib_BEfunc::getRecordTitlePrep($code, $this->fixedL);
                }
 
-               $titleCol = $TCA[$table]['ctrl']['label'];
-               $title = $row[$titleCol];
-
+               $title = t3lib_BEfunc::getRecordTitle($table,$row,FALSE,TRUE);
                $ficon = t3lib_iconWorks::getIcon($table,$row);
                $aOnClick = "return insertElement('".$table."', '".$row['uid']."', 'db', ".t3lib_div::quoteJSvalue($title).", '', '', '".$ficon."');";
                $ATag = '<a href="#" onclick="'.$aOnClick.'">';
@@ -228,7 +201,8 @@ class TBE_browser_recordList extends localRecordList {
                $ATag_e = '</a>';
 
                return $ATag.
-                               '<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/plusbullet2.gif','width="18" height="16"').' title="'.$GLOBALS['LANG']->getLL('addToList',1).'" alt="" />'.
+                               '<img' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/plusbullet2.gif', 'width="18" height="16"') .
+                               ' title="' . $GLOBALS['LANG']->getLL('addToList', 1) . '" alt="" />' .
                                $ATag_e.
                                $ATag_alt.
                                $code.
@@ -236,14 +210,14 @@ class TBE_browser_recordList extends localRecordList {
        }
 
        /**
-        * Returns the title (based on $code) of a table ($table) without a link
+        * Local version that sets allFields to TRUE to support userFieldSelect
         *
-        * @param       string          Table name
-        * @param       string          Table label
-        * @return      string          The linked table label
+        * @return      void
+        * @see fieldSelectBox
         */
-       function linkWrapTable($table,$code)    {
-               return $code;
+       function generateList() {
+               $this->allFields = TRUE;
+               parent::generateList();
        }
 }
 
@@ -255,23 +229,29 @@ class TBE_browser_recordList extends localRecordList {
 /**
  * Class which generates the page tree
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
 class localPageTree extends t3lib_browseTree {
 
        /**
+        * whether the page ID should be shown next to the title, activate through userTSconfig (options.pageTree.showPageIdWithTitle)
+        * @boolean
+        */
+       public $ext_showPageId = FALSE;
+
+       /**
         * Constructor. Just calling init()
         *
         * @return      void
         */
-       function localPageTree() {
+       function __construct() {
                $this->thisScript = t3lib_div::getIndpEnv('SCRIPT_NAME');
 
                $this->init();
 
-               $this->clause = ' AND doktype!=255'.$this->clause;
+               $this->clause = ' AND doktype!=' . t3lib_pageSelect::DOKTYPE_RECYCLER . $this->clause;
        }
 
        /**
@@ -342,7 +322,7 @@ class localPageTree extends t3lib_browseTree {
        }
 
        /**
-        * Returns true if a doktype can be linked.
+        * Returns TRUE if a doktype can be linked.
         *
         * @param       integer         Doktype value to test
         * @param       integer         uid to test.
@@ -350,7 +330,7 @@ class localPageTree extends t3lib_browseTree {
         */
        function ext_isLinkable($doktype,$uid)  {
                if ($uid && $doktype<199)       {
-                       return true;
+                       return TRUE;
                }
        }
 
@@ -379,8 +359,12 @@ class localPageTree extends t3lib_browseTree {
         * @param       array           The row for the current element
         * @return      string          The processed icon input value.
         */
-       function wrapIcon($icon,$row)   {
-               return $this->addTagAttributes($icon,' title="id='.$row['uid'].'"');
+       function wrapIcon($icon, $row) {
+               $content = $this->addTagAttributes($icon, ' title="id=' . $row['uid'] . '"');
+               if ($this->ext_showPageId) {
+                       $content .= '[' . $row['uid'] . ']&nbsp;';
+               }
+               return $content;
        }
 }
 
@@ -394,7 +378,7 @@ class localPageTree extends t3lib_browseTree {
 /**
  * Page tree for the RTE - totally the same, no changes needed. (Just for the sake of beauty - or confusion... :-)
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
@@ -411,21 +395,21 @@ class rtePageTree extends localPageTree {
 /**
  * For TBE record browser
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
 class TBE_PageTree extends localPageTree {
 
        /**
-        * Returns true if a doktype can be linked (which is always the case here).
+        * Returns TRUE if a doktype can be linked (which is always the case here).
         *
         * @param       integer         Doktype value to test
         * @param       integer         uid to test.
         * @return      boolean
         */
        function ext_isLinkable($doktype,$uid)  {
-               return true;
+               return TRUE;
        }
 
        /**
@@ -458,7 +442,7 @@ class TBE_PageTree extends localPageTree {
  * Base extension class which generates the folder tree.
  * Used directly by the RTE.
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
@@ -471,9 +455,9 @@ class localFolderTree extends t3lib_folderTree {
         *
         * @return      void
         */
-       function localFolderTree() {
+       function __construct() {
                $this->thisScript = t3lib_div::getIndpEnv('SCRIPT_NAME');
-               $this->t3lib_folderTree();
+               parent::__construct();
        }
 
        /**
@@ -493,10 +477,10 @@ class localFolderTree extends t3lib_folderTree {
        }
 
        /**
-        * Returns true if the input "record" contains a folder which can be linked.
+        * Returns TRUE if the input "record" contains a folder which can be linked.
         *
         * @param       array           Array with information about the folder element. Contains keys like title, uid, path, _title
-        * @return      boolean         True is returned if the path is found in the web-part of the server and is NOT a recycler or temp folder
+        * @return      boolean         TRUE is returned if the path is found in the web-part of the server and is NOT a recycler or temp folder
         */
        function ext_isLinkable($v)     {
                $webpath=t3lib_BEfunc::getPathType_web_nonweb($v['path']);      // Checking, if the input path is a web-path.
@@ -542,7 +526,7 @@ class localFolderTree extends t3lib_folderTree {
                        // Preparing the current-path string (if found in the listing we will see a red blinking arrow).
                if (!$GLOBALS['SOBE']->browser->curUrlInfo['value'])    {
                        $cmpPath='';
-               } else if (substr(trim($GLOBALS['SOBE']->browser->curUrlInfo['info']),-1)!='/') {
+               } elseif (substr(trim($GLOBALS['SOBE']->browser->curUrlInfo['info']),-1)!='/')  {
                        $cmpPath=PATH_site.dirname($GLOBALS['SOBE']->browser->curUrlInfo['info']).'/';
                } else {
                        $cmpPath=PATH_site.$GLOBALS['SOBE']->browser->curUrlInfo['info'];
@@ -554,7 +538,7 @@ class localFolderTree extends t3lib_folderTree {
                        $bgColorClass=($c+1)%2 ? 'bgColor' : 'bgColor-10';
 
                                // Creating blinking arrow, if applicable:
-                       if ($GLOBALS['SOBE']->browser->curUrlInfo['act']=='file' && $cmpPath==$v['row']['path'])        {
+                       if (($GLOBALS['SOBE']->browser->curUrlInfo['act'] == 'file' || $GLOBALS['SOBE']->browser->curUrlInfo['act'] == 'folder') && $cmpPath == $v['row']['path']) {
                                $arrCol='<td><img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/blinkarrow_right.gif','width="5" height="9"').' class="c-blinkArrowR" alt="" /></td>';
                                $bgColorClass='bgColor4';
                        } else {
@@ -567,7 +551,7 @@ class localFolderTree extends t3lib_folderTree {
                                // Put table row with folder together:
                        $out.='
                                <tr class="'.$bgColorClass.'">
-                                       <td nowrap="nowrap">'.$v['HTML'].$this->wrapTitle(t3lib_div::fixed_lgd_cs($v['row']['title'],$titleLen),$v['row']).'</td>
+                                       <td nowrap="nowrap">' . $v['HTML'] . $this->wrapTitle(htmlspecialchars(t3lib_div::fixed_lgd_cs($v['row']['title'], $titleLen)), $v['row']) . '</td>
                                        '.$arrCol.'
                                        <td>'.$cEbullet.'</td>
                                </tr>';
@@ -593,7 +577,7 @@ class localFolderTree extends t3lib_folderTree {
 /**
  * Folder tree for the RTE - totally the same, no changes needed. (Just for the sake of beauty - or confusion... :-)
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
@@ -609,7 +593,7 @@ class rteFolderTree extends localFolderTree {
 /**
  * For TBE File Browser
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
@@ -617,10 +601,10 @@ class TBE_FolderTree extends localFolderTree {
        var $ext_noTempRecyclerDirs=0;          // If file-drag mode is set, temp and recycler folders are filtered out.
 
        /**
-        * Returns true if the input "record" contains a folder which can be linked.
+        * Returns TRUE if the input "record" contains a folder which can be linked.
         *
         * @param       array           Array with information about the folder element. Contains keys like title, uid, path, _title
-        * @return      boolean         True is returned if the path is NOT a recycler or temp folder AND if ->ext_noTempRecyclerDirs is not set.
+        * @return      boolean         TRUE is returned if the path is NOT a recycler or temp folder AND if ->ext_noTempRecyclerDirs is not set.
         */
        function ext_isLinkable($v)     {
                if ($this->ext_noTempRecyclerDirs && (substr($v['path'],-7)=='_temp_/' || substr($v['path'],-11)=='_recycler_/'))       {
@@ -652,7 +636,7 @@ class TBE_FolderTree extends localFolderTree {
 /**
  * class for the Element Browser window.
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
@@ -663,8 +647,10 @@ class browse_links {
        var $thisScript;                // the script to link to
        var $thisConfig;                // RTE specific TSconfig
        var $setTarget;                 // Target (RTE specific)
+       var $setClass;                  // CSS Class (RTE specific)
        var $setTitle;                  // title (RTE specific)
-       var $doc;                               // Backend template object
+       var $doc;                       // Backend template object
+       var $elements = array();        // Holds information about files
 
                // GPvars:      (Input variables from outside)
        /**
@@ -708,10 +694,14 @@ class browse_links {
         * Example value: "data[pages][39][bodytext]|||tt_content|" or "data[tt_content][NEW3fba56fde763d][image]|||gif,jpg,jpeg,tif,bmp,pcx,tga,png,pdf,ai|"
         *
         * Values:
-        * 0: form field name reference
-        * 1: old/unused?
-        * 2: old/unused?
+        * 0: form field name reference, eg. "data[tt_content][123][image]"
+        * 1: htlmArea RTE parameters: editorNo:contentTypo3Language:contentTypo3Charset
+        * 2: RTE config parameters: RTEtsConfigParams
         * 3: allowed types. Eg. "tt_content" or "gif,jpg,jpeg,tif,bmp,pcx,tga,png,pdf,ai"
+        * 4: IRRE uniqueness: target level object-id to perform actions/checks on, eg. "data[79][tt_address][1][<field>][<foreign_table>]"
+        * 5: IRRE uniqueness: name of function in opener window that checks if element is already used, eg. "inline.checkUniqueElement"
+        * 6: IRRE uniqueness: name of function in opener window that performs some additional(!) action, eg. "inline.setUniqueElement"
+        * 7: IRRE uniqueness: name of function in opener window that performs action instead of using addElement/insertElement, eg. "inline.importElement"
         *
         * $pArr = explode('|',$this->bparams);
         * $formFieldName = $pArr[0];
@@ -751,9 +741,16 @@ class browse_links {
         */
        var $curUrlInfo;
 
+       /**
+        * array which holds hook objects (initialised in init() )
+        */
+       protected $hookObjects = array();
 
 
-
+       /**
+        * object for t3lib_basicFileFunctions
+        */
+       public $fileProcessor;
 
 
        /**
@@ -763,21 +760,43 @@ class browse_links {
         * @return      void
         */
        function init() {
-               global $BE_USER,$BACK_PATH;
+               global $BACK_PATH;
 
                        // Main GPvars:
-               $this->pointer = t3lib_div::_GP('pointer');
-               $this->bparams = t3lib_div::_GP('bparams');
-               $this->P = t3lib_div::_GP('P');
+               $this->pointer           = t3lib_div::_GP('pointer');
+               $this->bparams           = t3lib_div::_GP('bparams');
+               $this->P                 = t3lib_div::_GP('P');
                $this->RTEtsConfigParams = t3lib_div::_GP('RTEtsConfigParams');
-               $this->expandPage = t3lib_div::_GP('expandPage');
-               $this->expandFolder = t3lib_div::_GP('expandFolder');
-               $this->PM = t3lib_div::_GP('PM');
+               $this->expandPage        = t3lib_div::_GP('expandPage');
+               $this->expandFolder      = t3lib_div::_GP('expandFolder');
+               $this->PM                = t3lib_div::_GP('PM');
 
                        // Find "mode"
-               $this->mode=t3lib_div::_GP('mode');
+               $this->mode = t3lib_div::_GP('mode');
                if (!$this->mode)       {
-                       $this->mode='rte';
+                       $this->mode = 'rte';
+               }
+                       // Creating backend template object:
+               $this->doc = t3lib_div::makeInstance('template');
+               $this->doc->backPath = $GLOBALS['BACK_PATH'];
+                       // Load the Prototype library and browse_links.js
+               $this->doc->getPageRenderer()->loadPrototype();
+               $this->doc->loadJavascriptLib('js/browse_links.js');
+
+                       // init hook objects:
+               $this->hookObjects = array();
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['browseLinksHook'])) {
+                       foreach($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['browseLinksHook'] as $classData) {
+                               $processObject = t3lib_div::getUserObj($classData);
+
+                               if(!($processObject instanceof t3lib_browseLinksHook)) {
+                                       throw new UnexpectedValueException('$processObject must implement interface t3lib_browseLinksHook', 1195039394);
+                               }
+
+                               $parameters = array();
+                               $processObject->init($this, $parameters);
+                               $this->hookObjects[] = $processObject;
+                       }
                }
 
                        // Site URL
@@ -786,13 +805,54 @@ class browse_links {
                        // the script to link to
                $this->thisScript = t3lib_div::getIndpEnv('SCRIPT_NAME');
 
+                       // init fileProcessor
+               $this->fileProcessor = t3lib_div::makeInstance('t3lib_basicFileFunctions');
+               $this->fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
+
+
                        // CurrentUrl - the current link url must be passed around if it exists
-               if ($this->mode=='wizard')      {
-                       $currentLinkParts = t3lib_div::trimExplode(' ',$this->P['currentValue']);
-                       $this->curUrlArray = array(
-                               'target' => $currentLinkParts[1]
+               if ($this->mode == 'wizard')    {
+                       $currentValues = t3lib_div::trimExplode(LF, trim($this->P['currentValue']));
+                       if (count($currentValues) > 0) {
+                               $currentValue = array_pop($currentValues);
+                       } else {
+                               $currentValue = '';
+                       }
+                       $currentLinkParts = t3lib_div::unQuoteFilenames($currentValue, TRUE);
+                       $initialCurUrlArray = array (
+                               'href'   => $currentLinkParts[0],
+                               'target' => $currentLinkParts[1],
+                               'class'  => $currentLinkParts[2],
+                               'title'  => $currentLinkParts[3],
+                               'params'  => $currentLinkParts[4]
                        );
-                       $this->curUrlInfo=$this->parseCurUrl($this->siteURL.'?id='.$currentLinkParts[0],$this->siteURL);
+                       $this->curUrlArray = (is_array(t3lib_div::_GP('curUrl'))) ?
+                               array_merge($initialCurUrlArray, t3lib_div::_GP('curUrl')) :
+                               $initialCurUrlArray;
+                       $this->curUrlInfo = $this->parseCurUrl($this->siteURL.'?id='.$this->curUrlArray['href'], $this->siteURL);
+                       if ($this->curUrlInfo['pageid'] == 0 && $this->curUrlArray['href']) { // pageid == 0 means that this is not an internal (page) link
+                               if (file_exists(PATH_site.rawurldecode($this->curUrlArray['href'])))    { // check if this is a link to a file
+                                       if (t3lib_div::isFirstPartOfStr($this->curUrlArray['href'], PATH_site)) {
+                                               $currentLinkParts[0] = substr($this->curUrlArray['href'], strlen(PATH_site));
+                                       }
+                                       $this->curUrlInfo = $this->parseCurUrl($this->siteURL.$this->curUrlArray['href'], $this->siteURL);
+                               } elseif (strstr($this->curUrlArray['href'], '@')) { // check for email link
+                                       if (t3lib_div::isFirstPartOfStr($this->curUrlArray['href'], 'mailto:')) {
+                                               $currentLinkParts[0] = substr($this->curUrlArray['href'], 7);
+                                       }
+                                       $this->curUrlInfo = $this->parseCurUrl('mailto:'.$this->curUrlArray['href'], $this->siteURL);
+                               } else { // nothing of the above. this is an external link
+                                       if(strpos($this->curUrlArray['href'], '://') === FALSE) {
+                                               $currentLinkParts[0] = 'http://' . $this->curUrlArray['href'];
+                                       }
+                                       $this->curUrlInfo = $this->parseCurUrl($currentLinkParts[0], $this->siteURL);
+                               }
+                       } elseif (!$this->curUrlArray['href']) {
+                               $this->curUrlInfo = array();
+                               $this->act = 'page';
+                       } else {
+                               $this->curUrlInfo = $this->parseCurUrl($this->siteURL.'?id='.$this->curUrlArray['href'], $this->siteURL);
+                       }
                } else {
                        $this->curUrlArray = t3lib_div::_GP('curUrl');
                        if ($this->curUrlArray['all'])  {
@@ -809,7 +869,7 @@ class browse_links {
 
                        // Rich Text Editor specific configuration:
                $addPassOnParams='';
-               if ((string)$this->mode=='rte') {
+               if ((string)$this->mode == 'rte')       {
                        $RTEtsConfigParts = explode(':',$this->RTEtsConfigParams);
                        $addPassOnParams.='&RTEtsConfigParams='.rawurlencode($this->RTEtsConfigParams);
                        $RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($RTEtsConfigParts[5]));
@@ -817,54 +877,64 @@ class browse_links {
                }
 
                        // Initializing the target value (RTE)
-               $this->setTarget = $this->curUrlArray['target'];
+               $this->setTarget = ($this->curUrlArray['target'] != '-') ? $this->curUrlArray['target'] : '';
                if ($this->thisConfig['defaultLinkTarget'] && !isset($this->curUrlArray['target']))     {
                        $this->setTarget=$this->thisConfig['defaultLinkTarget'];
                }
 
-                       // Initializing the title value (RTE)
-               $this->setTitle = $this->curUrlArray['title'];
-
+                       // Initializing the class value (RTE)
+               $this->setClass = ($this->curUrlArray['class'] != '-') ? $this->curUrlArray['class'] : '';
 
+                       // Initializing the title value (RTE)
+               $this->setTitle = ($this->curUrlArray['title'] != '-') ? $this->curUrlArray['title'] : '';
 
-                       // Creating backend template object:
-               $this->doc = t3lib_div::makeInstance('template');
-               $this->doc->docType= 'xhtml_trans';
-               $this->doc->backPath = $BACK_PATH;
+                       // Initializing the params value
+               $this->setParams = ($this->curUrlArray['params'] != '-') ? $this->curUrlArray['params'] : '';
 
                        // BEGIN accumulation of header JavaScript:
-               $JScode = '';
-               $JScode.= '
+               $JScode = '
                                // This JavaScript is primarily for RTE/Link. jumpToUrl is used in the other cases as well...
                        var add_href="'.($this->curUrlArray['href']?'&curUrl[href]='.rawurlencode($this->curUrlArray['href']):'').'";
                        var add_target="'.($this->setTarget?'&curUrl[target]='.rawurlencode($this->setTarget):'').'";
+                       var add_class="'.($this->setClass ? '&curUrl[class]='.rawurlencode($this->setClass) : '').'";
                        var add_title="'.($this->setTitle?'&curUrl[title]='.rawurlencode($this->setTitle):'').'";
                        var add_params="'.($this->bparams?'&bparams='.rawurlencode($this->bparams):'').'";
 
                        var cur_href="'.($this->curUrlArray['href']?$this->curUrlArray['href']:'').'";
                        var cur_target="'.($this->setTarget?$this->setTarget:'').'";
+                       var cur_class = "' . ($this->setClass ? $this->setClass : '') . '";
                        var cur_title="'.($this->setTitle?$this->setTitle:'').'";
+                       var cur_params="' . ($this->setParams ? $this->setParams : '') . '";
 
-                       function setTarget(target)      {       //
+                       function browse_links_setTarget(target) {       //
                                cur_target=target;
                                add_target="&curUrl[target]="+escape(target);
                        }
-                       function setTitle(title)        {       //
+                       function browse_links_setClass(cssClass) {   //
+                               cur_class = cssClass;
+                               add_class = "&curUrl[class]=" + escape(cssClass);
+                       }
+                       function browse_links_setTitle(title)   {       //
                                cur_title=title;
                                add_title="&curUrl[title]="+escape(title);
                        }
-                       function setValue(value)        {       //
+                       function browse_links_setValue(value) { //
                                cur_href=value;
                                add_href="&curUrl[href]="+value;
                        }
+                       function browse_links_setParams(params) {       //
+                               cur_params=params;
+                               add_params="&curUrl[params]="+escape(params);
+                       }
                ';
 
-
-               if ($this->mode=='wizard')      {       // Functions used, if the link selector is in wizard mode (= TCEforms fields)
+               if ($this->mode == 'wizard')    {       // Functions used, if the link selector is in wizard mode (= TCEforms fields)
+                       if (!$this->areFieldChangeFunctionsValid() && !$this->areFieldChangeFunctionsValid(TRUE)) {
+                               $this->P['fieldChangeFunc'] = array();
+                       }
                        unset($this->P['fieldChangeFunc']['alert']);
-                       reset($this->P['fieldChangeFunc']);
                        $update='';
-                       while(list($k,$v)=each($this->P['fieldChangeFunc']))    {
+                       foreach ($this->P['fieldChangeFunc'] as $k => $v) {
                                $update.= '
                                window.opener.'.$v;
                        }
@@ -873,25 +943,37 @@ class browse_links {
                        $P2['itemName']=$this->P['itemName'];
                        $P2['formName']=$this->P['formName'];
                        $P2['fieldChangeFunc']=$this->P['fieldChangeFunc'];
+                       $P2['fieldChangeFuncHash'] = t3lib_div::hmac(serialize($this->P['fieldChangeFunc']));
+                       $P2['params']['allowedExtensions']=$this->P['params']['allowedExtensions'];
+                       $P2['params']['blindLinkOptions']=$this->P['params']['blindLinkOptions'];
                        $addPassOnParams.=t3lib_div::implodeArrayForUrl('P',$P2);
 
                        $JScode.='
                                function link_typo3Page(id,anchor)      {       //
-                                       updateValueInMainForm(id+(anchor?anchor:"")+" "+cur_target);
+                                       updateValueInMainForm(id + (anchor ? anchor : ""));
                                        close();
                                        return false;
                                }
                                function link_folder(folder)    {       //
-                                       updateValueInMainForm(folder+" "+cur_target);
+                                       updateValueInMainForm(folder);
                                        close();
                                        return false;
                                }
                                function link_current() {       //
                                        if (cur_href!="http://" && cur_href!="mailto:") {
-                                               var setValue = cur_href+" "+cur_target+" "+cur_title;
-                                               if (setValue.substr(0,7)=="http://")    setValue = setValue.substr(7);
-                                               if (setValue.substr(0,7)=="mailto:")    setValue = setValue.substr(7);
-                                               updateValueInMainForm(setValue);
+                                               returnBeforeCleaned = cur_href;
+                                               if (returnBeforeCleaned.substr(0, 7) == "http://") {
+                                                       returnToMainFormValue = returnBeforeCleaned.substr(7);
+                                               } else if (returnBeforeCleaned.substr(0, 7) == "mailto:") {
+                                                       if (returnBeforeCleaned.substr(0, 14) == "mailto:mailto:") {
+                                                               returnToMainFormValue = returnBeforeCleaned.substr(14);
+                                                       } else {
+                                                               returnToMainFormValue = returnBeforeCleaned.substr(7);
+                                                       }
+                                               } else {
+                                                       returnToMainFormValue = returnBeforeCleaned;
+                                               }
+                                               updateValueInMainForm(returnToMainFormValue);
                                                close();
                                        }
                                        return false;
@@ -906,7 +988,32 @@ class browse_links {
                                function updateValueInMainForm(input)   {       //
                                        var field = checkReference();
                                        if (field)      {
-                                               field.value = input;
+                                               if (cur_target == "" && (cur_class != "" || cur_title != "" || cur_params != "")) {
+                                                       cur_target = "-";
+                                               }
+                                               if (cur_class == "" && (cur_title != "" || cur_params != "")) {
+                                                       cur_class = "-";
+                                               }
+                                               cur_class = cur_class.replace(/[\'\"]/g, "");
+                                               if (cur_class.indexOf(" ") != -1) {
+                                                       cur_class = "\"" + cur_class + "\"";
+                                               }
+                                               if (cur_title == "" && cur_params != "") {
+                                                       cur_title = "-";
+                                               }
+                                               cur_title = cur_title.replace(/(^\")|(\"$)/g, "");
+                                               if (cur_title.indexOf(" ") != -1) {
+                                                       cur_title = "\"" + cur_title + "\"";
+                                               }
+                                               if (cur_params) {
+                                                       cur_params = cur_params.replace(/\bid\=.*?(\&|$)/, "");
+                                               }
+                                               input = input + " " + cur_target + " " + cur_class + " " + cur_title + " " + cur_params;
+                                               if(field.value && field.className.search(/textarea/) != -1) {
+                                                       field.value += "\n" + input;
+                                               } else {
+                                                       field.value = input;
+                                               }
                                                '.$update.'
                                        }
                                }
@@ -915,21 +1022,21 @@ class browse_links {
                        $JScode.='
                                function link_typo3Page(id,anchor)      {       //
                                        var theLink = \''.$this->siteURL.'?id=\'+id+(anchor?anchor:"");
-                                       self.parent.parent.renderPopup_addLink(theLink,cur_target,cur_title);
+                                       self.parent.parent.renderPopup_addLink(theLink, cur_target, cur_class, cur_title);
                                        return false;
                                }
                                function link_folder(folder)    {       //
                                        var theLink = \''.$this->siteURL.'\'+folder;
-                                       self.parent.parent.renderPopup_addLink(theLink,cur_target,cur_title);
+                                       self.parent.parent.renderPopup_addLink(theLink, cur_target, cur_class, cur_title);
                                        return false;
                                }
                                function link_spec(theLink)     {       //
-                                       self.parent.parent.renderPopup_addLink(theLink,cur_target,cur_title);
+                                       self.parent.parent.renderPopup_addLink(theLink, cur_target, cur_class, cur_title);
                                        return false;
                                }
                                function link_current() {       //
                                        if (cur_href!="http://" && cur_href!="mailto:") {
-                                               self.parent.parent.renderPopup_addLink(cur_href,cur_target,cur_title);
+                                               self.parent.parent.renderPopup_addLink(cur_href, cur_target, cur_class, cur_title);
                                        }
                                        return false;
                                }
@@ -941,16 +1048,77 @@ class browse_links {
                        function jumpToUrl(URL,anchor)  {       //
                                var add_act = URL.indexOf("act=")==-1 ? "&act='.$this->act.'" : "";
                                var add_mode = URL.indexOf("mode=")==-1 ? "&mode='.$this->mode.'" : "";
-                               var theLocation = URL+add_act+add_mode+add_href+add_target+add_title+add_params'.($addPassOnParams?'+"'.$addPassOnParams.'"':'').'+(anchor?anchor:"");
+                               var theLocation = URL + add_act + add_mode + add_href + add_target + add_class + add_title + add_params'.($addPassOnParams?'+"'.$addPassOnParams.'"':'').'+(anchor?anchor:"");
                                window.location.href = theLocation;
                                return false;
                        }
                ';
 
 
-                       // This is JavaScript especially for the TBE Element Browser!
+               /**
+                * Splits parts of $this->bparams
+                * @see $bparams
+                */
                $pArr = explode('|',$this->bparams);
+
+                       // This is JavaScript especially for the TBE Element Browser!
                $formFieldName = 'data['.$pArr[0].']['.$pArr[1].']['.$pArr[2].']';
+
+                       // insertElement - Call check function (e.g. for uniqueness handling):
+               if ($pArr[4] && $pArr[5]) {
+                       $JScodeCheck = '
+                                       // Call a check function in the opener window (e.g. for uniqueness handling):
+                               if (parent.window.opener) {
+                                       var res = parent.window.opener.'.$pArr[5].'("'.addslashes($pArr[4]).'",table,uid,type);
+                                       if (!res.passed) {
+                                               if (res.message) alert(res.message);
+                                               performAction = false;
+                                       }
+                               } else {
+                                       alert("Error - reference to main window is not set properly!");
+                                       parent.close();
+                               }
+                       ';
+               }
+                       // insertElement - Call helper function:
+               if ($pArr[4] && $pArr[6]) {
+                       $JScodeHelper = '
+                                               // Call helper function to manage data in the opener window:
+                                       if (parent.window.opener) {
+                                               parent.window.opener.'.$pArr[6].'("'.addslashes($pArr[4]).'",table,uid,type,"'.addslashes($pArr[0]).'");
+                                       } else {
+                                               alert("Error - reference to main window is not set properly!");
+                                               parent.close();
+                                       }
+                       ';
+               }
+                       // insertElement - perform action commands:
+               if ($pArr[4] && $pArr[7]) {
+                               // Call user defined action function:
+                       $JScodeAction = '
+                                       if (parent.window.opener) {
+                                               parent.window.opener.'.$pArr[7].'("'.addslashes($pArr[4]).'",table,uid,type);
+                                               focusOpenerAndClose(close);
+                                       } else {
+                                               alert("Error - reference to main window is not set properly!");
+                                               parent.close();
+                                       }
+                       ';
+               } elseif ($pArr[0] && !$pArr[1] && !$pArr[2]) {
+                       $JScodeAction = '
+                                       addElement(filename,table+"_"+uid,fp,close);
+                       ';
+               } else {
+                       $JScodeAction = '
+                                       if (setReferences()) {
+                                               parent.window.opener.group_change("add","'.$pArr[0].'","'.$pArr[1].'","'.$pArr[2].'",elRef,targetDoc);
+                                       } else {
+                                               alert("Error - reference to main window is not set properly!");
+                                       }
+                                       focusOpenerAndClose(close);
+                       ';
+               }
+
                $JScode.='
                        var elRef="";
                        var targetDoc="";
@@ -963,11 +1131,7 @@ class browse_links {
                                }
                        }
                        function setReferences()        {       //
-                               if (parent.window.opener
-                               && parent.window.opener.content
-                               && parent.window.opener.content.document.editform
-                               && parent.window.opener.content.document.editform["'.$formFieldName.'"]
-                                               ) {
+                               if (parent.window.opener && parent.window.opener.content && parent.window.opener.content.document.editform && parent.window.opener.content.document.editform["'.$formFieldName.'"]) {
                                        targetDoc = parent.window.opener.content.document;
                                        elRef = targetDoc.editform["'.$formFieldName.'"];
                                        return true;
@@ -976,37 +1140,30 @@ class browse_links {
                                }
                        }
                        function insertElement(table, uid, type, filename,fp,filetype,imagefile,action, close)  {       //
-                               if (1=='.($pArr[0]&&!$pArr[1]&&!$pArr[2] ? 1 : 0).')    {
-                                       addElement(filename,table+"_"+uid,fp,close);
-                               } else {
-                                       if (setReferences())    {
-                                               parent.window.opener.group_change("add","'.$pArr[0].'","'.$pArr[1].'","'.$pArr[2].'",elRef,targetDoc);
-                                       } else {
-                                               alert("Error - reference to main window is not set properly!");
-                                       }
-                                       if (close)      {
-                                               parent.window.opener.focus();
-                                               parent.close();
-                                       }
+                               var performAction = true;
+                               '.$JScodeCheck.'
+                                       // Call performing function and finish this action:
+                               if (performAction) {
+                                               '.$JScodeHelper.$JScodeAction.'
                                }
                                return false;
                        }
                        function addElement(elName,elValue,altElValue,close)    {       //
                                if (parent.window.opener && parent.window.opener.setFormValueFromBrowseWin)     {
                                        parent.window.opener.setFormValueFromBrowseWin("'.$pArr[0].'",altElValue?altElValue:elValue,elName);
-                                       if (close)      {
-                                               parent.window.opener.focus();
-                                               parent.close();
-                                       }
+                                       focusOpenerAndClose(close);
                                } else {
                                        alert("Error - reference to main window is not set properly!");
                                        parent.close();
                                }
                        }
+                       function focusOpenerAndClose(close)     {       //
+                               BrowseLinks.focusOpenerAndClose(close);
+                       }
                ';
 
                        // Finally, add the accumulated JavaScript to the template object:
-               $this->doc->JScode = $this->doc->wrapScriptTags($JScode);
+               $this->doc->JScode.= $this->doc->wrapScriptTags($JScode);
 
                        // Debugging:
                if (FALSE) debug(array(
@@ -1033,22 +1190,23 @@ class browse_links {
         * @return      array           Session data and boolean which indicates that data needs to be stored in session because it's changed
         */
        function processSessionData($data) {
-               $store = false;
+               $store = FALSE;
 
                switch((string)$this->mode)     {
                        case 'db':
                                if (isset($this->expandPage))   {
                                        $data['expandPage']=$this->expandPage;
-                                       $store = true;
+                                       $store = TRUE;
                                } else {
                                        $this->expandPage=$data['expandPage'];
                                }
                        break;
                        case 'file':
                        case 'filedrag':
+                       case 'folder':
                                if (isset($this->expandFolder)) {
                                        $data['expandFolder']=$this->expandFolder;
-                                       $store = true;
+                                       $store = TRUE;
                                } else {
                                        $this->expandFolder=$data['expandFolder'];
                                }
@@ -1076,13 +1234,26 @@ class browse_links {
         * @return      string          Modified content variable.
         */
        function main_rte($wiz=0)       {
-               global $LANG, $BACK_PATH;
+               global $BACK_PATH;
 
                        // Starting content:
                $content=$this->doc->startPage('RTE link');
 
                        // Initializing the action value, possibly removing blinded values etc:
-               $allowedItems = array_diff(explode(',','page,file,url,mail,spec'),t3lib_div::trimExplode(',',$this->thisConfig['blindLinkOptions'],1));
+               $allowedItems = array_diff(
+                       explode(',','page,file,folder,url,mail,spec'),
+                       t3lib_div::trimExplode(',',$this->thisConfig['blindLinkOptions'],1)
+               );
+               $allowedItems = array_diff(
+                       $allowedItems,
+                       t3lib_div::trimExplode(',',$this->P['params']['blindLinkOptions'])
+               );
+
+                       //call hook for extra options
+               foreach($this->hookObjects as $hookObject) {
+                       $allowedItems = $hookObject->addAllowedItems($allowedItems);
+               }
+
                reset($allowedItems);
                if (!in_array($this->act,$allowedItems))        $this->act = current($allowedItems);
 
@@ -1090,46 +1261,57 @@ class browse_links {
                $menuDef = array();
                if (!$wiz)      {
                        $menuDef['removeLink']['isActive'] = $this->act=='removeLink';
-                       $menuDef['removeLink']['label'] = $LANG->getLL('removeLink',1);
+                       $menuDef['removeLink']['label'] = $GLOBALS['LANG']->getLL('removeLink', 1);
                        $menuDef['removeLink']['url'] = '#';
                        $menuDef['removeLink']['addParams'] = 'onclick="self.parent.parent.renderPopup_unLink();return false;"';
                }
                if (in_array('page',$allowedItems)) {
                        $menuDef['page']['isActive'] = $this->act=='page';
-                       $menuDef['page']['label'] = $LANG->getLL('page',1);
+                       $menuDef['page']['label'] = $GLOBALS['LANG']->getLL('page', 1);
                        $menuDef['page']['url'] = '#';
                        $menuDef['page']['addParams'] = 'onclick="jumpToUrl(\'?act=page\');return false;"';
                }
                if (in_array('file',$allowedItems)){
                        $menuDef['file']['isActive'] = $this->act=='file';
-                       $menuDef['file']['label'] = $LANG->getLL('file',1);
+                       $menuDef['file']['label'] = $GLOBALS['LANG']->getLL('file', 1);
                        $menuDef['file']['url'] = '#';
                        $menuDef['file']['addParams'] = 'onclick="jumpToUrl(\'?act=file\');return false;"';
                }
+               if (in_array('folder',$allowedItems)){
+                       $menuDef['folder']['isActive']  = $this->act == 'folder';
+                       $menuDef['folder']['label']     = $GLOBALS['LANG']->getLL('folder', 1);
+                       $menuDef['folder']['url']       = '#';
+                       $menuDef['folder']['addParams'] = 'onclick="jumpToUrl(\'?act=folder\');return false;"';
+               }
                if (in_array('url',$allowedItems)) {
                        $menuDef['url']['isActive'] = $this->act=='url';
-                       $menuDef['url']['label'] = $LANG->getLL('extUrl',1);
+                       $menuDef['url']['label'] = $GLOBALS['LANG']->getLL('extUrl', 1);
                        $menuDef['url']['url'] = '#';
                        $menuDef['url']['addParams'] = 'onclick="jumpToUrl(\'?act=url\');return false;"';
                }
                if (in_array('mail',$allowedItems)) {
                        $menuDef['mail']['isActive'] = $this->act=='mail';
-                       $menuDef['mail']['label'] = $LANG->getLL('email',1);
+                       $menuDef['mail']['label'] = $GLOBALS['LANG']->getLL('email', 1);
                        $menuDef['mail']['url'] = '#';
                        $menuDef['mail']['addParams'] = 'onclick="jumpToUrl(\'?act=mail\');return false;"';
                }
                if (is_array($this->thisConfig['userLinks.']) && in_array('spec',$allowedItems)) {
                        $menuDef['spec']['isActive'] = $this->act=='spec';
-                       $menuDef['spec']['label'] = $LANG->getLL('special',1);
+                       $menuDef['spec']['label'] = $GLOBALS['LANG']->getLL('special', 1);
                        $menuDef['spec']['url'] = '#';
                        $menuDef['spec']['addParams'] = 'onclick="jumpToUrl(\'?act=spec\');return false;"';
                }
+
+                       // call hook for extra options
+               foreach($this->hookObjects as $hookObject) {
+                       $menuDef = $hookObject->modifyMenuDefinition($menuDef);
+               }
+
                $content .= $this->doc->getTabMenuRaw($menuDef);
 
                        // Adding the menu and header to the top of page:
                $content.=$this->printCurrentUrl($this->curUrlInfo['info']).'<br />';
 
-
                        // Depending on the current action we will create the actual module content for selecting a link:
                switch($this->act)      {
                        case 'mail':
@@ -1141,9 +1323,9 @@ class browse_links {
                                        <form action="" name="lurlform" id="lurlform">
                                                <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkMail">
                                                        <tr>
-                                                               <td>'.$GLOBALS['LANG']->getLL('emailAddress',1).':</td>
+                                                               <td style="width: 96px;">' . $GLOBALS['LANG']->getLL('emailAddress', 1) . ':</td>
                                                                <td><input type="text" name="lemail"'.$this->doc->formWidth(20).' value="'.htmlspecialchars($this->curUrlInfo['act']=='mail'?$this->curUrlInfo['info']:'').'" /> '.
-                                                                       '<input type="submit" value="'.$GLOBALS['LANG']->getLL('setLink',1).'" onclick="setTarget(\'\');setValue(\'mailto:\'+document.lurlform.lemail.value); return link_current();" /></td>
+                                                                       '<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', 1) . '" onclick="browse_links_setTarget(\'\');browse_links_setValue(\'mailto:\'+document.lurlform.lemail.value); return link_current();" /></td>
                                                        </tr>
                                                </table>
                                        </form>';
@@ -1158,35 +1340,43 @@ class browse_links {
                                        <form action="" name="lurlform" id="lurlform">
                                                <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkURL">
                                                        <tr>
-                                                               <td>URL:</td>
-                                                               <td><input type="text" name="lurl"'.$this->doc->formWidth(20).' value="'.htmlspecialchars($this->curUrlInfo['act']=='url'?$this->curUrlInfo['info']:'http://').'" /> '.
-                                                                       '<input type="submit" value="'.$GLOBALS['LANG']->getLL('setLink',1).'" onclick="setValue(document.lurlform.lurl.value); return link_current();" /></td>
+                                                               <td style="width: 96px;">URL:</td>
+                                                               <td><input type="text" name="lurl"'.$this->doc->formWidth(30).' value="'.htmlspecialchars($this->curUrlInfo['act']=='url'?$this->curUrlInfo['info']:'http://').'" /> '.
+                                                                       '<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', 1) . '" onclick="browse_links_setValue(document.lurlform.lurl.value); return link_current();" /></td>
                                                        </tr>
                                                </table>
                                        </form>';
                                $content.=$extUrl;
                        break;
                        case 'file':
-                               $foldertree = t3lib_div::makeInstance('rteFolderTree');
+                       case 'folder':
+                               $foldertree             = t3lib_div::makeInstance('rteFolderTree');
                                $foldertree->thisScript = $this->thisScript;
-                               $tree=$foldertree->getBrowsableTree();
-
-                               if (!$this->curUrlInfo['value'] || $this->curUrlInfo['act']!='file')    {
-                                       $cmpPath='';
-                               } elseif (substr(trim($this->curUrlInfo['info']),-1)!='/')      {
-                                       $cmpPath=PATH_site.dirname($this->curUrlInfo['info']).'/';
-                                       if (!isset($this->expandFolder))                        $this->expandFolder = $cmpPath;
+                               $tree                   = $foldertree->getBrowsableTree();
+
+                               if (!$this->curUrlInfo['value'] || $this->curUrlInfo['act'] != $this->act)      {
+                                       $cmpPath = '';
+                               } elseif (substr(trim($this->curUrlInfo['info']), -1) != '/')   {
+                                       $cmpPath = PATH_site.dirname($this->curUrlInfo['info']).'/';
+                                       if (!isset($this->expandFolder)) {
+                                               $this->expandFolder = $cmpPath;
+                                       }
                                } else {
-                                       $cmpPath=PATH_site.$this->curUrlInfo['info'];
+                                       $cmpPath = PATH_site.$this->curUrlInfo['info'];
+                                       if (!isset($this->expandFolder) && $this->curUrlInfo['act'] == 'folder') {
+                                               $this->expandFolder = $cmpPath;
+                                       }
                                }
 
-                               list(,,$specUid) = explode('_',$this->PM);
-                               $files = $this->expandFolder($foldertree->specUIDmap[$specUid]);
-
+                               list(, , $specUid) = explode('_', $this->PM);
+                               $files = $this->expandFolder(
+                                       $foldertree->specUIDmap[$specUid],
+                                       $this->P['params']['allowedExtensions']
+                               );
                                $content.= '
 
                        <!--
-                               Wrapper table for folder tree / file list:
+                               Wrapper table for folder tree / file/folder list:
                        -->
                                        <table border="0" cellpadding="0" cellspacing="0" id="typo3-linkFiles">
                                                <tr>
@@ -1200,8 +1390,7 @@ class browse_links {
                                if (is_array($this->thisConfig['userLinks.']))  {
                                        $subcats=array();
                                        $v=$this->thisConfig['userLinks.'];
-                                       reset($v);
-                                       while(list($k2)=each($v))       {
+                                       foreach ($v as $k2 => $value) {
                                                $k2i = intval($k2);
                                                if (substr($k2,-1)=='.' && is_array($v[$k2i.'.']))      {
 
@@ -1210,14 +1399,14 @@ class browse_links {
                                                        if (!$title)    {
                                                                $title=$v[$k2i.'.']['url'];
                                                        } else {
-                                                               $title=$LANG->sL($title);
+                                                               $title = $GLOBALS['LANG']->sL($title);
                                                        }
                                                                // Description:
-                                                       $description=$v[$k2i.'.']['description'] ? $LANG->sL($v[$k2i.'.']['description'],1).'<br />' : '';
+                                                       $description = ($v[$k2i . '.']['description'] ? $GLOBALS['LANG']->sL($v[$k2i . '.']['description'], 1) . '<br />' : '');
 
                                                                // URL + onclick event:
                                                        $onClickEvent='';
-                                                       if (isset($v[$k2i.'.']['target']))      $onClickEvent.="setTarget('".$v[$k2i.'.']['target']."');";
+                                                       if (isset($v[$k2i.'.']['target']))      $onClickEvent.="browse_links_setTarget('".$v[$k2i.'.']['target']."');";
                                                        $v[$k2i.'.']['url'] = str_replace('###_URL###',$this->siteURL,$v[$k2i.'.']['url']);
                                                        if (substr($v[$k2i.'.']['url'],0,7)=='http://' || substr($v[$k2i.'.']['url'],0,7)=='mailto:')   {
                                                                $onClickEvent.="cur_href=unescape('".rawurlencode($v[$k2i.'.']['url'])."');link_current();";
@@ -1247,7 +1436,7 @@ class browse_links {
                        -->
                                                <table border="0" cellpadding="1" cellspacing="1" id="typo3-linkSpecial">
                                                        <tr>
-                                                               <td class="bgColor5" class="c-wCell" valign="top"><strong>'.$LANG->getLL('special',1).'</strong></td>
+                                                               <td class="bgColor5" class="c-wCell" valign="top"><strong>' . $GLOBALS['LANG']->getLL('special', 1) . '</strong></td>
                                                        </tr>
                                                        '.implode('',$subcats).'
                                                </table>
@@ -1255,11 +1444,28 @@ class browse_links {
                                }
                        break;
                        case 'page':
-                       default:
                                $pagetree = t3lib_div::makeInstance('rtePageTree');
                                $pagetree->thisScript = $this->thisScript;
+                               $pagetree->ext_showPageId = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
+                               $pagetree->ext_showNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
+                               $pagetree->addField('nav_title');
                                $tree=$pagetree->getBrowsableTree();
                                $cElements = $this->expandPage();
+
+                               // Outputting Temporary DB mount notice:
+                               if (intval($GLOBALS['BE_USER']->getSessionData('pageTree_temporaryMountPoint')))        {
+                                       $link = '<a href="' . htmlspecialchars(t3lib_div::linkThisScript(array('setTempDBmount' => 0))) . '">' .
+                                                                               $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_core.xml:labels.temporaryDBmount', 1) .
+                                                                       '</a>';
+                                       $flashMessage = t3lib_div::makeInstance(
+                                               't3lib_FlashMessage',
+                                               $link,
+                                               '',
+                                               t3lib_FlashMessage::INFO
+                                       );
+                                       $dbmount = $flashMessage->render();
+                               }
+
                                $content.= '
 
                        <!--
@@ -1267,27 +1473,53 @@ class browse_links {
                        -->
                                        <table border="0" cellpadding="0" cellspacing="0" id="typo3-linkPages">
                                                <tr>
-                                                       <td class="c-wCell" valign="top">'.$this->barheader($GLOBALS['LANG']->getLL('pageTree').':').$tree.'</td>
+                                                       <td class="c-wCell" valign="top">' . $this->barheader($GLOBALS['LANG']->getLL('pageTree') . ':') . $dbmount . $tree . '</td>
                                                        <td class="c-wCell" valign="top">'.$cElements.'</td>
                                                </tr>
                                        </table>
                                        ';
                        break;
+                       default:
+                                       //call hook
+                               foreach($this->hookObjects as $hookObject) {
+                                       $content .= $hookObject->getTab($this->act);
+                               }
+                       break;
                }
 
                $content .= '
+                       <!--
+                               Selecting params for link:
+                       -->
+                               <form action="" name="lparamsform" id="lparamsform">
+                                       <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkParams">
+                                               <tr>
+                                                       <td style="width: 96px;">' . $GLOBALS['LANG']->getLL('params', 1) . '</td>
+                                                       <td><input type="text" name="lparams" class="typo3-link-input" onchange="browse_links_setParams(this.value);" value="' . htmlspecialchars($this->setParams) . '" /></td>
+                                               </tr>
+                                       </table>
+                               </form>
 
-
+                       <!--
+                               Selecting class for link:
+                       -->
+                               <form action="" name="lclassform" id="lclassform">
+                                       <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkClass">
+                                               <tr>
+                                                       <td style="width: 96px;">' . $GLOBALS['LANG']->getLL('class', 1) . '</td>
+                                                       <td><input type="text" name="lclass" class="typo3-link-input" onchange="browse_links_setClass(this.value);" value="' . htmlspecialchars($this->setClass) . '" /></td>
+                                               </tr>
+                                       </table>
+                               </form>
 
                        <!--
                                Selecting title for link:
                        -->
-                               <form action="" name="ltitleform" id="ltargetform">
-                                       <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkTarget">
+                               <form action="" name="ltitleform" id="ltitleform">
+                                       <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkTitle">
                                                <tr>
-                                                       <td>'.$GLOBALS['LANG']->getLL('title',1).'</td>
-                                                       <td><input type="text" name="ltitle" onchange="setTitle(this.value);" value="'.htmlspecialchars($this->setTitle).'"'.$this->doc->formWidth(10).' /></td>
-                                                       <td><input type="submit" value="'.$GLOBALS['LANG']->getLL('update',1).'" onclick="return link_current();" /></td>
+                                                       <td style="width: 96px;">' . $GLOBALS['LANG']->getLL('title', 1) . '</td>
+                                                       <td><input type="text" name="ltitle" class="typo3-link-input" onchange="browse_links_setTitle(this.value);" value="' . htmlspecialchars($this->setTitle) . '" /></td>
                                                </tr>
                                        </table>
                                </form>
@@ -1306,17 +1538,16 @@ class browse_links {
                                        <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkTarget">
                                                <tr>
                                                        <td>'.$GLOBALS['LANG']->getLL('target',1).':</td>
-                                                       <td><input type="text" name="ltarget" onchange="setTarget(this.value);" value="'.htmlspecialchars($this->setTarget).'"'.$this->doc->formWidth(10).' /></td>
+                                                       <td><input type="text" name="ltarget" onchange="browse_links_setTarget(this.value);" value="' . htmlspecialchars($this->setTarget) . '"' . $this->doc->formWidth(10) . ' /></td>
                                                        <td>
-                                                               <select name="ltarget_type" onchange="setTarget(this.options[this.selectedIndex].value);document.ltargetform.ltarget.value=this.options[this.selectedIndex].value;this.selectedIndex=0;">
+                                                               <select name="ltarget_type" onchange="browse_links_setTarget(this.options[this.selectedIndex].value);document.ltargetform.ltarget.value=this.options[this.selectedIndex].value;this.selectedIndex=0;">
                                                                        <option></option>
                                                                        <option value="_top">'.$GLOBALS['LANG']->getLL('top',1).'</option>
                                                                        <option value="_blank">'.$GLOBALS['LANG']->getLL('newWindow',1).'</option>
                                                                </select>
                                                        </td>
                                                        <td>';
-
-                       if (($this->curUrlInfo['act']=="page" || $this->curUrlInfo['act']=='file') && $this->curUrlArray['href'])       {
+                       if (($this->curUrlInfo['act'] == 'page' || $this->curUrlInfo['act'] == 'file' || $this->curUrlInfo['act'] == 'folder') && $this->curUrlArray['href'] && $this->curUrlInfo['act'] == $this->act) {
                                $ltarget.='
                                                        <input type="submit" value="'.$GLOBALS['LANG']->getLL('update',1).'" onclick="return link_current();" />';
                        }
@@ -1324,8 +1555,10 @@ class browse_links {
                        $selectJS = '
                                if (document.ltargetform.popup_width.options[document.ltargetform.popup_width.selectedIndex].value>0 && document.ltargetform.popup_height.options[document.ltargetform.popup_height.selectedIndex].value>0)     {
                                        document.ltargetform.ltarget.value = document.ltargetform.popup_width.options[document.ltargetform.popup_width.selectedIndex].value+"x"+document.ltargetform.popup_height.options[document.ltargetform.popup_height.selectedIndex].value;
-                                       setTarget(document.ltargetform.ltarget.value);
-                               setTitle(document.ltitleform.ltitle.value);
+                                       browse_links_setTarget(document.ltargetform.ltarget.value);
+                                       browse_links_setClass(document.lclassform.lclass.value);
+                                       browse_links_setTitle(document.ltitleform.ltitle.value);
+                                       browse_links_setParams(document.lparamsform.lparams.value);
                                        document.ltargetform.popup_width.selectedIndex=0;
                                        document.ltargetform.popup_height.selectedIndex=0;
                                }
@@ -1380,7 +1613,7 @@ class browse_links {
        function main_db()      {
 
                        // Starting content:
-               $content=$this->doc->startPage('TBE file selector');
+               $content=$this->doc->startPage('TBE record selector');
 
                        // Init variable:
                $pArr = explode('|',$this->bparams);
@@ -1389,6 +1622,9 @@ class browse_links {
                $pagetree = t3lib_div::makeInstance('TBE_PageTree');
                $pagetree->thisScript=$this->thisScript;
                $pagetree->ext_pArrPages = !strcmp($pArr[3],'pages')?1:0;
+               $pagetree->ext_showNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
+               $pagetree->ext_showPageId = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
+               $pagetree->addField('nav_title');
                $tree=$pagetree->getBrowsableTree();
 
                        // Making the list of elements, if applicable:
@@ -1423,29 +1659,29 @@ class browse_links {
         * @return      string          HTML content for the module
         */
        function main_file()    {
-               global $BE_USER;
 
                        // Starting content:
-               $content.=$this->doc->startPage('TBE file selector');
+               $content = $this->doc->startPage('TBE file selector');
 
                        // Init variable:
                $pArr = explode('|',$this->bparams);
 
                        // Create upload/create folder forms, if a path is given:
-               $fileProcessor = t3lib_div::makeInstance('t3lib_basicFileFunctions');
-               $fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
                $path=$this->expandFolder;
                if (!$path || !@is_dir($path))  {
-                       $path = $fileProcessor->findTempFolder().'/';   // The closest TEMP-path is found
+                               // The closest TEMP-path is found
+                       $path = $this->fileProcessor->findTempFolder().'/';
                }
-               if ($path!='/' && @is_dir($path))       {
+               if ($path!='/' && @is_dir($path)) {
                        $uploadForm=$this->uploadForm($path);
                        $createFolder=$this->createFolder($path);
                } else {
                        $createFolder='';
                        $uploadForm='';
                }
-               if ($BE_USER->getTSConfigVal('options.uploadFieldsInTopOfEB'))  $content.=$uploadForm;
+               if ($GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
+                       $content .= $uploadForm;
+               }
 
                        // Getting flag for showing/not showing thumbnails:
                $noThumbs = $GLOBALS['BE_USER']->getTSConfigVal('options.noThumbsInEB');
@@ -1455,12 +1691,8 @@ class browse_links {
                        $_MOD_MENU = array('displayThumbs' => '');
                        $_MCONF['name']='file_list';
                        $_MOD_SETTINGS = t3lib_BEfunc::getModuleData($_MOD_MENU, t3lib_div::_GP('SET'), $_MCONF['name']);
-                       $addParams = '&act='.$this->act.'&mode='.$this->mode.'&expandFolder='.rawurlencode($path).'&bparams='.rawurlencode($this->bparams);
-                       $thumbNailCheck = t3lib_BEfunc::getFuncCheck('','SET[displayThumbs]',$_MOD_SETTINGS['displayThumbs'],$this->thisScript,$addParams).' '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_file_list.php:displayThumbs',1);
-               } else {
-                       $thumbNailCheck='';
                }
-               $noThumbs = $noThumbs?$noThumbs:!$_MOD_SETTINGS['displayThumbs'];
+               $noThumbs = $noThumbs ? $noThumbs : !$_MOD_SETTINGS['displayThumbs'];
 
                        // Create folder tree:
                $foldertree = t3lib_div::makeInstance('TBE_FolderTree');
@@ -1489,22 +1721,97 @@ class browse_links {
                                </tr>
                        </table>
                        ';
-               $content.=$thumbNailCheck;
 
                        // Adding create folder + upload forms if applicable:
-               if (!$BE_USER->getTSConfigVal('options.uploadFieldsInTopOfEB')) $content.=$uploadForm;
-               if ($BE_USER->isAdmin() || $BE_USER->getTSConfigVal('options.createFoldersInEB'))       $content.=$createFolder;
+               if (!$GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
+                       $content .= $uploadForm;
+               }
+               if ($GLOBALS['BE_USER']->isAdmin() || $GLOBALS['BE_USER']->getTSConfigVal('options.createFoldersInEB')) {
+                       $content .= $createFolder;
+               }
 
                        // Add some space
                $content.='<br /><br />';
 
+                       // Setup indexed elements:
+               $this->doc->JScode.= $this->doc->wrapScriptTags('BrowseLinks.addElements(' . json_encode($this->elements) . ');');
                        // Ending page, returning content:
                $content.= $this->doc->endPage();
                $content = $this->doc->insertStylesAndJS($content);
+
                return $content;
        }
 
+       /**
+        * TYPO3 Element Browser: Showing a folder tree, allowing you to browse for folders.
+        *
+        * @return      string          HTML content for the module
+        */
+       function main_folder() {
 
+                       // Starting content:
+               $content = $this->doc->startPage('TBE folder selector');
+
+                       // Init variable:
+               $parameters = explode('|', $this->bparams);
+
+
+               $path = $this->expandFolder;
+               if (!$path || !@is_dir($path)) {
+                               // The closest TEMP-path is found
+                       $path = $this->fileProcessor->findTempFolder().'/';
+               }
+               if ($path != '/' && @is_dir($path)) {
+                       $createFolder = $this->createFolder($path);
+               } else {
+                       $createFolder='';
+               }
+
+                       // Create folder tree:
+               $foldertree                         = t3lib_div::makeInstance('TBE_FolderTree');
+               $foldertree->thisScript             = $this->thisScript;
+               $foldertree->ext_noTempRecyclerDirs = ($this->mode == 'filedrag');
+               $tree                                = $foldertree->getBrowsableTree(FALSE);
+
+               list(, , $specUid) = explode('_', $this->PM);
+
+               if($this->mode == 'filedrag') {
+                       $folders = $this->TBE_dragNDrop(
+                               $foldertree->specUIDmap[$specUid],
+                               $parameters[3]
+                       );
+               } else {
+                       $folders = $this->TBE_expandSubFolders($foldertree->specUIDmap[$specUid]);
+               }
+
+                       // Putting the parts together, side by side:
+               $content.= '
+
+                       <!--
+                               Wrapper table for folder tree / folder list:
+                       -->
+                       <table border="0" cellpadding="0" cellspacing="0" id="typo3-EBfiles">
+                               <tr>
+                                       <td class="c-wCell" valign="top">'.$this->barheader($GLOBALS['LANG']->getLL('folderTree').':').$tree.'</td>
+                                       <td class="c-wCell" valign="top">'.$folders.'</td>
+                               </tr>
+                       </table>
+                       ';
+
+                       // Adding create folder if applicable:
+               if ($GLOBALS['BE_USER']->isAdmin() || $GLOBALS['BE_USER']->getTSConfigVal('options.createFoldersInEB')) {
+                       $content .= $createFolder;
+               }
+
+                       // Add some space
+               $content .= '<br /><br />';
+
+                       // Ending page, returning content:
+               $content.= $this->doc->endPage();
+               $content = $this->doc->insertStylesAndJS($content);
+
+               return $content;
+       }
 
 
 
@@ -1533,7 +1840,7 @@ class browse_links {
         * @return      string          HTML output. Returns content only if the ->expandPage value is set (pointing to a page uid to show tt_content records from ...)
         */
        function expandPage()   {
-               global $BE_USER, $BACK_PATH;
+               global $BACK_PATH;
 
                $out='';
                $expPageId = $this->expandPage;         // Set page id (if any) to expand
@@ -1544,7 +1851,7 @@ class browse_links {
                }
 
                        // Draw the record list IF there is a page id to expand:
-               if ($expPageId && t3lib_div::testInt($expPageId) && $BE_USER->isInWebMount($expPageId)) {
+               if ($expPageId && t3lib_div::testInt($expPageId) && $GLOBALS['BE_USER']->isInWebMount($expPageId)) {
 
                                // Set header:
                        $out.=$this->barheader($GLOBALS['LANG']->getLL('contentElements').':');
@@ -1552,19 +1859,19 @@ class browse_links {
                                // Create header for listing, showing the page title/icon:
                        $titleLen=intval($GLOBALS['BE_USER']->uc['titleLen']);
                        $mainPageRec = t3lib_BEfunc::getRecordWSOL('pages',$expPageId);
-                       $picon=t3lib_iconWorks::getIconImage('pages',$mainPageRec,'','');
-                       $picon.= htmlspecialchars(t3lib_div::fixed_lgd_cs($mainPageRec['title'],$titleLen));
+                       $picon = t3lib_iconWorks::getSpriteIconForRecord('pages', $mainPageRec);
+                       $picon .= t3lib_BEfunc::getRecordTitle('pages', $mainPageRec, TRUE);
                        $out.=$picon.'<br />';
 
                                // Look up tt_content elements from the expanded page:
                        $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
-                                                       'uid,header,hidden,starttime,endtime,fe_group,CType,colpos,bodytext',
+                                                       'uid,header,hidden,starttime,endtime,fe_group,CType,colPos,bodytext',
                                                        'tt_content',
                                                        'pid='.intval($expPageId).
                                                                t3lib_BEfunc::deleteClause('tt_content').
                                                                t3lib_BEfunc::versioningPlaceholderClause('tt_content'),
                                                        '',
-                                                       'colpos,sorting'
+                                                       'colPos,sorting'
                                                );
                        $cc = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
 
@@ -1572,7 +1879,7 @@ class browse_links {
                        $c=0;
                        while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))       {
                                $c++;
-                               $icon=t3lib_iconWorks::getIconImage('tt_content',$row,$BACK_PATH,'');
+                               $icon = t3lib_iconWorks::getSpriteIconForRecord('tt_content', $row);
                                if ($this->curUrlInfo['act']=='page' && $this->curUrlInfo['cElement']==$row['uid'])     {
                                        $arrCol='<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/blinkarrow_left.gif','width="5" height="9"').' class="c-blinkArrowL" alt="" />';
                                } else {
@@ -1583,7 +1890,7 @@ class browse_links {
                                                $arrCol.
                                                '<a href="#" onclick="return link_typo3Page(\''.$expPageId.'\',\'#'.$row['uid'].'\');">'.
                                                $icon.
-                                               htmlspecialchars(t3lib_div::fixed_lgd_cs($row['header'],$titleLen)).
+                                               t3lib_BEfunc::getRecordTitle('tt_content', $row, TRUE) .
                                                '</a><br />';
 
                                        // Finding internal anchor points:
@@ -1614,14 +1921,12 @@ class browse_links {
         * @return      string          HTML output.
         */
        function TBE_expandPage($tables)        {
-               global $TCA,$BE_USER, $BACK_PATH;
-
                $out='';
-               if ($this->expandPage>=0 && t3lib_div::testInt($this->expandPage) && $BE_USER->isInWebMount($this->expandPage)) {
+               if ($this->expandPage >= 0 && t3lib_div::testInt($this->expandPage) && $GLOBALS['BE_USER']->isInWebMount($this->expandPage)) {
 
                                // Set array with table names to list:
                        if (!strcmp(trim($tables),'*')) {
-                               $tablesArr = array_keys($TCA);
+                               $tablesArr = array_keys($GLOBALS['TCA']);
                        } else {
                                $tablesArr = t3lib_div::trimExplode(',',$tables,1);
                        }
@@ -1636,15 +1941,19 @@ class browse_links {
                        $ATag='';
                        $ATag_e='';
                        $ATag2='';
-                       if (in_array('pages',$tablesArr))       {
-                               $ficon=t3lib_iconWorks::getIcon('pages',$mainPageRec);
-                               $ATag="<a href=\"#\" onclick=\"return insertElement('pages', '".$mainPageRec['uid']."', 'db', ".t3lib_div::quoteJSvalue($mainPageRec['title']).", '', '', '".$ficon."','',1);\">";
-                               $ATag2="<a href=\"#\" onclick=\"return insertElement('pages', '".$mainPageRec['uid']."', 'db', ".t3lib_div::quoteJSvalue($mainPageRec['title']).", '', '', '".$ficon."','',0);\">";
-                               $ATag_alt=substr($ATag,0,-4).",'',1);\">";
-                               $ATag_e='</a>';
+                       $picon = '';
+                       if (is_array($mainPageRec)) {
+                               $picon = t3lib_iconWorks::getSpriteIconForRecord('pages', $mainPageRec);
+                               if (in_array('pages', $tablesArr)) {
+                                       $ATag = "<a href=\"#\" onclick=\"return insertElement('pages', '" . $mainPageRec['uid'] .
+                                               "', 'db', " . t3lib_div::quoteJSvalue($mainPageRec['title']) . ", '', '', '','',1);\">";
+                                       $ATag2 = "<a href=\"#\" onclick=\"return insertElement('pages', '" . $mainPageRec['uid'] .
+                                               "', 'db', " . t3lib_div::quoteJSvalue($mainPageRec['title']) . ", '', '', '','',0);\">";
+                                       $ATag_alt = substr($ATag, 0, -4) . ",'',1);\">";
+                                       $ATag_e = '</a>';
+                               }
                        }
-                       $picon=t3lib_iconWorks::getIconImage('pages',$mainPageRec,$BACK_PATH,'');
-                       $pBicon=$ATag2?'<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/plusbullet2.gif','width="18" height="16"').' alt="" />':'';
+                       $pBicon = ($ATag2 ? '<img' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/plusbullet2.gif', 'width="18" height="16"') . ' alt="" />' : '');
                        $pText=htmlspecialchars(t3lib_div::fixed_lgd_cs($mainPageRec['title'],$titleLen));
                        $out.=$picon.$ATag2.$pBicon.$ATag_e.$ATag.$pText.$ATag_e.'<br />';
 
@@ -1656,6 +1965,7 @@ class browse_links {
                        $table='';
 
                                // Generate the record list:
+                       /** @var $dblist TBE_browser_recordList */
                        $dblist = t3lib_div::makeInstance('TBE_browser_recordList');
                        $dblist->thisScript=$this->thisScript;
                        $dblist->backPath = $GLOBALS['BACK_PATH'];
@@ -1676,6 +1986,12 @@ class browse_links {
 
                                //      Add the HTML for the record list to output variable:
                        $out.=$dblist->HTMLcode;
+
+                               // Add support for fieldselectbox in singleTableMode
+                       if ($dblist->table) {
+                               $out.= $dblist->fieldSelectBox($dblist->table);
+                       }
+
                        $out.=$dblist->getSearchBox();
                }
 
@@ -1684,6 +2000,40 @@ class browse_links {
        }
 
 
+       /**
+        * Render list of folders inside a folder.
+        *
+        * @param       string          string of the current folder
+        * @return      string          HTML output
+        */
+       function TBE_expandSubFolders($expandFolder=0) {
+               $content = '';
+
+               $expandFolder = $expandFolder ?
+                       $expandFolder :
+                       $this->expandFolder;
+
+               if($expandFolder && $this->checkFolder($expandFolder)) {
+                       if(t3lib_div::isFirstPartOfStr($expandFolder, PATH_site)) {
+                               $rootFolder = substr($expandFolder, strlen(PATH_site));
+                       }
+
+                       $folders = array();
+
+                               // Listing the folders:
+                       $folders = t3lib_div::get_dirs($expandFolder);
+                       if(count($folders) > 0) {
+                               foreach($folders as $index => $folder) {
+                                       $folders[$index] = $rootFolder.$folder.'/';
+                               }
+                       }
+                       $content.= $this->folderList($rootFolder, $folders);
+               }
+
+                       // Return accumulated content for folderlisting:
+               return $content;
+       }
+
 
 
 
@@ -1729,32 +2079,44 @@ class browse_links {
                        $picon='<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/i/_icon_webfolders.gif','width="18" height="16"').' alt="" />';
                        $picon.=htmlspecialchars(t3lib_div::fixed_lgd_cs(basename($expandFolder),$titleLen));
                        $picon='<a href="#" onclick="return link_folder(\''.t3lib_div::rawUrlEncodeFP(substr($expandFolder,strlen(PATH_site))).'\');">'.$picon.'</a>';
+                       if ($this->curUrlInfo['act'] == 'folder' && $cmpPath == $expandFolder)  {
+                               $out.= '<img'.t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/blinkarrow_left.gif', 'width="5" height="9"') . ' class="c-blinkArrowL" alt="" />';
+                       }
                        $out.=$picon.'<br />';
 
                                // Get files from the folder:
-                       $files = t3lib_div::getFilesInDir($expandFolder,$extensionList,1,1);    // $extensionList="",$prependPath=0,$order='')
+                       if ($this->mode == 'wizard' && $this->act == 'folder') {
+                               $files = t3lib_div::get_dirs($expandFolder);
+                       } else {
+                               $files = t3lib_div::getFilesInDir($expandFolder, $extensionList, 1, 1); // $extensionList='', $prependPath=0, $order='')
+                       }
+
                        $c=0;
                        $cc=count($files);
-
                        if (is_array($files))   {
                                foreach($files as $filepath)    {
                                        $c++;
                                        $fI=pathinfo($filepath);
 
-                                               // File icon:
-                                       $icon = t3lib_BEfunc::getFileIcon(strtolower($fI['extension']));
+                                       if ($this->mode == 'wizard' && $this->act == 'folder') {
+                                               $filepath = $expandFolder.$filepath.'/';
+                                               $icon = '<img' . t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/i/_icon_webfolders.gif', 'width="18" height="16"') . ' alt="" />';
+                                       } else {
+                                                       // File icon:
+                                               $icon = t3lib_BEfunc::getFileIcon(strtolower($fI['extension']));
+
+                                                       // Get size and icon:
+                                               $size = ' (' . t3lib_div::formatSize(filesize($filepath)) . 'bytes)';
+                                               $icon = '<img' . t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/fileicons/' . $icon . '', 'width="18" height="16"') . ' title="' . htmlspecialchars($fI['basename'] . $size) . '" alt="" />';
+                                       }
 
                                                // If the listed file turns out to be the CURRENT file, then show blinking arrow:
-                                       if ($this->curUrlInfo['act']=="file" && $cmpPath==$filepath)    {
+                                       if (($this->curUrlInfo['act'] == 'file' || $this->curUrlInfo['act'] == 'folder') && $cmpPath == $filepath) {
                                                $arrCol='<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/blinkarrow_left.gif','width="5" height="9"').' class="c-blinkArrowL" alt="" />';
                                        } else {
                                                $arrCol='';
                                        }
 
-                                               // Get size and icon:
-                                       $size=' ('.t3lib_div::formatSize(filesize($filepath)).'bytes)';
-                                       $icon = '<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/fileicons/'.$icon.'','width="18" height="16"').' title="'.htmlspecialchars($fI['basename'].$size).'" alt="" />';
-
                                                // Put it all together for the file element:
                                        $out.='<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/ol/join'.($c==$cc?'bottom':'').'.gif','width="18" height="16"').' alt="" />'.
                                                        $arrCol.
@@ -1777,8 +2139,7 @@ class browse_links {
         * @return      string          HTML output
         */
        function TBE_expandFolder($expandFolder=0,$extensionList='',$noThumbs=0)        {
-               global $LANG;
-
+               $extensionList = ($extensionList == '*') ? '' : $extensionList;
                $expandFolder = $expandFolder ? $expandFolder : $this->expandFolder;
                $out='';
                if ($expandFolder && $this->checkFolder($expandFolder)) {
@@ -1800,7 +2161,7 @@ class browse_links {
         * @return      string          HTML output
         */
        function fileList($files, $folderName='', $noThumbs=0) {
-               global $LANG, $BACK_PATH;
+               global $BACK_PATH;
 
                $out='';
 
@@ -1808,18 +2169,24 @@ class browse_links {
                if (is_array($files))   {
 
                                // Create headline (showing number of files):
-                       $out.=$this->barheader(sprintf($GLOBALS['LANG']->getLL('files').' (%s):',count($files)));
+                       $filesCount = count($files);
+                       $out.=$this->barheader(sprintf($GLOBALS['LANG']->getLL('files').' (%s):', $filesCount));
+                       $out .= '<div id="filelist">';
+                       $out.=$this->getBulkSelector($filesCount);
 
                        $titleLen=intval($GLOBALS['BE_USER']->uc['titleLen']);
 
                                // Create the header of current folder:
                        if($folderName) {
-                               $picon='<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/i/_icon_webfolders.gif','width="18" height="16"').' alt="" />';
-                               $picon.=htmlspecialchars(t3lib_div::fixed_lgd_cs(basename($folderName),$titleLen));
-                               $out.=$picon.'<br />';
+                               $picon = '<div id="currentFolderHeader">';
+                               $picon .= '<img' . t3lib_iconWorks::skinImg($BACK_PATH,'gfx/i/_icon_webfolders.gif', 'width="18" height="16"') . ' alt="" /> ';
+                               $picon .= htmlspecialchars(t3lib_div::fixed_lgd_cs(basename($folderName), $titleLen));
+                               $picon .= '</div>';
+                               $out .= $picon;
                        }
 
                                // Init graphic object for reading file dimensions:
+                       /** @var $imgObj t3lib_stdGraphic */
                        $imgObj = t3lib_div::makeInstance('t3lib_stdGraphic');
                        $imgObj->init();
                        $imgObj->mayScaleUp=0;
@@ -1831,7 +2198,7 @@ class browse_links {
                                $fI=pathinfo($filepath);
 
                                        // Thumbnail/size generation:
-                               if (t3lib_div::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],$fI['extension']) && !$noThumbs)      {
+                               if (t3lib_div::inList(strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']),strtolower($fI['extension'])) && !$noThumbs)      {
                                        $imgInfo = $imgObj->getImageDimensions($filepath);
                                        $pDim = $imgInfo[0].'x'.$imgInfo[1].' pixels';
                                        $clickIcon = t3lib_BEfunc::getThumbNail($BACK_PATH.'thumbs.php',$filepath,'hspace="5" vspace="5" border="1"');
@@ -1847,11 +2214,22 @@ class browse_links {
 
                                        // Create links for adding the file:
                                if (strstr($filepath,',') || strstr($filepath,'|'))     {       // In case an invalid character is in the filepath, display error message:
-                                       $eMsg = $LANG->JScharCode(sprintf($LANG->getLL('invalidChar'),', |'));
+                                       $eMsg = $GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->getLL('invalidChar'), ', |'));
                                        $ATag = $ATag_alt = "<a href=\"#\" onclick=\"alert(".$eMsg.");return false;\">";
+                                       $bulkCheckBox = '';
                                } else {        // If filename is OK, just add it:
-                                       $ATag = "<a href=\"#\" onclick=\"return insertElement('','".t3lib_div::shortMD5($filepath)."', 'file', '".rawurlencode($fI['basename'])."', unescape('".rawurlencode($filepath)."'), '".$fI['extension']."', '".$ficon."');\">";
-                                       $ATag_alt = substr($ATag,0,-4).",'',1);\">";
+                                       $filesIndex = count($this->elements);
+                                       $this->elements['file_'.$filesIndex] = array(
+                                               'md5' => t3lib_div::shortMD5($filepath),
+                                               'type' => 'file',
+                                               'fileName' => $fI['basename'],
+                                               'filePath' => $filepath,
+                                               'fileExt' => $fI['extension'],
+                                               'fileIcon' => $ficon,
+                                       );
+                                       $ATag = "<a href=\"#\" onclick=\"return BrowseLinks.File.insertElement('file_$filesIndex');\">";
+                                       $ATag_alt = substr($ATag,0,-4).",1);\">";
+                                       $bulkCheckBox = '<input type="checkbox" class="typo3-bulk-item" name="file_'.$filesIndex.'" value="0" /> ';
                                }
                                $ATag_e='</a>';
 
@@ -1861,27 +2239,27 @@ class browse_links {
                                $ATag2_e='</a>';
 
                                        // Combine the stuff:
-                                       $filenameAndIcon=$ATag_alt.$icon.htmlspecialchars(t3lib_div::fixed_lgd_cs(basename($filepath),$titleLen)).$ATag_e;
+                               $filenameAndIcon=$bulkCheckBox.$ATag_alt.$icon.htmlspecialchars(t3lib_div::fixed_lgd_cs(basename($filepath),$titleLen)).$ATag_e;
 
                                        // Show element:
                                if ($pDim)      {               // Image...
                                        $lines[]='
                                                <tr class="bgColor4">
                                                        <td nowrap="nowrap">'.$filenameAndIcon.'&nbsp;</td>
-                                                       <td>'.$ATag.'<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/plusbullet2.gif','width="18" height="16"').' title="'.$LANG->getLL('addToList',1).'" alt="" />'.$ATag_e.'</td>
-                                                       <td nowrap="nowrap">'.($ATag2.'<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/zoom2.gif','width="12" height="12"').' title="'.$LANG->getLL('info',1).'" alt="" /> '.$LANG->getLL('info',1).$ATag2_e).'</td>
+                                                       <td>' . $ATag . '<img' . t3lib_iconWorks::skinImg($BACK_PATH,'gfx/plusbullet2.gif', 'width="18" height="16"') . ' title="' . $GLOBALS['LANG']->getLL('addToList',1) . '" alt="" />' . $ATag_e . '</td>
+                                                       <td nowrap="nowrap">' . ($ATag2 . '<img'.t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/zoom2.gif', 'width="12" height="12"') . ' title="' . $GLOBALS['LANG']->getLL('info', 1) . '" alt="" /> ' . $GLOBALS['LANG']->getLL('info', 1) . $ATag2_e) . '</td>
                                                        <td nowrap="nowrap">&nbsp;'.$pDim.'</td>
                                                </tr>';
                                        $lines[]='
                                                <tr>
-                                                       <td colspan="4">'.$ATag_alt.$clickIcon.$ATag_e.'</td>
+                                                       <td class="filelistThumbnail" colspan="4">' . $ATag_alt . $clickIcon . $ATag_e . '</td>
                                                </tr>';
                                } else {
                                        $lines[]='
                                                <tr class="bgColor4">
                                                        <td nowrap="nowrap">'.$filenameAndIcon.'&nbsp;</td>
-                                                       <td>'.$ATag.'<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/plusbullet2.gif','width="18" height="16"').' title="'.$LANG->getLL('addToList',1).'" alt="" />'.$ATag_e.'</td>
-                                                       <td nowrap="nowrap">'.($ATag2.'<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/zoom2.gif','width="12" height="12"').' title="'.$LANG->getLL('info',1).'" alt="" /> '.$LANG->getLL('info',1).$ATag2_e).'</td>
+                                                       <td>' . $ATag . '<img' . t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/plusbullet2.gif','width="18" height="16"') . ' title="' . $GLOBALS['LANG']->getLL('addToList',1) . '" alt="" />' . $ATag_e . '</td>
+                                                       <td nowrap="nowrap">' . ($ATag2 . '<img' . t3lib_iconWorks::skinImg($BACK_PATH,'gfx/zoom2.gif','width="12" height="12"') . ' title="' . $GLOBALS['LANG']->getLL('info', 1) . '" alt="" /> ' . $GLOBALS['LANG']->getLL('info', 1) . $ATag2_e) . '</td>
                                                        <td>&nbsp;</td>
                                                </tr>';
                                }
@@ -1899,16 +2277,132 @@ class browse_links {
                <!--
                        File listing
                -->
-                               <table border="0" cellpadding="0" cellspacing="1" id="typo3-fileList">
+                               <table cellpadding="0" cellspacing="0" id="typo3-fileList">
                                        '.implode('',$lines).'
                                </table>';
                }
-
                        // Return accumulated content for filelisting:
+               $out .= '</div>';
                return $out;
        }
 
        /**
+        * Render list of folders.
+        *
+        * @param       array           List of folders. See t3lib_div::get_dirs
+        * @param       string          If set a header with a folder icon and folder name are shown
+        * @return      string          HTML output
+        */
+       function folderList($baseFolder, $folders) {
+               global $BACK_PATH;
+
+               $content = '';
+
+                       // Create headline (showing number of folders):
+               $content.=$this->barheader(
+                       sprintf($GLOBALS['LANG']->getLL('folders').' (%s):',count($folders))
+               );
+
+               $titleLength = intval($GLOBALS['BE_USER']->uc['titleLen']);
+
+                       // Create the header of current folder:
+               if($baseFolder) {
+                       if (strstr($baseFolder, ',') || strstr($baseFolder, '|'))       {
+                                       // In case an invalid character is in the filepath, display error message:
+                               $errorMessage     = $GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->getLL('invalidChar'), ', |'));
+                               $aTag = $aTag_alt = "<a href=\"#\" onclick=\"alert(".$errorMessage.");return false;\">";
+                       } else {
+                                       // If foldername is OK, just add it:
+                               $aTag = "<a href=\"#\" onclick=\"return insertElement('','".rawurlencode($baseFolder)."', 'folder', '".rawurlencode($baseFolder)."', unescape('".rawurlencode($baseFolder)."'), '".$fI['extension']."', '".$ficon."');\">";
+                               $aTag_alt = substr($aTag,0,-4).",'',1);\">";
+                       }
+                       $aTag_e = '</a>';
+
+                               // add the foder icon
+                       $folderIcon = $aTag_alt;
+                       $folderIcon.= '<img'.t3lib_iconWorks::skinImg(
+                               $BACK_PATH,
+                               'gfx/i/_icon_webfolders.gif','width="18" height="16"'
+                       ).' alt="" />';
+                       $folderIcon.= htmlspecialchars(
+                               t3lib_div::fixed_lgd_cs(basename($baseFolder),$titleLength)
+                       );
+                       $folderIcon.= $aTag_e;
+
+                       $content.=$folderIcon.'<br />';
+               }
+
+                       // Listing the folders:
+               if(is_array($folders)) {
+                       if(count($folders) > 0) {
+                                       // Traverse the folder list:
+                               $lines = array();
+                               foreach($folders as $folderPath)        {
+                                       $pathInfo = pathinfo($folderPath);
+
+                                               // Create folder icon:
+                                       $icon = '<img src="clear.gif" width="16" height="16" alt="" /><img'.t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/i/_icon_webfolders.gif','width="16" height="16"').' title="'.htmlspecialchars($pathInfo['basename'].$size).'" class="absmiddle" alt="" />';
+
+                                               // Create links for adding the folder:
+                                       if($this->P['itemName'] != '' && $this->P['formName'] != '') {
+                                               $aTag = "<a href=\"#\" onclick=\"return set_folderpath(unescape('".rawurlencode($folderPath)."'));\">";
+                                       } else {
+                                               $aTag = "<a href=\"#\" onclick=\"return insertElement('','".rawurlencode($folderPath)."', 'folder', '".rawurlencode($folderPath)."', unescape('".rawurlencode($folderPath)."'), '".$pathInfo['extension']."', '".$ficon."');\">";
+                                       }
+
+                                       if (strstr($folderPath,',') || strstr($folderPath,'|')) {
+                                                       // In case an invalid character is in the filepath, display error message:
+                                               $errorMessage     = $GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->getLL('invalidChar'), ', |'));
+                                               $aTag = $aTag_alt = "<a href=\"#\" onclick=\"alert(".$errorMessage.");return false;\">";
+                                       } else {
+                                                       // If foldername is OK, just add it:
+                                               $aTag_alt = substr($aTag,0,-4).",'',1);\">";
+                                       }
+                                       $aTag_e='</a>';
+
+                                               // Combine icon and folderpath:
+                                       $foldernameAndIcon = $aTag_alt.$icon.htmlspecialchars(
+                                               t3lib_div::fixed_lgd_cs(basename($folderPath),$titleLength)
+                                       ).$aTag_e;
+
+                                       if($this->P['itemName'] != '') {
+                                               $lines[] = '
+                                                       <tr class="bgColor4">
+                                                               <td nowrap="nowrap">'.$foldernameAndIcon.'&nbsp;</td>
+                                                               <td>&nbsp;</td>
+                                                       </tr>';
+                                       } else {
+                                               $lines[] = '
+                                                       <tr class="bgColor4">
+                                                               <td nowrap="nowrap">'.$foldernameAndIcon.'&nbsp;</td>
+                                                               <td>' . $aTag . '<img' . t3lib_iconWorks::skinImg($BACK_PATH, 'gfx/plusbullet2.gif', 'width="18" height="16"') . ' title="' . $GLOBALS['LANG']->getLL('addToList', 1) . '" alt="" />' . $aTag_e .' </td>
+                                                               <td>&nbsp;</td>
+                                                       </tr>';
+                                       }
+
+                                       $lines[] = '
+                                                       <tr>
+                                                               <td colspan="3"><img src="clear.gif" width="1" height="3" alt="" /></td>
+                                                       </tr>';
+                               }
+                       }
+
+                               // Wrap all the rows in table tags:
+                       $content.='
+
+               <!--
+                       Folder listing
+               -->
+                               <table border="0" cellpadding="0" cellspacing="1" id="typo3-folderList">
+                                       '.implode('', $lines).'
+                               </table>';
+               }
+
+                       // Return accumulated content for folderlisting:
+               return $content;
+       }
+
+       /**
         * For RTE: This displays all IMAGES (gif,png,jpg) (from extensionList) from folder. Thumbnails are shown for images.
         * This listing is of images located in the web-accessible paths ONLY - the listing is for drag-n-drop use in the RTE
         *
@@ -1919,6 +2413,7 @@ class browse_links {
        function TBE_dragNDrop($expandFolder=0,$extensionList='')       {
                global $BACK_PATH;
 
+               $extensionList = ($extensionList == '*') ? '' : $extensionList;
                $expandFolder = $expandFolder ? $expandFolder : $this->expandFolder;
                $out='';
                if ($expandFolder && $this->checkFolder($expandFolder)) {
@@ -1943,15 +2438,15 @@ class browse_links {
                                                        <td colspan="2">'.$this->getMsgBox($GLOBALS['LANG']->getLL('findDragDrop')).'</td>
                                                </tr>';
 
-                                               // Fraverse files:
-                                       while(list(,$filepath)=each($files))    {
-                                               $fI=pathinfo($filepath);
+                                               // Traverse files:
+                                       foreach ($files as $filepath) {
+                                               $fI = pathinfo($filepath);
 
                                                        // URL of image:
                                                $iurl = $this->siteURL.t3lib_div::rawurlencodeFP(substr($filepath,strlen(PATH_site)));
 
                                                        // Show only web-images
-                                               if (t3lib_div::inList('gif,jpeg,jpg,png',$fI['extension']))     {
+                                               if (t3lib_div::inList('gif,jpeg,jpg,png',strtolower($fI['extension']))) {
                                                        $imgInfo = @getimagesize($filepath);
                                                        $pDim = $imgInfo[0].'x'.$imgInfo[1].' pixels';
 
@@ -2042,10 +2537,10 @@ class browse_links {
         * Verifies that a path is a web-folder:
         *
         * @param       string          Absolute filepath
-        * @return      boolean         If the input path is found in PATH_site then it returns true.
+        * @return      boolean         If the input path is found in PATH_site then it returns TRUE.
         */
        function isWebFolder($folder)   {
-               $folder = ereg_replace('\/$','',$folder).'/';
+               $folder = rtrim($folder, '/').'/';
                return t3lib_div::isFirstPartOfStr($folder,PATH_site) ? TRUE : FALSE;
        }
 
@@ -2053,13 +2548,20 @@ class browse_links {
         * Checks, if a path is within the mountpoints of the backend user
         *
         * @param       string          Absolute filepath
-        * @return      boolean         If the input path is found in the backend users filemounts, then return true.
+        * @return      boolean         If the input path is found in the backend users filemounts, then return TRUE.
         */
        function checkFolder($folder)   {
-               $fileProcessor = t3lib_div::makeInstance('t3lib_basicFileFunctions');
-               $fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
+               return $this->fileProcessor->checkPathAgainstMounts(rtrim($folder, '/') . '/') ? TRUE : FALSE;
+       }
 
-               return $fileProcessor->checkPathAgainstMounts(ereg_replace('\/$','',$folder).'/') ? TRUE : FALSE;
+       /**
+        * Checks, if a path is within a read-only mountpoint of the backend user
+        *
+        * @param       string          Absolute filepath
+        * @return      boolean         If the input path is found in the backend users filemounts and if the filemount is of type readonly, then return TRUE.
+        */
+       function isReadOnlyFolder($folder) {
+               return ($GLOBALS['FILEMOUNTS'][$this->fileProcessor->checkPathAgainstMounts(rtrim($folder, '/') . '/')]['type'] == 'readonly');
        }
 
        /**
@@ -2070,11 +2572,8 @@ class browse_links {
         */
        function barheader($str)        {
                return '
-
-                       <!--
-                               Bar header:
-                       -->
-                       <h3 class="bgColor5">'.htmlspecialchars($str).'</h3>
+                       <!-- Bar header: -->
+                       <h3>' . htmlspecialchars($str) . '</h3>
                        ';
        }
 
@@ -2110,16 +2609,17 @@ class browse_links {
         * @return      string          HTML content, wrapped in a table.
         */
        function printCurrentUrl($str)  {
-               return '
-
-                       <!--
-                               Print current URL
-                       -->
-                       <table border="0" cellpadding="0" cellspacing="0" class="bgColor5" id="typo3-curUrl">
-                               <tr>
-                                       <td>'.$GLOBALS['LANG']->getLL('currentLink',1).': '.htmlspecialchars(rawurldecode($str)).'</td>
-                               </tr>
-                       </table>';
+               if (strlen($str)) {
+                       return '
+                               <!-- Print current URL -->
+                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-curUrl">
+                                       <tr>
+                                               <td>' . $GLOBALS['LANG']->getLL('currentLink',1) . ': ' .htmlspecialchars(rawurldecode($str)) . '</td>
+                                       </tr>
+                               </table>';
+               } else {
+                       return '';
+               }
        }
 
        /**
@@ -2144,14 +2644,20 @@ class browse_links {
                                $info['act']='spec';
                        } elseif (t3lib_div::isFirstPartOfStr($href,$siteUrl))  {       // If URL is on the current frontend website:
                                $rel = substr($href,strlen($siteUrl));
-                               if (@file_exists(PATH_site.rawurldecode($rel))) {       // URL is a file, which exists:
+                               if (file_exists(PATH_site.rawurldecode($rel)))  {       // URL is a file, which exists:
                                        $info['value']=rawurldecode($rel);
-                                       $info['act']='file';
+                                       if (@is_dir(PATH_site . $info['value'])) {
+                                               $info['act'] = 'folder';
+                                       } else {
+                                               $info['act'] = 'file';
+                                       }
                                } else {        // URL is a page (id parameter)
                                        $uP=parse_url($rel);
                                        if (!trim($uP['path'])) {
-                                               $pp = explode('id=',$uP['query']);
-                                               $id = $pp[1];
+                                               $pp = preg_split('/^id=/', $uP['query']);
+                                               $pp[1] = preg_replace( '/&id=[^&]*/', '', $pp[1]);
+                                               $parameters = explode('&', $pp[1]);
+                                               $id = array_shift($parameters);
                                                if ($id)        {
                                                                // Checking if the id-parameter is an alias.
                                                        if (!t3lib_div::testInt($id))   {
@@ -2165,6 +2671,7 @@ class browse_links {
                                                        $info['pageid']=$id;
                                                        $info['cElement']=$uP['fragment'];
                                                        $info['act']='page';
+                                                       $info['query'] = $parameters[0]?'&'.implode('&', $parameters):'';
                                                }
                                        }
                                }
@@ -2181,6 +2688,12 @@ class browse_links {
                        $info['value']='';
                        $info['act']='page';
                }
+
+                       // let the hook have a look
+               foreach($this->hookObjects as $hookObject) {
+                       $info = $hookObject->parseCurrentUrl($href, $siteUrl, $info);
+               }
+
                return $info;
        }
 
@@ -2193,23 +2706,34 @@ class browse_links {
         */
        function uploadForm($path)      {
                global $BACK_PATH;
-               $count=3;
+
+               if ($this->isReadOnlyFolder($path)) return '';
+
+                       // Read configuration of upload field count
+               $userSetting = $GLOBALS['BE_USER']->getTSConfigVal('options.folderTree.uploadFieldsInLinkBrowser');
+               $count = isset($userSetting) ? $userSetting : 3;
+               if ($count === '0') {
+                       return '';
+               }
+               $count = intval($count) == 0 ? 3 : intval($count);
 
                        // Create header, showing upload path:
                $header = t3lib_div::isFirstPartOfStr($path,PATH_site)?substr($path,strlen(PATH_site)):$path;
-               $code=$this->barheader($GLOBALS['LANG']->getLL('uploadImage').':');
-               $code.='
+               $code = '
 
                        <!--
                                Form, for uploading files:
                        -->
-                       <form action="'.$BACK_PATH.'tce_file.php" method="post" name="editform" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'">
-                               <table border="0" cellpadding="0" cellspacing="3" id="typo3-uplFiles">
+                       <form action="' . $BACK_PATH . 'tce_file.php" method="post" name="editform" id="typo3-uplFilesForm" enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '">
+                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-uplFiles">
+                                       <tr>
+                                               <td>' . $this->barheader($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:file_upload.php.pagetitle', 1) . ':') . '</td>
+                                       </tr>
                                        <tr>
-                                               <td><strong>'.$GLOBALS['LANG']->getLL('path',1).':</strong> '.htmlspecialchars($header).'</td>
+                                               <td class="c-wCell c-hCell"><strong>' . $GLOBALS['LANG']->getLL('path', 1) . ':</strong> ' . htmlspecialchars($header) . '</td>
                                        </tr>
                                        <tr>
-                                               <td>';
+                                               <td class="c-wCell c-hCell">';
 
                        // Traverse the number of upload fields (default is 3):
                for ($a=1;$a<=$count;$a++)      {
@@ -2220,13 +2744,13 @@ class browse_links {
 
                        // Make footer of upload form, including the submit button:
                $redirectValue = $this->thisScript.'?act='.$this->act.'&mode='.$this->mode.'&expandFolder='.rawurlencode($path).'&bparams='.rawurlencode($this->bparams);
-               $code.='<input type="hidden" name="redirect" value="'.htmlspecialchars($redirectValue).'" />'.
-                               '<input type="submit" name="submit" value="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:file_upload.php.submit',1).'" />';
+               $code .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($redirectValue) . '" />';
 
                $code.='
                        <div id="c-override">
-                               <input type="checkbox" name="overwriteExistingFiles" value="1" /> '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:overwriteExistingFiles',1).'
+                               <label><input type="checkbox" name="overwriteExistingFiles" id="overwriteExistingFiles" value="1" /> ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:overwriteExistingFiles', 1) . '</label>
                        </div>
+                       <input type="submit" name="submit" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:file_upload.php.submit', 1) . '" />
                ';
 
 
@@ -2247,21 +2771,30 @@ class browse_links {
         */
        function createFolder($path)    {
                global $BACK_PATH;
+
+               if ($this->isReadOnlyFolder($path)) return '';
+
+                       // Don't show Folder-create form if it's denied
+               if ($GLOBALS['BE_USER']->getTSConfigVal('options.folderTree.hideCreateFolder')) {
+                       return '';
+               }
                        // Create header, showing upload path:
                $header = t3lib_div::isFirstPartOfStr($path,PATH_site)?substr($path,strlen(PATH_site)):$path;
-               $code=$this->barheader($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:file_newfolder.php.pagetitle').':');
-               $code.='
+               $code = '
 
                        <!--
                                Form, for creating new folders:
                        -->
-                       <form action="'.$BACK_PATH.'tce_file.php" method="post" name="editform2">
-                               <table border="0" cellpadding="0" cellspacing="3" id="typo3-crFolder">
+                       <form action="' . $BACK_PATH . 'tce_file.php" method="post" name="editform2" id="typo3-crFolderForm">
+                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-crFolder">
                                        <tr>
-                                               <td><strong>'.$GLOBALS['LANG']->getLL('path',1).':</strong> '.htmlspecialchars($header).'</td>
+                                               <td>' . $this->barheader($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:file_newfolder.php.pagetitle') . ':') . '</td>
                                        </tr>
                                        <tr>
-                                               <td>';
+                                               <td class="c-wCell c-hCell"><strong>' . $GLOBALS['LANG']->getLL('path', 1) . ':</strong> ' . htmlspecialchars($header) . '</td>
+                                       </tr>
+                                       <tr>
+                                               <td class="c-wCell c-hCell">';
 
                        // Create the new-folder name field:
                $a=1;
@@ -2280,12 +2813,88 @@ class browse_links {
 
                return $code;
        }
-}
 
-// Include extension?
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/class.browse_links.php'])   {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/class.browse_links.php']);
+       /**
+        * Get the HTML data required for a bulk selection of files of the TYPO3 Element Browser.
+        *
+        * @param       integer         $filesCount: Number of files currently displayed
+        * @return      string          HTML data required for a bulk selection of files - if $filesCount is 0, nothing is returned
+        */
+       function getBulkSelector($filesCount) {
+               if ($filesCount) {
+                       $labelToggleSelection = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.php:toggleSelection',1);
+                       $labelImportSelection = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.php:importSelection',1);
+
+                       // Getting flag for showing/not showing thumbnails:
+                       $noThumbsInEB = $GLOBALS['BE_USER']->getTSConfigVal('options.noThumbsInEB');
+
+                       $out = $this->doc->spacer(15).'<div>' .
+                                       '<a href="#" onclick="BrowseLinks.Selector.toggle()">' .
+                                               '<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/clip_select.gif','width="12" height="12"').' title="'.$labelToggleSelection.'" alt="" /> ' .
+                                               $labelToggleSelection.'</a>'.$this->doc->spacer(5) .
+                                       '<a href="#" onclick="BrowseLinks.Selector.handle()">' .
+                                               '<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/import.gif','width="12" height="12"').' title="'.$labelImportSelection.'" alt="" /> ' .
+                                               $labelImportSelection.'</a>' .
+                               '</div>';
+
+                       $thumbNailCheck = '';
+                       if (!$noThumbsInEB) {
+                               $path = $this->expandFolder;
+                               if (!$path || !@is_dir($path)) {
+                                               // The closest TEMP-path is found
+                                       $path = $this->fileProcessor->findTempFolder() . '/';
+                               }
+                                       // MENU-ITEMS, fetching the setting for thumbnails from File>List module:
+                               $_MOD_MENU = array('displayThumbs' => '');
+                               $_MCONF['name'] = 'file_list';
+                               $_MOD_SETTINGS = t3lib_BEfunc::getModuleData($_MOD_MENU, t3lib_div::_GP('SET'), $_MCONF['name']);
+                               $addParams = '&act=' . $this->act . '&mode=' . $this->mode . '&expandFolder=' . rawurlencode($path) . '&bparams=' . rawurlencode($this->bparams);
+                               $thumbNailCheck = t3lib_BEfunc::getFuncCheck('', 'SET[displayThumbs]', $_MOD_SETTINGS['displayThumbs'], $this->thisScript, $addParams, 'id="checkDisplayThumbs"') . ' <label for="checkDisplayThumbs">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_file_list.php:displayThumbs', 1) . '</label>';
+                               $out .= $this->doc->spacer(5) . $thumbNailCheck . $this->doc->spacer(15);
+                       } else {
+                               $out .= $this->doc->spacer(15);
+                       }
+               }
+               return $out;
+       }
+
+       /**
+        * Determines whether submitted field change functions are valid
+        * and are coming from the system and not from an external abuse.
+        *
+        * @param boolean $allowFlexformSections Whether to handle flexform sections differently
+        * @return boolean Whether the submitted field change functions are valid
+        */
+       protected function areFieldChangeFunctionsValid($handleFlexformSections = FALSE) {
+               $result = FALSE;
+
+               if (isset($this->P['fieldChangeFunc']) && is_array($this->P['fieldChangeFunc']) && isset($this->P['fieldChangeFuncHash'])) {
+                       $matches = array();
+                       $pattern = '#\[el\]\[(([^]-]+-[^]-]+-)(idx\d+-)([^]]+))\]#i';
+
+                       $fieldChangeFunctions = $this->P['fieldChangeFunc'];
+
+                               // Special handling of flexform sections:
+                               // Field change functions are modified in JavaScript, thus the hash is always invalid
+                       if ($handleFlexformSections && preg_match($pattern, $this->P['itemName'], $matches)) {
+                               $originalName = $matches[1];
+                               $cleanedName = $matches[2] . $matches[4];
+
+                               foreach ($fieldChangeFunctions as &$value) {
+                                       $value = str_replace($originalName, $cleanedName, $value);
+                               }
+                       }
+
+                       $result = ($this->P['fieldChangeFuncHash'] === t3lib_div::hmac(serialize($fieldChangeFunctions)));
+               }
+
+               return $result;
+       }
 }
 
 
-?>
\ No newline at end of file
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/class.browse_links.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/class.browse_links.php']);
+}
+
+?>