[BUGFIX] Adjustments to FAL-enabled RTE image and link dialogues
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / mod3 / class.tx_rtehtmlarea_browse_links.php
index acd64b3..d3a8650 100644 (file)
@@ -2,8 +2,8 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2004 Kasper Skaarhoj (kasperYYYY@typo3.com)
-*  (c) 2005-2006 Stanislas Rolland <stanislas.rolland(arobas)fructifor.ca>
+*  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
+*  (c) 2005-2012 Stanislas Rolland <typo3(arobas)sjbr.ca>
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  *
  * Adapted for htmlArea RTE by Stanislas Rolland
  *
- * $Id$
- *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
- * @author     Stanislas Rolland <stanislas.rolland(arobas)fructifor.ca>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
+ * @author     Stanislas Rolland <typo3(arobas)sjbr.ca>
  */
 
 require_once (PATH_typo3.'class.browse_links.php');
-require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
 
 
 /**
  * Class which generates the page tree
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
@@ -58,7 +55,6 @@ class tx_rtehtmlarea_pageTree extends rtePageTree {
         * @return      string          HTML output.
         */
        function printTree($treeArr='') {
-               global $BACK_PATH;
                $titleLen=intval($GLOBALS['BE_USER']->uc['titleLen']);
                if (!is_array($treeArr))        $treeArr=$this->tree;
 
@@ -68,17 +64,17 @@ class tx_rtehtmlarea_pageTree extends rtePageTree {
                foreach($treeArr as $k => $v)   {
                        $c++;
                        $bgColorClass = ($c+1)%2 ? 'bgColor' : 'bgColor-10';
-                       if ($GLOBALS['SOBE']->browser->curUrlInfo['act']=='page' && $GLOBALS['SOBE']->browser->curUrlInfo['pageid']==$v['row']['uid'] && $GLOBALS['SOBE']->browser->curUrlInfo['pageid'])       {
-                               $arrCol='<td><img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/blinkarrow_right.gif','width="5" height="9"').' class="c-blinkArrowR" alt="" /></td>';
+                       if ($GLOBALS['SOBE']->browser->curUrlInfo['act']=='page' && $GLOBALS['SOBE']->browser->curUrlInfo['pageid']==$v['row']['uid'] && $GLOBALS['SOBE']->browser->curUrlInfo['pageid']) {
+                               $arrCol = '<td><img' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_right.gif', 'width="5" height="9"') . ' class="c-blinkArrowR" alt="" /></td>';
                                $bgColorClass='bgColor4';
                        } else {
                                $arrCol='<td></td>';
                        }
 
-                       $aOnClick = 'return jumpToUrl(\''.$this->thisScript.'?act='.$GLOBALS['SOBE']->browser->act.'&editorNo='.$GLOBALS['SOBE']->browser->editorNo.'&contentTypo3Language='.$GLOBALS['SOBE']->browser->contentTypo3Language.'&contentTypo3Charset='.$GLOBALS['SOBE']->browser->contentTypo3Charset.'&mode='.$GLOBALS['SOBE']->browser->mode.'&expandPage='.$v['row']['uid'].'\');';
-                       $cEbullet = $this->ext_isLinkable($v['row']['doktype'],$v['row']['uid']) ?
-                                               '<a href="#" onclick="'.htmlspecialchars($aOnClick).'"><img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/ol/arrowbullet.gif','width="18" height="16"').' alt="" /></a>' :
-                                               '';
+                       $aOnClick = 'return jumpToUrl(\''.$this->thisScript.'?act='.$GLOBALS['SOBE']->browser->act.'&editorNo='.$GLOBALS['SOBE']->browser->editorNo.'&contentTypo3Language='.$GLOBALS['SOBE']->browser->contentTypo3Language.'&mode='.$GLOBALS['SOBE']->browser->mode.'&expandPage='.$v['row']['uid'].'\');';
+                       $cEbullet = ($this->ext_isLinkable($v['row']['doktype'], $v['row']['uid'])
+                               ? '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"><img' . t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/ol/arrowbullet.gif', 'width="18" height="16"') . ' alt="" /></a>'
+                               : '');
                        $out.='
                                <tr class="'.$bgColorClass.'">
                                        <td nowrap="nowrap"'.($v['row']['_CSSCLASS'] ? ' class="'.$v['row']['_CSSCLASS'].'"' : '').'>'.
@@ -106,7 +102,7 @@ class tx_rtehtmlarea_pageTree extends rtePageTree {
  * 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
  */
@@ -115,100 +111,68 @@ class tx_rtehtmlarea_folderTree extends rteFolderTree {
        /**
         * Wrapping the title in a link, if applicable.
         *
-        * @param       string          Title, ready for output.
-        * @param       array           The "record"
-        * @return      string          Wrapping title string.
+        * @param       string                  Title, ready for output.
+        * @param       t3lib_file_Folder       The "record"
+        * @return      string                  Wrapping title string.
         */
-       function wrapTitle($title,$v)   {
-               if ($this->ext_isLinkable($v))  {
-                       $aOnClick = 'return jumpToUrl(\''.$this->thisScript.'?act='.$GLOBALS['SOBE']->browser->act.'&editorNo='.$GLOBALS['SOBE']->browser->editorNo.'&contentTypo3Language='.$GLOBALS['SOBE']->browser->contentTypo3Language.'&contentTypo3Charset='.$GLOBALS['SOBE']->browser->contentTypo3Charset.'&mode='.$GLOBALS['SOBE']->browser->mode.'&expandFolder='.rawurlencode($v['path']).'\');';
-                       return '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.$title.'</a>';
+       function wrapTitle ($title, t3lib_file_Folder $folderObject) {
+               if ($this->ext_isLinkable($folderObject)) {
+                       $aOnClick = 'return jumpToUrl(\'' . $this->thisScript .
+                               '?act=' . $GLOBALS['SOBE']->browser->act .
+                               '&mode=' . $GLOBALS['SOBE']->browser->mode .
+                               '&editorNo=' . $GLOBALS['SOBE']->browser->editorNo .
+                               '&contentTypo3Language=' . $GLOBALS['SOBE']->browser->contentTypo3Language .
+                               '&contentTypo3Charset=' . $GLOBALS['SOBE']->browser->contentTypo3Charset .
+                               '&expandFolder=' . rawurlencode($folderObject->getCombinedIdentifier()) . '\');';
+                       return '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . $title . '</a>';
                } else {
-                       return '<span class="typo3-dimmed">'.$title.'</span>';
+                       return '<span class="typo3-dimmed">' . $title . '</span>';
                }
        }
 
        /**
-        * Create the folder navigation tree in HTML
+        * Wrap the plus/minus icon in a link
         *
-        * @param       mixed           Input tree array. If not array, then $this->tree is used.
-        * @return      string          HTML output of the tree.
+        * @param       string          HTML string to wrap, probably an image tag.
+        * @param       string          Command for 'PM' get var
+        * @return      string          Link-wrapped input string
+        * @access private
         */
-       function printTree($treeArr='') {
-               global $BACK_PATH;
-               $titleLen=intval($GLOBALS['BE_USER']->uc['titleLen']);
-
-               if (!is_array($treeArr))        $treeArr=$this->tree;
-
-               $out='';
-               $c=0;
-
-                       // 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)!='/') {
-                       $cmpPath=PATH_site.dirname($GLOBALS['SOBE']->browser->curUrlInfo['info']).'/';
+       public function PMiconATagWrap ($icon, $cmd, $isExpand = TRUE) {
+               if ($this->thisScript) {
+                       $js = htmlspecialchars('Tree.thisScript=\'' . $GLOBALS['BACK_PATH'] . 'ajax.php\',Tree.load(\'' . $cmd . '\', ' . intval($isExpand) . ', this);');
+                       return '<a class="pm" onclick="' . $js . '">' . $icon . '</a>';
                } else {
-                       $cmpPath=PATH_site.$GLOBALS['SOBE']->browser->curUrlInfo['info'];
+                       return $icon;
                }
-
-                       // Traverse rows for the tree and print them into table rows:
-               foreach($treeArr as $k => $v)   {
-                       $c++;
-                       $bgColorClass=($c+1)%2 ? 'bgColor' : 'bgColor-10';
-
-                               // Creating blinking arrow, if applicable:
-                       if ($GLOBALS['SOBE']->browser->curUrlInfo['act']=='file' && $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 {
-                               $arrCol='<td></td>';
-                       }
-                               // Create arrow-bullet for file listing (if folder path is linkable):
-                       $aOnClick = 'return jumpToUrl(\''.$this->thisScript.'?act='.$GLOBALS['SOBE']->browser->act.'&editorNo='.$GLOBALS['SOBE']->browser->editorNo.'&contentTypo3Language='.$GLOBALS['SOBE']->browser->contentTypo3Language.'&contentTypo3Charset='.$GLOBALS['SOBE']->browser->contentTypo3Charset.'&mode='.$GLOBALS['SOBE']->browser->mode.'&expandFolder='.rawurlencode($v['row']['path']).'\');';
-                       $cEbullet = $this->ext_isLinkable($v['row']) ? '<a href="#" onclick="'.htmlspecialchars($aOnClick).'"><img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/ol/arrowbullet.gif','width="18" height="16"').' alt="" /></a>' : '';
-
-                               // 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>
-                                       '.$arrCol.'
-                                       <td>'.$cEbullet.'</td>
-                               </tr>';
-               }
-
-               $out='
-
-                       <!--
-                               Folder tree:
-                       -->
-                       <table border="0" cellpadding="0" cellspacing="0" id="typo3-tree">
-                               '.$out.'
-                       </table>';
-               return $out;
        }
-
 }
 
 /**
  * Script class for the Element Browser window.
  *
- * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @author     Kasper Skårhøj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
 class tx_rtehtmlarea_browse_links extends browse_links {
 
-               // Internal, static:
-       var $setTarget;                 // Target (RTE specific)
-       var $setClass;                  // Class (RTE specific)
-       var $setTitle;                  // Title (RTE specific)
+       public $editorNo;
+       public $contentTypo3Language;
+       public $contentTypo3Charset = 'utf-8';
+       public $additionalAttributes = array();
+       public $buttonConfig = array();
+       public $RTEProperties = array();
 
-       var $contentTypo3Language;
-       var $contentTypo3Charset;
+       public $anchorTypes = array( 'page', 'url', 'file', 'mail', 'spec');
+       public $classesAnchorDefault = array();
+       public $classesAnchorDefaultTitle = array();
+       public $classesAnchorClassTitle = array();
+       public $classesAnchorDefaultTarget = array();
+       public $classesAnchorJSOptions = array();
+       protected $defaultLinkTarget;
 
-       var $editorNo;
-       var $buttonConfig = array();
+       public $allowedItems;
 
        /**
         * Constructor:
@@ -217,364 +181,380 @@ class tx_rtehtmlarea_browse_links extends browse_links {
         * @return      void
         */
        function init() {
-               global $BE_USER,$BACK_PATH,$LANG;
+               $this->initVariables();
+               $this->initConfiguration();
+                       // init fileProcessor
+               $this->fileProcessor = t3lib_div::makeInstance('t3lib_basicFileFunctions');
+               $this->fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
+                       // Creating backend template object:
+               $this->doc = t3lib_div::makeInstance('template');
+               $this->doc->backPath = $GLOBALS['BACK_PATH'];
+                       // Loading the Prototype library and browse_links.js
+               $this->doc->getPageRenderer()->loadPrototype();
+               $this->doc->loadJavascriptLib('js/tree.js');
+               $this->doc->loadJavascriptLib('js/browse_links.js');
+                       // Adding context menu code
+               $this->doc->getContextMenuCode();
+                       // Initializing hooking browsers
+               $this->initHookObjects('ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php');
+                       // CurrentUrl - the current link url must be passed around if it exists
+               $this->curUrlArray = t3lib_div::_GP('curUrl');
+               if ($this->curUrlArray['all'])  {
+                       $this->curUrlArray = t3lib_div::get_tag_attributes($this->curUrlArray['all']);
+                       $this->curUrlArray['href'] = htmlspecialchars_decode($this->curUrlArray['href']);
+               }
+                       // Note: parseCurUrl will invoke the hooks
+               $this->curUrlInfo = $this->parseCurUrl($this->curUrlArray['href'], $this->siteURL);
+               if (isset($this->curUrlArray['data-htmlarea-external']) && $this->curUrlInfo['act'] != 'mail') {
+                       $this->curUrlInfo['act'] = 'url';
+                       $this->curUrlInfo['info'] = $this->curUrlArray['href'];
+               }
+                       // Determine nature of current url:
+               $this->act = t3lib_div::_GP('act');
+               if (!$this->act) {
+                       $this->act = $this->curUrlInfo['act'];
+               }
+                       // Setting intial values for link attributes
+               $this->initLinkAttributes();
+                       // Apply the same styles as those of the base script
+               $this->doc->bodyTagId = 'typo3-browse-links-php';
+                       // Add attributes to body tag. Note: getBodyTagAdditions will invoke the hooks
+               $this->doc->bodyTagAdditions = $this->getBodyTagAdditions();
+                       // Adding RTE JS code
+               $this->doc->JScodeArray['rtehtmlarea'] = $this->getJSCode();
+       }
+
+       /**
+        * Initialize class variables
+        *
+        * @return      void
+        */
+       public function initVariables() {
 
                        // Main GPvars:
-               $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->contentTypo3Language = t3lib_div::_GP('typo3ContentLanguage');
-               $this->contentTypo3Charset = t3lib_div::_GP('typo3ContentCharset');
-               $this->editorNo = t3lib_div::_GP('editorNo');
+               $this->pointer           = t3lib_div::_GP('pointer');
+               $this->bparams           = t3lib_div::_GP('bparams');
+               $this->P                 = t3lib_div::_GP('P');
+               $this->expandPage        = t3lib_div::_GP('expandPage');
+               $this->expandFolder      = t3lib_div::_GP('expandFolder');
+               $this->PM                = t3lib_div::_GP('PM');
+
+                       // Process bparams
+               $pArr = explode('|', $this->bparams);
+               $pRteArr = explode(':', $pArr[1]);
+               $this->editorNo = $pRteArr[0];
+               $this->contentTypo3Language = $pRteArr[1];
+               $this->RTEtsConfigParams = $pArr[2];
+               if (!$this->editorNo) {
+                       $this->editorNo = t3lib_div::_GP('editorNo');
+                       $this->contentTypo3Language = t3lib_div::_GP('contentTypo3Language');
+                       $this->RTEtsConfigParams = t3lib_div::_GP('RTEtsConfigParams');
+               }
+               $pArr[1] = implode(':', array($this->editorNo, $this->contentTypo3Language, $this->contentTypo3Charset));
+               $pArr[2] = $this->RTEtsConfigParams;
+               $this->bparams = implode('|', $pArr);
 
                        // Find "mode"
-               $this->mode=t3lib_div::_GP('mode');
+               $this->mode = t3lib_div::_GP('mode');
                if (!$this->mode)       {
-                       $this->mode='rte';
+                       $this->mode = 'rte';
                }
+                       // Current site url
+               $this->siteURL = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
+
+                       // the script to link to
+               $this->thisScript = t3lib_div::getIndpEnv('SCRIPT_NAME');
+       }
+
+       /**
+        * Initializes the configuration variables
+        *
+        * @return      void
+        */
+        public function initConfiguration() {
+               $this->thisConfig = $this->getRTEConfig();
+               $this->buttonConfig = $this->getButtonConfig('link');
+        }
+
+       /**
+        * Get the RTE configuration from Page TSConfig
+        *
+        * @return      array           RTE configuration array
+        */
+       protected function getRTEConfig()       {
+               $RTEtsConfigParts = explode(':', $this->RTEtsConfigParams);
+               $RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE', t3lib_BEfunc::getPagesTSconfig($RTEtsConfigParts[5]));
+               $this->RTEProperties = $RTEsetup['properties'];
+               return t3lib_BEfunc::RTEsetup($this->RTEProperties, $RTEtsConfigParts[0],$RTEtsConfigParts[2],$RTEtsConfigParts[4]);
+       }
 
-                       // init hook objects:
-               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);
+       /**
+        * Get the configuration of the button
+        *
+        * @param       string          $buttonName: the name of the button
+        * @return      array           the configuration array of the image button
+        */
+       protected function getButtonConfig($buttonName) {
+               return ((is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.'][$buttonName.'.'])) ? $this->thisConfig['buttons.'][$buttonName.'.'] : array());
+       }
 
+       /**
+        * Initialize hook objects implementing interface t3lib_browseLinksHook
+        * @param       string          $hookKey: the hook key
+        * @return      void
+        */
+       protected function initHookObjects($hookKey) {
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][$hookKey]['browseLinksHook'])) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][$hookKey]['browseLinksHook'] as $classData) {
+                               $processObject = t3lib_div::getUserObj($classData);
                                if(!($processObject instanceof t3lib_browseLinksHook)) {
                                        throw new UnexpectedValueException('$processObject must implement interface t3lib_browseLinksHook', 1195115652);
                                }
-
                                $parameters = array();
                                $processObject->init($this, $parameters);
                                $this->hookObjects[] = $processObject;
                        }
                }
+       }
 
-                       // Site URL
-               $this->siteURL = t3lib_div::getIndpEnv('TYPO3_SITE_URL');       // Current site url
-
-                       // the script to link to
-               $this->thisScript = t3lib_div::getIndpEnv('SCRIPT_NAME');
-
-                       // 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]
-                       );
-                       $this->curUrlInfo=$this->parseCurUrl($this->siteURL.'?id='.$currentLinkParts[0],$this->siteURL);
-               } else {
-                       $this->curUrlArray = t3lib_div::_GP('curUrl');
-                       if ($this->curUrlArray['all'])  {
-                               $this->curUrlArray=t3lib_div::get_tag_attributes($this->curUrlArray['all']);
-                       }
-                       $this->curUrlInfo=$this->parseCurUrl($this->curUrlArray['href'],$this->siteURL);
-               }
-
-                       // Determine nature of current url:
-               $this->act=t3lib_div::_GP('act');
-               if (!$this->act)        {
-                       $this->act=$this->curUrlInfo['act'];
-               }
-
-                       // Initializing the titlevalue
-               $this->setTitle = $LANG->csConvObj->conv($this->curUrlArray['title'], 'utf-8', $LANG->charSet);
-
-                       // Rich Text Editor specific configuration:
-               $addPassOnParams='';
-               if ((string)$this->mode=='rte') {
-                       $RTEtsConfigParts = explode(':',$this->RTEtsConfigParams);
-                       $addPassOnParams .= '&RTEtsConfigParams='.rawurlencode($this->RTEtsConfigParams);
-                       $addPassOnParams .= ($this->contentTypo3Language ? '&typo3ContentLanguage=' . rawurlencode($this->contentTypo3Language) : '');
-                       $addPassOnParams .= ($this->contentTypo3Charset ? '&typo3ContentCharset=' . rawurlencode($this->contentTypo3Charset) : '');
-                       $RTEsetup = $BE_USER->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($RTEtsConfigParts[5]));
-                       $this->thisConfig = t3lib_BEfunc::RTEsetup($RTEsetup['properties'],$RTEtsConfigParts[0],$RTEtsConfigParts[2],$RTEtsConfigParts[4]);
-                       if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['link.'])) {
-                               $this->buttonConfig = $this->thisConfig['buttons.']['link.'];
-                       }
-                       if($this->thisConfig['classesAnchor']) {
-                               $this->setClass = $this->curUrlArray['class'];
-                               $classesAnchorArray = t3lib_div::trimExplode(',',$this->thisConfig['classesAnchor'],1);
-                               $anchorTypes = array( 'page', 'url', 'file', 'mail', 'spec');
-                               $classesAnchor = array();
-                               $classesAnchorDefault = array();
-                               $this->classesAnchorDefaultTitle = array();
-                               $classesAnchor['all'] = array();
-                               if (is_array($RTEsetup['properties']['classesAnchor.'])) {
-                                       reset($RTEsetup['properties']['classesAnchor.']);
-                                       while(list($label,$conf)=each($RTEsetup['properties']['classesAnchor.'])) {
+       /**
+        * Initialize the current or default values of the link attributes
+        *
+        * @return      void
+        */
+       protected function initLinkAttributes() {
+
+                       // Initializing the title value
+               $this->setTitle = $this->curUrlArray['title'];
+
+                       // Processing the classes configuration
+               $classSelected = array();
+               if ($this->buttonConfig['properties.']['class.']['allowedClasses']) {
+                       $this->setClass = $this->curUrlArray['class'];
+                       $classesAnchorArray = t3lib_div::trimExplode(',', $this->buttonConfig['properties.']['class.']['allowedClasses'], 1);
+                       $classesAnchorConfigArray = array();
+                               // Collecting allowed classes and configured default values
+                       $classesAnchor = array();
+                       $classesAnchor['all'] = array();
+                       $titleReadOnly = $this->buttonConfig['properties.']['title.']['readOnly'] || $this->buttonConfig[$this->act.'.']['properties.']['title.']['readOnly'];
+                       if (is_array($this->RTEProperties['classesAnchor.'])) {
+                               foreach ($this->RTEProperties['classesAnchor.'] as $label => $conf) {
+                                       if (in_array($conf['class'], $classesAnchorArray)) {
                                                $classesAnchor['all'][] = $conf['class'];
-                                               if (in_array($conf['type'], $anchorTypes)) {
+                                               if (in_array($conf['type'], $this->anchorTypes)) {
                                                        $classesAnchor[$conf['type']][] = $conf['class'];
-                                                       if (is_array($this->thisConfig['classesAnchor.']) && is_array($this->thisConfig['classesAnchor.']['default.']) && $this->thisConfig['classesAnchor.']['default.'][$conf['type']] == $conf['class']) {
-                                                               $classesAnchorDefault[$conf['type']] = $conf['class'];
+                                                       if ($this->buttonConfig[$conf['type']. '.']['properties.']['class.']['default'] == $conf['class']) {
+                                                               $this->classesAnchorDefault[$conf['type']] = $conf['class'];
                                                                if ($conf['titleText']) {
-                                                                       $string = trim($conf['titleText']);
-                                                                       if (substr($string,0,4)=='LLL:') {       // language file
-                                                                               $arr = explode(':',$string);
-                                                                               if($arr[0] == 'LLL' && $arr[1] == 'EXT') {
-                                                                                       $BE_lang = $LANG->lang;
-                                                                                       $BE_origCharset = $LANG->origCharSet;
-                                                                                       $LANG->lang = $this->contentTypo3Language;
-                                                                                       $LANG->origCharSet = $LANG->csConvObj->charSetArray[$this->contentTypo3Language];
-                                                                                       $LANG->origCharSet = $LANG->origCharSet ? $LANG->origCharSet : 'iso-8859-1';
-                                                                                       $string = $LANG->getLLL($arr[3], $LANG->readLLfile($arr[1].':'.$arr[2]), true);
-                                                                                       $LANG->lang = $BE_lang;
-                                                                                       $LANG->origCharSet = $BE_origCharset;
-                                                                               }
-                                                                       }
-                                                                       $this->classesAnchorDefaultTitle[$conf['type']] = $string;
+                                                                       $this->classesAnchorDefaultTitle[$conf['type']] = $this->getLLContent(trim($conf['titleText']));
+                                                               }
+                                                               if ($conf['target']) {
+                                                                       $this->classesAnchorDefaultTarget[$conf['type']] = trim($conf['target']);
                                                                }
                                                        }
                                                }
-                                       }
-                               }
-                               $this->classesAnchorJSOptions = array();
-                               reset($anchorTypes);
-                               while (list(, $anchorType) = each($anchorTypes) ) {
-                                       reset($classesAnchorArray);
-                                       while(list(,$class)=each($classesAnchorArray)) {
-                                               if (!in_array($class, $classesAnchor['all']) || (in_array($class, $classesAnchor['all']) && is_array($classesAnchor[$anchorType]) && in_array($class, $classesAnchor[$anchorType]))) {
-                                                       $selected = '';
-                                                       if ($this->setClass == $class) $selected = 'selected="selected"';
-                                                       if (!$this->setClass && $classesAnchorDefault[$anchorType] == $class) {
-                                                               $selected = 'selected="selected"';
-                                                       }
-                                                       $this->classesAnchorJSOptions[$anchorType] .= '<option ' . $selected . ' value="' .$class . '">' . $class . '</option>';
+                                               if ($titleReadOnly && $conf['titleText']) {
+                                                       $this->classesAnchorClassTitle[$conf['class']] = $this->classesAnchorDefaultTitle[$conf['type']] = $this->getLLContent(trim($conf['titleText']));
                                                }
                                        }
-                                       if ($this->classesAnchorJSOptions[$anchorType]) {
+                               }
+                       }
+                               // Constructing the class selector options
+                       foreach ($this->anchorTypes as $anchorType) {
+                               foreach ($classesAnchorArray as $class) {
+                                       if (!in_array($class, $classesAnchor['all']) || (in_array($class, $classesAnchor['all']) && is_array($classesAnchor[$anchorType]) && in_array($class, $classesAnchor[$anchorType]))) {
                                                $selected = '';
-                                               if (!$this->setClass && !$classesAnchorDefault[$anchorType])  $selected = 'selected="selected"';
-                                               $this->classesAnchorJSOptions[$anchorType] =  '<option ' . $selected . ' value=""></option>' . $this->classesAnchorJSOptions[$anchorType];
+                                               if ($this->setClass == $class || (!$this->setClass && $this->classesAnchorDefault[$anchorType] == $class)) {
+                                                       $selected = 'selected="selected"';
+                                                       $classSelected[$anchorType] = TRUE;
+                                               }
+                                               $classLabel = (is_array($this->RTEProperties['classes.']) && is_array($this->RTEProperties['classes.'][$class.'.']) && $this->RTEProperties['classes.'][$class.'.']['name']) ? $this->getPageConfigLabel($this->RTEProperties['classes.'][$class.'.']['name'], 0) : $class;
+                                               $classStyle = (is_array($this->RTEProperties['classes.']) && is_array($this->RTEProperties['classes.'][$class.'.']) && $this->RTEProperties['classes.'][$class.'.']['value']) ? $this->RTEProperties['classes.'][$class.'.']['value'] : '';
+                                               $this->classesAnchorJSOptions[$anchorType] .= '<option ' . $selected . ' value="' .$class . '"' . ($classStyle?' style="'.$classStyle.'"':'') . '>' . $classLabel . '</option>';
                                        }
                                }
+                               if ($this->classesAnchorJSOptions[$anchorType] && !($this->buttonConfig['properties.']['class.']['required'] || $this->buttonConfig[$this->act.'.']['properties.']['class.']['required'])) {
+                                       $selected = '';
+                                       if (!$this->setClass && !$this->classesAnchorDefault[$anchorType])  $selected = 'selected="selected"';
+                                       $this->classesAnchorJSOptions[$anchorType] =  '<option ' . $selected . ' value=""></option>' . $this->classesAnchorJSOptions[$anchorType];
+                               }
                        }
                }
-
-                       // Initializing the target value (RTE)
-               $this->setTarget = $this->curUrlArray['target'];
-               if ($this->thisConfig['defaultLinkTarget'] && !isset($this->curUrlArray['target']))     {
-                       $this->setTarget=$this->thisConfig['defaultLinkTarget'];
+                       // Initializing the target value
+                       // Unset the target if it is set to a value different than default and if no class is selected and the target field is not displayed
+                       // In other words, do not forward the target if we changed tab and the target field is not displayed
+               $this->defaultLinkTarget = isset($this->buttonConfig['properties.']['target.']['default']) ? $this->buttonConfig['properties.']['target.']['default'] : '';
+               $this->setTarget = '';
+               if (isset($this->curUrlArray['target']) && !(
+                               $this->curUrlArray['target'] != $this->defaultLinkTarget
+                               && !$classSelected[$this->act]
+                               && is_array($this->buttonConfig['targetSelector.']) && $this->buttonConfig['targetSelector.']['disabled'] 
+                               && is_array($this->buttonConfig['popupSelector.']) && $this->buttonConfig['popupSelector.']['disabled']
+                               )
+                       ) {
+                       $this->setTarget = $this->curUrlArray['target'];
                }
+               if ($this->defaultLinkTarget && !isset($this->curUrlArray['target'])) {
+                       $this->setTarget = $this->defaultLinkTarget;
+               }
+                       // Initializing additional attributes
+               if ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['TYPO3Link']['additionalAttributes']) {
+                       $addAttributes = t3lib_div::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['TYPO3Link']['additionalAttributes'], 1);
+                       foreach ($addAttributes as $attribute) {
+                               $this->additionalAttributes[$attribute] = isset($this->curUrlArray[$attribute]) ? $this->curUrlArray[$attribute] : '';
+                       }
+               }
+       }
 
-                       // Creating backend template object:
-               $this->doc = t3lib_div::makeInstance('template');
-               $this->doc->docType= 'xhtml_trans';
-               $this->doc->backPath = $BACK_PATH;
+       /**
+        * Provide the additional parameters to be included in the template body tag
+        *
+        * @return      string          the body tag additions
+        */
+       public function getBodyTagAdditions() {
+               $bodyTagAdditions = array();
+                       // call hook for extra additions
+               foreach ($this->hookObjects as $hookObject) {
+                       if (method_exists($hookObject, 'addBodyTagAdditions')) {
+                               $bodyTagAdditions = $hookObject->addBodyTagAdditions($bodyTagAdditions);
+                       }
+               }
+               return t3lib_div::implodeAttributes($bodyTagAdditions, TRUE);
+       }
 
+       /**
+        * Generate JS code to be used on the link insert/modify dialogue
+        *
+        * @return      string          the generated JS code
+        */
+       function getJSCode()    {
                        // BEGIN accumulation of header JavaScript:
                $JScode = '';
                $JScode.= '
-                       if (window.opener) {
-                               var editor = window.opener.RTEarea[' . $this->editorNo . ']["editor"];
-                               var HTMLArea = window.opener.HTMLArea;
-                       }
-                               // This JavaScript is primarily for RTE/Link. jumpToUrl is used in the other cases as well...
+                       var plugin = window.parent.RTEarea["' . $this->editorNo . '"].editor.getPlugin("TYPO3Link");
+                       var HTMLArea = window.parent.HTMLArea;
                        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 additionalValues = ' . (count($this->additionalAttributes) ? json_encode($this->additionalAttributes) : '{}') . ';';
 
-                       var cur_href="'.($this->curUrlArray['href']?$this->curUrlArray['href']:'').'";
+                       // Attributes setting functions
+               $JScode.= '
+                       var cur_href="'.($this->curUrlArray['href'] ? ($this->curUrlInfo['query'] ? substr($this->curUrlArray['href'], 0, -strlen($this->curUrlInfo['query'])) :$this->curUrlArray['href']):'').'";
                        var cur_target="'.($this->setTarget?$this->setTarget:'').'";
                        var cur_class="'.($this->setClass?$this->setClass:'').'";
                        var cur_title="'.($this->setTitle?$this->setTitle:'').'";
 
-                       function setTarget(value)       {
+                       function browse_links_setTarget(value)  {
                                cur_target=value;
                                add_target="&curUrl[target]="+encodeURIComponent(value);
                        }
-                       function setClass(value)        {
+                       function browse_links_setClass(value)   {
                                cur_class=value;
                                add_class="&curUrl[class]="+encodeURIComponent(value);
                        }
-                       function setTitle(value)        {
+                       function browse_links_setTitle(value)   {
                                cur_title=value;
                                add_title="&curUrl[title]="+encodeURIComponent(value);
                        }
-                       function setValue(value)        {
+                       function browse_links_setHref(value)    {
                                cur_href=value;
                                add_href="&curUrl[href]="+value;
                        }
-';
-
-               if ($this->mode=='wizard')      {       // Functions used, if the link selector is in wizard mode (= TCEforms fields)
-                       unset($this->P['fieldChangeFunc']['alert']);
-                       reset($this->P['fieldChangeFunc']);
-                       $update='';
-                       while(list($k,$v)=each($this->P['fieldChangeFunc']))    {
-
-                               $update.= '
-                               window.opener.'.$v;
+                       function browse_links_setAdditionalValue(name, value) {
+                               additionalValues[name] = value;
                        }
-
-                       $P2=array();
-                       $P2['itemName']=$this->P['itemName'];
-                       $P2['formName']=$this->P['formName'];
-                       $P2['fieldChangeFunc']=$this->P['fieldChangeFunc'];
-                       $addPassOnParams.=t3lib_div::implodeArrayForUrl('P',$P2);
-
-                       $JScode.='
-                               function link_typo3Page(id,anchor)      {       //
-                                       updateValueInMainForm(id+(anchor?anchor:"")+" "+cur_target);
-                                       close();
-                                       return false;
-                               }
-                               function link_folder(folder)    {       //
-                                       updateValueInMainForm(folder+" "+cur_target);
-                                       close();
-                                       return false;
-                               }
-                               function link_current() {       //
-                                       if (cur_href!="http://" && cur_href!="mailto:") {
-                                               var setValue = cur_href+" "+cur_target+" "+cur_class+" "+cur_title;
-                                               if (setValue.substr(0,7)=="http://")    setValue = setValue.substr(7);
-                                               if (setValue.substr(0,7)=="mailto:")    setValue = setValue.substr(7);
-                                               updateValueInMainForm(setValue);
-                                               close();
-                                       }
-                                       return false;
-                               }
-                               function checkReference()       {       //
-                                       if (window.opener && window.opener.document && window.opener.document.'.$this->P['formName'].' && window.opener.document.'.$this->P['formName'].'["'.$this->P['itemName'].'"] ) {
-                                               return window.opener.document.'.$this->P['formName'].'["'.$this->P['itemName'].'"];
-                                       } else {
-                                               close();
-                                       }
-                               }
-                               function updateValueInMainForm(input)   {       //
-                                       var field = checkReference();
-                                       if (field)      {
-                                               field.value = input;
-                                               '.$update.'
-                                       }
-                               }
-                       ';
-               } else {        // Functions used, if the link selector is in RTE mode:
-                       $JScode.='
-                               function link_typo3Page(id,anchor)      {
-                                       var theLink = \''.$this->siteURL.'?id=\'+id+(anchor?anchor:"");
-                                       if (document.ltargetform.anchor_title) setTitle(document.ltargetform.anchor_title.value);
-                                       if (document.ltargetform.anchor_class) setClass(document.ltargetform.anchor_class.value);
-                                       editor.renderPopup_addLink(theLink,cur_target,cur_class,cur_title);
-                                       return false;
-                               }
-                               function link_folder(folder)    {       //
-                                       var theLink = \''.$this->siteURL.'\'+folder;
-                                       if (document.ltargetform.anchor_title) setTitle(document.ltargetform.anchor_title.value);
-                                       if (document.ltargetform.anchor_class) setClass(document.ltargetform.anchor_class.value);
-                                       editor.renderPopup_addLink(theLink,cur_target,cur_class,cur_title);
-                                       return false;
-                               }
-                               function link_spec(theLink)     {       //
-                                       if (document.ltargetform.anchor_title) setTitle(document.ltargetform.anchor_title.value);
-                                       if (document.ltargetform.anchor_class) setClass(document.ltargetform.anchor_class.value);
-                                       editor.renderPopup_addLink(theLink,cur_target,cur_class,cur_title);
-                                       return false;
+               ';
+                       // Link setting functions
+               $JScode.='
+                       function link_typo3Page(id,anchor) {
+                               var parameters = (document.ltargetform.query_parameters && document.ltargetform.query_parameters.value) ? (document.ltargetform.query_parameters.value.charAt(0) == "&" ? "" : "&") + document.ltargetform.query_parameters.value : "";
+                               var theLink = \'' . $this->siteURL . '?id=\' + id + parameters + (anchor ? anchor : "");
+                               if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
+                               if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
+                               if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
+                               if (document.ltargetform.lrel) browse_links_setAdditionalValue("rel", document.ltargetform.lrel.value);
+                               browse_links_setAdditionalValue("data-htmlarea-external", "");
+                               plugin.createLink(theLink,cur_target,cur_class,cur_title,additionalValues);
+                               return false;
+                       }
+                       function link_folder(folder) {
+                               if (folder && folder.substr(0, 5) == "file:") {
+                                       var theLink = \'' . $this->siteURL . '?file:\' + encodeURIComponent(folder.substr(5));
+                               } else {
+                                       var theLink = \'' . $this->siteURL . '?\' + folder;
                                }
-                               function link_current() {       //
-                                       if (document.ltargetform.anchor_title) setTitle(document.ltargetform.anchor_title.value);
-                                       if (document.ltargetform.anchor_class) setClass(document.ltargetform.anchor_class.value);
-                                       if (cur_href!="http://" && cur_href!="mailto:") {
-                                               editor.renderPopup_addLink(cur_href,cur_target,cur_class,cur_title);
-                                       }
-                                       return false;
+                               if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
+                               if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
+                               if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
+                               if (document.ltargetform.lrel) browse_links_setAdditionalValue("rel", document.ltargetform.lrel.value);
+                               browse_links_setAdditionalValue("data-htmlarea-external", "");
+                               plugin.createLink(theLink,cur_target,cur_class,cur_title,additionalValues);
+                               return false;
+                       }
+                       function link_spec(theLink) {
+                               if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
+                               if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
+                               if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
+                               browse_links_setAdditionalValue("data-htmlarea-external", "");
+                               plugin.createLink(theLink,cur_target,cur_class,cur_title,additionalValues);
+                               return false;
+                       }
+                       function link_current() {
+                               var parameters = (document.ltargetform.query_parameters && document.ltargetform.query_parameters.value) ? (document.ltargetform.query_parameters.value.charAt(0) == "&" ? "" : "&") + document.ltargetform.query_parameters.value : "";
+                               if (document.ltargetform.anchor_title) browse_links_setTitle(document.ltargetform.anchor_title.value);
+                               if (document.ltargetform.anchor_class) browse_links_setClass(document.ltargetform.anchor_class.value);
+                               if (document.ltargetform.ltarget) browse_links_setTarget(document.ltargetform.ltarget.value);
+                               if (document.ltargetform.lrel) browse_links_setAdditionalValue("rel", document.ltargetform.lrel.value);
+                               if (cur_href!="http://" && cur_href!="mailto:") {
+                                       plugin.createLink(cur_href + parameters,cur_target,cur_class,cur_title,additionalValues);
                                }
-                       ';
-               }
-
-                       // General "jumpToUrl" function:
+                               return false;
+                       }
+               ';
+                       // General "jumpToUrl" and launchView functions:
                $JScode.='
-                       function jumpToUrl(URL,anchor)  {       //
+                       function jumpToUrl(URL,anchor) {
                                var add_editorNo = URL.indexOf("editorNo=")==-1 ? "&editorNo='.$this->editorNo.'" : "";
                                var add_contentTypo3Language = URL.indexOf("contentTypo3Language=")==-1 ? "&contentTypo3Language='.$this->contentTypo3Language.'" : "";
-                               var add_contentTypo3Charset = URL.indexOf("contentTypo3Charset=")==-1 ? "&contentTypo3Charset='.$this->contentTypo3Charset.'" : "";
                                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_editorNo+add_contentTypo3Language+add_contentTypo3Charset+add_mode+add_href+add_target+add_class+add_title+add_params'.($addPassOnParams?'+"'.$addPassOnParams.'"':'').'+(anchor?anchor:"");
+                               var add_additionalValues = "";
+                               if (plugin.pageTSConfiguration && plugin.pageTSConfiguration.additionalAttributes) {
+                                       var additionalAttributes = plugin.pageTSConfiguration.additionalAttributes.split(",");
+                                       for (var i = additionalAttributes.length; --i >= 0;) {
+                                               if (additionalValues[additionalAttributes[i]] != "") {
+                                                       add_additionalValues += "&curUrl[" + additionalAttributes[i] + "]=" + encodeURIComponent(additionalValues[additionalAttributes[i]]);
+                                               }
+                                       }
+                               }
+                               var theLocation = URL+add_act+add_editorNo+add_contentTypo3Language+add_mode+add_href+add_target+add_class+add_title+add_additionalValues+add_params+(anchor?anchor:"");
                                window.location.href = theLocation;
                                return false;
                        }
-               ';
-
-                       // This is JavaScript especially for the TBE Element Browser!
-               $pArr = explode('|',$this->bparams);
-               $formFieldName = 'data['.$pArr[0].']['.$pArr[1].']['.$pArr[2].']';
-               $JScode.='
-                       var elRef="";
-                       var targetDoc="";
-
-                       function launchView(url)        {       //
+                       function launchView(url) {
                                var thePreviewWindow="";
-                               thePreviewWindow = window.open("' . $BACK_PATH . 'show_item.php?table="+url,"ShowItem","height=300,width=410,status=0,menubar=0,resizable=0,location=0,directories=0,scrollbars=1,toolbar=0");
+                               thePreviewWindow = window.open("' . $GLOBALS['BACK_PATH'] . 'show_item.php?table="+url,"ShowItem","height=300,width=410,status=0,menubar=0,resizable=0,location=0,directories=0,scrollbars=1,toolbar=0");
                                if (thePreviewWindow && thePreviewWindow.focus) {
                                        thePreviewWindow.focus();
                                }
                        }
-                       function setReferences()        {       //
-                               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;
-                               } else {
-                                       return false;
-                               }
-                       }
-                       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();
-                                       }
-                               }
-                               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();
-                                       }
-                               } else {
-                                       alert("Error - reference to main window is not set properly!");
-                                       parent.close();
-                               }
-                       }
                ';
 
-                       // Finally, add the accumulated JavaScript to the template object:
-               $this->doc->JScode = $this->doc->wrapScriptTags($JScode);
-
-                       // Debugging:
-               if (FALSE) debug(array(
-                       'pointer' => $this->pointer,
-                       'act' => $this->act,
-                       'mode' => $this->mode,
-                       'curUrlInfo' => $this->curUrlInfo,
-                       'curUrlArray' => $this->curUrlArray,
-                       'P' => $this->P,
-                       'bparams' => $this->bparams,
-                       'RTEtsConfigParams' => $this->RTEtsConfigParams,
-                       'expandPage' => $this->expandPage,
-                       'expandFolder' => $this->expandFolder,
-                       'PM' => $this->PM,
-               ),'Internal variables of Script Class:');
+                       // Hook to overwrite or extend javascript functions
+               if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['extendJScode']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['extendJScode'])) {
+                       $_params = array(
+                               'conf' => &$conf
+                       );
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['extendJScode'] as $objRef) {
+                               $processor = &t3lib_div::getUserObj($objRef);
+                               $JScode .= $processor->extendJScode( $_params, $this);
+                       }
+               }
+
+               return $JScode;
        }
 
        /******************************************************************
@@ -590,67 +570,70 @@ class tx_rtehtmlarea_browse_links extends browse_links {
         * @param       boolean         If set, the "remove link" is not shown in the menu: Used for the "Select link" wizard which is used by the TCEforms
         * @return      string          Modified content variable.
         */
-       function main_rte($wiz=0)       {
-               global $LANG, $BE_USER, $BACK_PATH;
+       function main_rte ($wiz=0) {
 
                        // Starting content:
-               $content=$this->doc->startPage($LANG->getLL('Insert/Modify Link',1));
+               $content=$this->doc->startPage($GLOBALS['LANG']->getLL('Insert/Modify Link',1));
 
-                       // Initializing the action value, possibly removing blinded values etc:
-               $allowedItems = explode(',','page,file,url,mail,spec');
+                       // Default allowed values
+               $this->allowedItems = explode(',','page,file,folder,url,mail,spec');
 
-                       //call hook for extra options
+                       // Calling hook for extra options
                foreach($this->hookObjects as $hookObject) {
-                       $allowedItems = $hookObject->addAllowedItems($allowedItems);
+                       $this->allowedItems = $hookObject->addAllowedItems($this->allowedItems);
                }
-
+                       // Removing items as per configuration
                if (is_array($this->buttonConfig['options.']) && $this->buttonConfig['options.']['removeItems']) {
-                       $allowedItems = array_diff($allowedItems,t3lib_div::trimExplode(',',$this->buttonConfig['options.']['removeItems'],1));
-               } else {
-                       $allowedItems = array_diff($allowedItems,t3lib_div::trimExplode(',',$this->thisConfig['blindLinkOptions'],1));
+                       $this->allowedItems = array_diff($this->allowedItems,t3lib_div::trimExplode(',',$this->buttonConfig['options.']['removeItems'],1));
                }
-               reset($allowedItems);
-               if (!in_array($this->act,$allowedItems)) {
-                       $this->act = current($allowedItems);
+               reset($this->allowedItems);
+               if (!in_array($this->act, $this->allowedItems)) {
+                       $this->act = current($this->allowedItems);
                }
 
                        // Making menu in top:
                $menuDef = array();
-               if (!$wiz)      {
+               if (!$wiz && $this->curUrlArray['href'])        {
                        $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="editor.renderPopup_unLink();return false;"';
+                       $menuDef['removeLink']['addParams'] = 'onclick="plugin.unLink();return false;"';
                }
-               if (in_array('page',$allowedItems)) {
+               if (in_array('page', $this->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&editorNo='.$this->editorNo.'&contentTypo3Language='.$this->contentTypo3Language.'&contentTypo3Charset='.$this->contentTypo3Charset.'\');return false;"';
+                       $menuDef['page']['addParams'] = 'onclick="jumpToUrl(\''.htmlspecialchars('?act=page&mode='.$this->mode.'&bparams='.$this->bparams).'\');return false;"';
                }
-               if (in_array('file',$allowedItems)){
+               if (in_array('file', $this->allowedItems)){
                        $menuDef['file']['isActive'] = $this->act=='file';
-                       $menuDef['file']['label'] = $LANG->getLL('file',1);
+                       $menuDef['file']['label'] = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.xlf:file', 1);
                        $menuDef['file']['url'] = '#';
-                       $menuDef['file']['addParams'] = 'onclick="jumpToUrl(\'?act=file&editorNo='.$this->editorNo.'&contentTypo3Language='.$this->contentTypo3Language.'&contentTypo3Charset='.$this->contentTypo3Charset.'\');return false;"';
+                       $menuDef['file']['addParams'] = 'onclick="jumpToUrl(\''.htmlspecialchars('?act=file&mode='.$this->mode.'&bparams='.$this->bparams).'\');return false;"';
                }
-               if (in_array('url',$allowedItems)) {
+               if (in_array('folder', $this->allowedItems)){
+                       $menuDef['folder']['isActive'] = $this->act == 'folder';
+                       $menuDef['folder']['label'] = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.xlf:folder', 1);
+                       $menuDef['folder']['url'] = '#';
+                       $menuDef['folder']['addParams'] = 'onclick="jumpToUrl(\''.htmlspecialchars('?act=folder&mode='.$this->mode.'&bparams='.$this->bparams).'\');return false;"';
+               }
+               if (in_array('url', $this->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&editorNo='.$this->editorNo.'&contentTypo3Language='.$this->contentTypo3Language.'&contentTypo3Charset='.$this->contentTypo3Charset.'\');return false;"';
+                       $menuDef['url']['addParams'] = 'onclick="jumpToUrl(\''.htmlspecialchars('?act=url&mode='.$this->mode.'&bparams='.$this->bparams).'\');return false;"';
                }
-               if (in_array('mail',$allowedItems)) {
+               if (in_array('mail', $this->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&editorNo='.$this->editorNo.'&contentTypo3Language='.$this->contentTypo3Language.'&contentTypo3Charset='.$this->contentTypo3Charset.'\');return false;"';
+                       $menuDef['mail']['addParams'] = 'onclick="jumpToUrl(\''.htmlspecialchars('?act=mail&mode='.$this->mode.'&bparams='.$this->bparams).'\');return false;"';
                }
-               if (is_array($this->thisConfig['userLinks.']) && in_array('spec',$allowedItems)) {
+               if (is_array($this->thisConfig['userLinks.']) && in_array('spec', $this->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&editorNo='.$this->editorNo.'&contentTypo3Language='.$this->contentTypo3Language.'&contentTypo3Charset='.$this->contentTypo3Charset.'\');return false;"';
+                       $menuDef['spec']['addParams'] = 'onclick="jumpToUrl(\''.htmlspecialchars('?act=spec&mode='.$this->mode.'&bparams='.$this->bparams).'\');return false;"';
                }
 
                        // call hook for extra options
@@ -661,10 +644,10 @@ class tx_rtehtmlarea_browse_links extends browse_links {
                $content .= $this->doc->getTabMenuRaw($menuDef);
 
                        // Adding the menu and header to the top of page:
-               $content.=$this->printCurrentUrl($this->curUrlInfo['info']).'<br />';
+               $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)      {
+               switch ($this->act) {
                        case 'mail':
                                $extUrl='
                        <!--
@@ -673,14 +656,14 @@ class tx_rtehtmlarea_browse_links extends browse_links {
                                        <form action="" name="lurlform" id="lurlform">
                                                <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkMail">
                                                        <tr>
-                                                               <td>'.$LANG->getLL('emailAddress',1).':</td>
+                                                               <td>' . $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="'.$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_setHref(\'mailto:\'+document.lurlform.lemail.value);browse_links_setAdditionalValue(\'data-htmlarea-external\', \'\');return link_current();" /></td>
                                                        </tr>
                                                </table>
                                        </form>';
-                               $content.=$extUrl;
-                               $content.=$this->addAttributesForm();
+                               $content .= $extUrl;
+                               $content .= $this->addAttributesForm();
                        break;
                        case 'url':
                                $extUrl='
@@ -692,70 +675,98 @@ class tx_rtehtmlarea_browse_links extends browse_links {
                                                        <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="'.$LANG->getLL('setLink',1).'" onclick="setValue(document.lurlform.lurl.value); return link_current();" /></td>
+                                                                       '<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink',1).'" onclick="if (/^[A-Za-z0-9_+]{1,8}:/.test(document.lurlform.lurl.value)) { browse_links_setHref(document.lurlform.lurl.value); } else { browse_links_setHref(\'http://\'+document.lurlform.lurl.value); }; browse_links_setAdditionalValue(\'data-htmlarea-external\', \'1\'); return link_current();" /></td>
                                                        </tr>
                                                </table>
                                        </form>';
-                               $content.=$extUrl;
-                               $content.=$this->addAttributesForm();
+                               $content .= $extUrl;
+                               $content .= $this->addAttributesForm();
                        break;
                        case 'file':
-                               $content.=$this->addAttributesForm();
-
-                               $foldertree = t3lib_div::makeInstance('tx_rtehtmlarea_folderTree');
-                               $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;
+                       case 'folder':
+                               $content .= $this->addAttributesForm();
+
+                                       // Create folder tree:
+                               $this->doc->JScode .= $this->doc->wrapScriptTags('
+                                       Tree.ajaxID = "SC_alt_file_navframe::expandCollapse";
+                               ');
+                               $foldertree             = t3lib_div::makeInstance('tx_rtehtmlarea_folderTree');
+                               $foldertree->thisScript = $this->thisScript;
+                               $tree                   = $foldertree->getBrowsableTree();
+
+                               if (!$this->curUrlInfo['value'] || $this->curUrlInfo['act'] != $this->act) {
+                                       $cmpPath = '';
                                } else {
-                                       $cmpPath=PATH_site.$this->curUrlInfo['info'];
-                               }
-
-                               list(,,$specUid) = explode('_',$this->PM);
-                               $files = $this->expandFolder($foldertree->specUIDmap[$specUid]);
-
-                                       // Create upload/create folder forms, if a path is given:
-                               if ($BE_USER->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
-                                       $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
+                                       $cmpPath = $this->curUrlInfo['value'];
+                                       if (!isset($this->expandFolder)) {
+                                               $this->expandFolder = $cmpPath;
                                        }
-                                       if ($path!='/' && @is_dir($path))       {
-                                               $uploadForm=$this->uploadForm($path);
-                                               $createFolder=$this->createFolder($path);
-                                       } else {
-                                               $createFolder='';
-                                               $uploadForm='';
+                               }
+                                       // Get the selected folder
+                               if ($this->expandFolder) {
+                                       $selectedFolder = FALSE;
+                                       $fileOrFolderObject = t3lib_file_Factory::getInstance()->retrieveFileOrFolderObject($this->expandFolder);
+                                       if ($fileOrFolderObject instanceof t3lib_file_Folder) {
+                                               // it's a folder
+                                               $selectedFolder = $fileOrFolderObject;
+                                       } elseif ($fileOrFolderObject instanceof t3lib_file_FileInterface) {
+                                               // it's a file
+                                               // @todo: find the parent folder, right now done a bit ugly, because the file does not
+                                               // support finding the parent folder of a file on purpose
+                                               $folderIdentifier = dirname($fileOrFolderObject->getIdentifier());
+                                               $selectedFolder = $fileOrFolderObject->getStorage()->getFolder($folderIdentifier);
                                        }
-                                       $content.=$uploadForm;
-                                       if ($BE_USER->isAdmin() || $BE_USER->getTSConfigVal('options.createFoldersInEB')) {
-                                               $content.=$createFolder;
+                               }
+                                       // If no folder is selected, get the user's default upload folder
+                               if (!$selectedFolder) {
+                                       $selectedFolder = $GLOBALS['BE_USER']->getDefaultUploadFolder();
+                               }
+                                       // Build the file upload and folder creation forms
+                               $uploadForm = '';
+                               $createFolder = '';
+                               if ($selectedFolder && !$this->isReadOnlyFolder($selectedFolder)) {
+                                       $uploadForm = ($this->act === 'file') ? $this->uploadForm($selectedFolder) : '';
+                                       if ($GLOBALS['BE_USER']->isAdmin() || $GLOBALS['BE_USER']->getTSConfigVal('options.createFoldersInEB')) {
+                                               $createFolder = $this->createFolder($selectedFolder);
                                        }
                                }
+                                       // Insert the upload form on top, if so configured
+                               if ($GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
+                                       $content .= $uploadForm;
+                               }
+                                       // Render the filelist if there is a folder selected
+                               if ($selectedFolder) {
+                                       $files = $this->expandFolder(
+                                               $selectedFolder,
+                                               $this->P['params']['allowedExtensions']
+                                       );
+                               }
+                               $content .= '
 
-                               $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>
-                                                       <td class="c-wCell" valign="top">'.$this->barheader($LANG->getLL('folderTree').':').$tree.'</td>
-                                                       <td class="c-wCell" valign="top">'.$files.'</td>
+                                                       <td class="c-wCell" valign="top">' . $this->barheader($GLOBALS['LANG']->getLL('folderTree') . ':') . $tree . '</td>
+                                                       <td class="c-wCell" valign="top">' . $files . '</td>
                                                </tr>
                                        </table>
                                        ';
+
+                                       // Adding create folder + upload form if applicable
+                               if (!$GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
+                                       $content .= $uploadForm;
+                               }
+                               $content .= '<br />';
+                               $content .= $createFolder;
+                               $content .= '<br />';
                        break;
                        case 'spec':
                                if (is_array($this->thisConfig['userLinks.']))  {
                                        $subcats=array();
                                        $v=$this->thisConfig['userLinks.'];
-                                       reset($v);
-                                       while(list($k2)=each($v))       {
+                                       foreach ($v as $k2 => $dummyValue) {
                                                $k2i = intval($k2);
                                                if (substr($k2,-1)=='.' && is_array($v[$k2i.'.']))      {
 
@@ -764,14 +775,14 @@ class tx_rtehtmlarea_browse_links extends 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();";
@@ -785,7 +796,7 @@ class tx_rtehtmlarea_browse_links extends browse_links {
                                                                // Adding link to menu of user defined links:
                                                        $subcats[$k2i]='
                                                                <tr>
-                                                                       <td class="bgColor4">'.$A[0].'<strong>'.htmlspecialchars($title).($this->curUrlInfo['info']==$v[$k2i.'.']['url']?'<img'.t3lib_iconWorks::skinImg($BACK_PATH,'gfx/blinkarrow_right.gif','width="5" height="9"').' class="c-blinkArrowR" alt="" />':'').'</strong><br />'.$description.$A[1].'</td>
+                                                                       <td class="bgColor4">'.$A[0].'<strong>'.htmlspecialchars($title).($this->curUrlInfo['info']==$v[$k2i.'.']['url']?'<img'.t3lib_iconWorks::skinImg($GLOBALS['BACK_PATH'],'gfx/blinkarrow_right.gif','width="5" height="9"').' class="c-blinkArrowR" alt="" />':'').'</strong><br />'.$description.$A[1].'</td>
                                                                </tr>';
                                                }
                                        }
@@ -800,7 +811,7 @@ class tx_rtehtmlarea_browse_links extends 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>
@@ -812,17 +823,34 @@ class tx_rtehtmlarea_browse_links extends browse_links {
 
                                $pagetree = t3lib_div::makeInstance('tx_rtehtmlarea_pageTree');
                                $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();
                                $cElements = $this->expandPage();
-                               $content.= '
+
+
+                               // 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 .= '
                        <!--
                                Wrapper table for page tree / record list:
                        -->
                                        <table border="0" cellpadding="0" cellspacing="0" id="typo3-linkPages">
                                                <tr>
-                                                       <td class="c-wCell" valign="top">'.$this->barheader($LANG->getLL('pageTree').':').$tree.'</td>
-                                                       <td class="c-wCell" valign="top">'.$cElements.'</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>
                                        ';
@@ -838,23 +866,44 @@ class tx_rtehtmlarea_browse_links extends browse_links {
 
                        // End page, return content:
                $content.= $this->doc->endPage();
+               $content = $this->doc->insertStylesAndJS($content);
                return $content;
        }
 
-       function addAttributesForm() {
+       /**
+        * Creates a form for link attributes
+        *
+        * @return string The HTML code of the form
+        */
+       public function addAttributesForm() {
                $ltargetForm = '';
-                       // Add target and class selector box and title field:
+               $additionalAttributeFields = '';
+                       // Add page id, target, class selector box, title and parameters fields:
+               $lpageId = $this->addPageIdSelector();
+               $queryParameters = $this->addQueryParametersSelector();
                $ltarget = $this->addTargetSelector();
                $lclass = $this->addClassSelector();
                $ltitle = $this->addTitleSelector();
-               if ($ltarget || $lclass || $ltitle) {
-                       $ltargetForm = $this->wrapInForm($ltarget.$lclass.$ltitle);
+               $rel = $this->addRelField();
+
+                       // additional fields for links
+               if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['addAttributeFields']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['addAttributeFields'])) {
+                       $_params = array(
+                               'conf' => &$conf
+                       );
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']['addAttributeFields'] as $objRef) {
+                               $processor = &t3lib_div::getUserObj($objRef);
+                               $additionalAttributeFields .= $processor->getAttributefields( $_params, $this);
+                       }
+               }
+
+               if ($lpageId || $queryParameters || $ltarget || $lclass || $ltitle || $rel) {
+                       $ltargetForm = $this->wrapInForm($lpageId . $queryParameters . $ltarget . $lclass . $ltitle . $rel . $additionalAttributeFields);
                }
                return $ltargetForm;
        }
 
        function wrapInForm($string) {
-               global $LANG;
 
                $form = '
                        <!--
@@ -862,13 +911,13 @@ class tx_rtehtmlarea_browse_links extends browse_links {
                        -->
                                <form action="" name="ltargetform" id="ltargetform">
                                        <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkTarget">'. $string;
-               if ((($this->act == 'page' && $this->curUrlInfo['act']=='page') || ($this->act == 'file' && $this->curUrlInfo['act']=='file') || ($this->act == 'url' && $this->curUrlInfo['act']!='page')) && $this->curUrlArray['href']) {
+               if ($this->act == $this->curUrlInfo['act'] && $this->act != 'mail' && $this->curUrlArray['href']) {
                        $form .='
                                                <tr>
                                                        <td>
                                                        </td>
                                                        <td colspan="3">
-                                                               <input type="submit" value="'.$LANG->getLL('update',1).'" onclick="return link_current();" />
+                                                               <input type="submit" value="' . $GLOBALS['LANG']->getLL('update',1) . '" onclick="' . (($this->act == 'url') ? 'browse_links_setAdditionalValue(\'data-htmlarea-external\', \'1\'); ' : '') . 'return link_current();" />
                                                        </td>
                                                </tr>';
                }
@@ -878,8 +927,39 @@ class tx_rtehtmlarea_browse_links extends browse_links {
                return $form;
        }
 
+       function addPageIdSelector() {
+
+               return ($this->act == 'page' && $this->buttonConfig && is_array($this->buttonConfig['pageIdSelector.']) && $this->buttonConfig['pageIdSelector.']['enabled'])?'
+                                               <tr>
+                                                       <td>' . $GLOBALS['LANG']->getLL('page_id',1) . ':</td>
+                                                       <td colspan="3">
+                                                               <input type="text" size="6" name="luid" />&nbsp;<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', 1) . '" onclick="return link_typo3Page(document.ltargetform.luid.value);" />
+                                                       </td>
+                                               </tr>':'';
+       }
+
+       function addRelField() {
+               return (($this->act == 'page' || $this->act == 'url' || $this->act == 'file') && $this->buttonConfig && is_array($this->buttonConfig['relAttribute.']) && $this->buttonConfig['relAttribute.']['enabled'])?'
+                                               <tr>
+                                                       <td>'.$GLOBALS['LANG']->getLL('linkRelationship',1).':</td>
+                                                       <td colspan="3">
+                                                               <input type="text" name="lrel" value="' . $this->additionalAttributes['rel']. '"  ' . $this->doc->formWidth(30) . ' />
+                                                       </td>
+                                               </tr>':'';
+       }
+
+       function addQueryParametersSelector() {
+
+               return ($this->act == 'page' && $this->buttonConfig && is_array($this->buttonConfig['queryParametersSelector.']) && $this->buttonConfig['queryParametersSelector.']['enabled'])?'
+                                               <tr>
+                                                       <td>' . $GLOBALS['LANG']->getLL('query_parameters', 1) . ':</td>
+                                                       <td colspan="3">
+                                                               <input type="text" name="query_parameters" value="' . ($this->curUrlInfo['query']?$this->curUrlInfo['query']:'') . '" ' . $this->doc->formWidth(30) . ' />
+                                                       </td>
+                                               </tr>':'';
+       }
+
        function addTargetSelector() {
-               global $LANG;
 
                $targetSelectorConfig = array();
                $popupSelectorConfig = array();
@@ -892,42 +972,38 @@ class tx_rtehtmlarea_browse_links extends browse_links {
 
                $ltarget = '';
                if ($this->act != 'mail')       {
-                       if (!($targetSelectorConfig['disabled'] && $popupSelectorConfig['disabled'])) {
-                               $ltarget .= '
-                                               <tr>
-                                                       <td>'.$LANG->getLL('target',1).':</td>
-                                                       <td><input type="text" name="ltarget" onchange="setTarget(this.value);" value="'.htmlspecialchars($this->setTarget).'"'.$this->doc->formWidth(10).' /></td>';
-                               $ltarget .= '
-                                                       <td colspan="2">';
-                               if (!$targetSelectorConfig['disabled']) {
-                                       $ltarget .= '
-                                                               <select name="ltarget_type" onchange="setTarget(this.options[this.selectedIndex].value);document.ltargetform.ltarget.value=this.options[this.selectedIndex].value;this.selectedIndex=0;">
-                                                                       <option></option>
-                                                                       <option value="_top">'.$LANG->getLL('top',1).'</option>
-                                                                       <option value="_blank">'.$LANG->getLL('newWindow',1).'</option>
-                                                               </select>';
-                               }
+                       $ltarget .= '
+                                       <tr id="ltargetrow"'. (($targetSelectorConfig['disabled'] && $popupSelectorConfig['disabled']) ? ' style="display: none;"' : '') . '>
+                                               <td>' . $GLOBALS['LANG']->getLL('target', 1) . ':</td>
+                                               <td><input type="text" name="ltarget" onchange="browse_links_setTarget(this.value);" value="'.htmlspecialchars($this->setTarget?$this->setTarget:(($this->setClass || !$this->classesAnchorDefault[$this->act])?'':$this->classesAnchorDefaultTarget[$this->act])).'"'.$this->doc->formWidth(10).' /></td>';
+                       $ltarget .= '
+                                               <td colspan="2">';
+                       if (!$targetSelectorConfig['disabled']) {
                                $ltarget .= '
-                                                       </td>';
+                                                       <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>';
                        }
-
                        $ltarget .= '
-                                               </tr>';
+                                               </td>
+                                       </tr>';
                        if (!$popupSelectorConfig['disabled']) {
 
                                $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);
+                                       browse_links_setTarget(document.ltargetform.ltarget.value);
                                        document.ltargetform.popup_width.selectedIndex=0;
                                        document.ltargetform.popup_height.selectedIndex=0;
                                }';
 
                                $ltarget.='
                                                <tr>
-                                                       <td>'.$LANG->getLL('target_popUpWindow',1).':</td>
+                                                       <td>' . $GLOBALS['LANG']->getLL('target_popUpWindow', 1) . ':</td>
                                                        <td colspan="3">
                                                                <select name="popup_width" onchange="'.$selectJS.'">
-                                                                       <option value="0">'.$LANG->getLL('target_popUpWindow_width',1).'</option>
+                                                                       <option value="0">' . $GLOBALS['LANG']->getLL('target_popUpWindow_width', 1) . '</option>
                                                                        <option value="300">300</option>
                                                                        <option value="400">400</option>
                                                                        <option value="500">500</option>
@@ -937,7 +1013,7 @@ class tx_rtehtmlarea_browse_links extends browse_links {
                                                                </select>
                                                                x
                                                                <select name="popup_height" onchange="'.$selectJS.'">
-                                                                       <option value="0">'.$LANG->getLL('target_popUpWindow_height',1).'</option>
+                                                                       <option value="0">' . $GLOBALS['LANG']->getLL('target_popUpWindow_height', 1) . '</option>
                                                                        <option value="200">200</option>
                                                                        <option value="300">300</option>
                                                                        <option value="400">400</option>
@@ -951,29 +1027,19 @@ class tx_rtehtmlarea_browse_links extends browse_links {
                return $ltarget;
        }
 
-       function addClassSelector() {
-               global $LANG;
-
+       /**
+        * Return html code for the class selector
+        *
+        * @return      string          the html code to be added to the form
+        */
+       public function addClassSelector() {
                $selectClass = '';
                if ($this->classesAnchorJSOptions[$this->act]) {
-                       $selectClassJS = '
-                                       document.ltargetform.anchor_class.value = document.ltargetform.anchor_class.options[document.ltargetform.anchor_class.selectedIndex].value;
-                                       if(document.ltargetform.anchor_class.value && editor.classesAnchorSetup) {
-                                               for (var i = editor.classesAnchorSetup.length; --i >= 0;) {
-                                                       var anchorClass = editor.classesAnchorSetup[i];
-                                                       if (anchorClass[\'name\'] == document.ltargetform.anchor_class.value) {
-                                                               if(anchorClass[\'titleText\'] && document.ltargetform.anchor_title) document.ltargetform.anchor_title.value = anchorClass[\'titleText\'];
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                                       setClass(document.ltargetform.anchor_class.value);
-                               ';
                        $selectClass ='
                                                <tr>
-                                                       <td>'.$LANG->getLL('anchor_class',1).':</td>
+                                                       <td>'.$GLOBALS['LANG']->getLL('anchor_class',1).':</td>
                                                        <td colspan="3">
-                                                               <select name="anchor_class" onchange="'.$selectClassJS.'">
+                                                               <select name="anchor_class" onchange="'.$this->getClassOnChangeJS().'">
                                                                        ' . $this->classesAnchorJSOptions[$this->act] . '
                                                                </select>
                                                        </td>
@@ -982,119 +1048,95 @@ class tx_rtehtmlarea_browse_links extends browse_links {
                return $selectClass;
        }
 
-       function addTitleSelector() {
-               global $LANG;
+       /**
+        * Return JS code for the class selector onChange event
+        *
+        * @return      string  class selector onChange JS code
+        */
+        public function getClassOnChangeJS() {
+                return '
+                                       if (document.ltargetform.anchor_class) {
+                                               document.ltargetform.anchor_class.value = document.ltargetform.anchor_class.options[document.ltargetform.anchor_class.selectedIndex].value;
+                                               if (document.ltargetform.anchor_class.value && HTMLArea.classesAnchorSetup) {
+                                                       for (var i = HTMLArea.classesAnchorSetup.length; --i >= 0;) {
+                                                               var anchorClass = HTMLArea.classesAnchorSetup[i];
+                                                               if (anchorClass[\'name\'] == document.ltargetform.anchor_class.value) {
+                                                                       if (anchorClass[\'titleText\'] && document.ltargetform.anchor_title) {
+                                                                               document.ltargetform.anchor_title.value = anchorClass[\'titleText\'];
+                                                                               document.getElementById(\'rtehtmlarea-browse-links-title-readonly\').innerHTML = anchorClass[\'titleText\'];
+                                                                               browse_links_setTitle(anchorClass[\'titleText\']);
+                                                                       }
+                                                                       if (anchorClass[\'target\']) {
+                                                                               if (document.ltargetform.ltarget) {
+                                                                                       document.ltargetform.ltarget.value = anchorClass[\'target\'];
+                                                                               }
+                                                                               browse_links_setTarget(anchorClass[\'target\']);
+                                                                       } else if (document.ltargetform.ltarget && document.getElementById(\'ltargetrow\').style.display == \'none\') {
+                                                                                       // Reset target to default if field is not displayed and class has no configured target
+                                                                               document.ltargetform.ltarget.value = \''. ($this->defaultLinkTarget ? $this->defaultLinkTarget : '') .'\';
+                                                                               browse_links_setTarget(document.ltargetform.ltarget.value);
+                                                                       }
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                               browse_links_setClass(document.ltargetform.anchor_class.value);
+                                       }
+                                                               ';
+        }
 
+       function addTitleSelector() {
+               $title = ($this->setTitle ? $this->setTitle : (($this->setClass || !$this->classesAnchorDefault[$this->act]) ? '' : $this->classesAnchorDefaultTitle[$this->act]));
+               $readOnly = $this->buttonConfig['properties.']['title.']['readOnly'] || $this->buttonConfig[$this->act.'.']['properties.']['title.']['readOnly'];
+               if ($readOnly) {
+                       $title = $this->setClass ? $this->classesAnchorClassTitle[$this->setClass] : $this->classesAnchorDefaultTitle[$this->act];
+               }
                return '
                                                <tr>
-                                                       <td>'.$LANG->getLL('anchor_title',1).':</td>
+                                                       <td><label for="rtehtmlarea-browse-links-anchor_title" id="rtehtmlarea-browse-links-title-label">' . $GLOBALS['LANG']->getLL('anchor_title',1) . ':</label></td>
                                                        <td colspan="3">
-                                                               <input type="text" name="anchor_title" value="' . ($this->setTitle?$this->setTitle:($this->thisConfig['classesAnchor']?$this->classesAnchorDefaultTitle[$this->act]:'')) . '" ' . $this->doc->formWidth(30) . ' />
+                                                               <span id="rtehtmlarea-browse-links-title-input" style="display: ' . ($readOnly ? 'none' : 'inline') . ';">
+                                                                       <input type="text" id="rtehtmlarea-browse-links-anchor_title" name="anchor_title" value="' . $title . '" ' . $this->doc->formWidth(30) . ' />
+                                                               </span>
+                                                               <span id="rtehtmlarea-browse-links-title-readonly" style="display: ' . ($readOnly ? 'inline' : 'none') . ';">' . $title . '</span>
                                                        </td>
                                                </tr>';
        }
 
        /**
-        * For TBE: Makes an upload form for uploading files to the filemount the user is browsing.
-        * The files are uploaded to the tce_file.php script in the core which will handle the upload.
+        * Localize a string using the language of the content element rather than the language of the BE interface
         *
-        * @param       string          Absolute filepath on server to which to upload.
-        * @return      string          HTML for an upload form.
+        * @param       string          string: the label to be localized
+        * @return      string          Localized string.
         */
-       function uploadForm($path)      {
-               global $BACK_PATH;
-               $count=3;
-
-                       // 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.='
+       public function getLLContent($string) {
+               $BE_lang = $GLOBALS['LANG']->lang;
 
-                       <!--
-                               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">
-                                       <tr>
-                                               <td><strong>'.$GLOBALS['LANG']->getLL('path',1).':</strong> '.htmlspecialchars($header).'</td>
-                                       </tr>
-                                       <tr>
-                                               <td>';
-
-                       // Traverse the number of upload fields (default is 3):
-               for ($a=1;$a<=$count;$a++)      {
-                       $code.='<input type="file" name="upload_'.$a.'"'.$this->doc->formWidth(35).' size="50" />
-                               <input type="hidden" name="file[upload]['.$a.'][target]" value="'.htmlspecialchars($path).'" />
-                               <input type="hidden" name="file[upload]['.$a.'][data]" value="'.$a.'" /><br />';
-               }
-
-                       // Make footer of upload form, including the submit button:
-               $redirectValue = $this->thisScript.'?act='.$this->act.'&editorNo='.$this->editorNo.'&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.='
-                       <div id="c-override">
-                               <input type="checkbox" name="overwriteExistingFiles" value="1" /> '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xml:overwriteExistingFiles',1).'
-                       </div>
-               ';
-
-
-               $code.='</td>
-                                       </tr>
-                               </table>
-                       </form>';
+               $GLOBALS['LANG']->lang = $this->contentTypo3Language;
+               $LLString = $GLOBALS['LANG']->sL($string);
 
-               return $code;
+               $GLOBALS['LANG']->lang = $BE_lang;
+               return $LLString;
        }
 
        /**
-        * For TBE: Makes a form for creating new folders in the filemount the user is browsing.
-        * The folder creation request is sent to the tce_file.php script in the core which will handle the creation.
+        * Localize a label obtained from Page TSConfig
         *
-        * @param       string          Absolute filepath on server in which to create the new folder.
-        * @return      string          HTML for the create folder form.
+        * @param       string          string: the label to be localized
+        * @return      string          Localized string.
         */
-       function createFolder($path)    {
-               global $BACK_PATH;
-                       // 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.='
-
-                       <!--
-                               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">
-                                       <tr>
-                                               <td><strong>'.$GLOBALS['LANG']->getLL('path',1).':</strong> '.htmlspecialchars($header).'</td>
-                                       </tr>
-                                       <tr>
-                                               <td>';
-
-                       // Create the new-folder name field:
-               $a=1;
-               $code.='<input'.$this->doc->formWidth(20).' type="text" name="file[newfolder]['.$a.'][data]" />'.
-                               '<input type="hidden" name="file[newfolder]['.$a.'][target]" value="'.htmlspecialchars($path).'" />';
-
-                       // Make footer of upload form, including the submit button:
-               $redirectValue = $this->thisScript.'?act='.$this->act.'&editorNo='.$this->editorNo.'&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_newfolder.php.submit',1).'" />';
-
-               $code.='</td>
-                                       </tr>
-                               </table>
-                       </form>';
-
-               return $code;
+       public function getPageConfigLabel($string,$JScharCode=1) {
+               if (strcmp(substr($string,0,4),'LLL:')) {
+                       $label = $string;
+               } else {
+                       $label = $GLOBALS['LANG']->sL(trim($string));
+               }
+               $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
+               $label = $JScharCode ? $GLOBALS['LANG']->JScharCode($label): $label;
+               return $label;
        }
-
 }
-
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php'])     {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/mod3/class.tx_rtehtmlarea_browse_links.php']);
 }
-
-?>
\ No newline at end of file
+?>