[!!!][TASK] RTE reloaded 42/40842/30
authorChristian Kuhn <lolli@schwarzbu.ch>
Wed, 1 Jul 2015 12:31:21 +0000 (14:31 +0200)
committerBenjamin Mack <benni@typo3.org>
Tue, 7 Jul 2015 08:01:22 +0000 (10:01 +0200)
Main refactoring of RTE on PHP side. Classes AbstractRte,
RteHtmlAreaBase and the instantiator API RTEgetObj() are
dropped and inlined to the FormEngine class construct.
Lots of code is simplified or moved around.

Change-Id: Ibd4ff3e7fa8fe695a96b03355c905640d2efa351
Resolves: #67917
Releases: master
Reviewed-on: http://review.typo3.org/40842
Reviewed-by: Frank Nägler <frank.naegler@typo3.org>
Tested-by: Frank Nägler <frank.naegler@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Benjamin Mack <benni@typo3.org>
Tested-by: Benjamin Mack <benni@typo3.org>
58 files changed:
typo3/sysext/backend/Classes/Controller/Wizard/RteController.php
typo3/sysext/backend/Classes/Form/Container/SingleFieldContainer.php
typo3/sysext/backend/Classes/Form/FormEngine.php
typo3/sysext/backend/Classes/Rte/AbstractRte.php [deleted file]
typo3/sysext/backend/Classes/Utility/BackendUtility.php
typo3/sysext/backend/Classes/View/PageLayoutView.php
typo3/sysext/backend/Resources/Private/Templates/helper_javascript_css.html
typo3/sysext/compatibility6/Migrations/Code/ClassAliasMap.php
typo3/sysext/compatibility6/Migrations/Code/LegacyClassesForIde.php
typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php
typo3/sysext/core/Classes/DataHandling/DataHandler.php
typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-67811-RteApi.rst
typo3/sysext/rtehtmlarea/Classes/Extension/Abbreviation.php
typo3/sysext/rtehtmlarea/Classes/Extension/AboutEditor.php
typo3/sysext/rtehtmlarea/Classes/Extension/BlockElements.php
typo3/sysext/rtehtmlarea/Classes/Extension/CharacterMap.php
typo3/sysext/rtehtmlarea/Classes/Extension/ContextMenu.php
typo3/sysext/rtehtmlarea/Classes/Extension/CopyPaste.php
typo3/sysext/rtehtmlarea/Classes/Extension/DefaultClean.php
typo3/sysext/rtehtmlarea/Classes/Extension/DefaultImage.php
typo3/sysext/rtehtmlarea/Classes/Extension/DefaultInline.php
typo3/sysext/rtehtmlarea/Classes/Extension/DefaultLink.php
typo3/sysext/rtehtmlarea/Classes/Extension/DefinitionList.php
typo3/sysext/rtehtmlarea/Classes/Extension/EditElement.php
typo3/sysext/rtehtmlarea/Classes/Extension/EditorMode.php
typo3/sysext/rtehtmlarea/Classes/Extension/FindReplace.php
typo3/sysext/rtehtmlarea/Classes/Extension/InlineElements.php
typo3/sysext/rtehtmlarea/Classes/Extension/InsertSmiley.php
typo3/sysext/rtehtmlarea/Classes/Extension/Language.php
typo3/sysext/rtehtmlarea/Classes/Extension/MicroDataSchema.php
typo3/sysext/rtehtmlarea/Classes/Extension/Plaintext.php
typo3/sysext/rtehtmlarea/Classes/Extension/QuickTag.php
typo3/sysext/rtehtmlarea/Classes/Extension/RemoveFormat.php
typo3/sysext/rtehtmlarea/Classes/Extension/SelectFont.php
typo3/sysext/rtehtmlarea/Classes/Extension/Spellchecker.php
typo3/sysext/rtehtmlarea/Classes/Extension/TableOperations.php
typo3/sysext/rtehtmlarea/Classes/Extension/TextIndicator.php
typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Color.php
typo3/sysext/rtehtmlarea/Classes/Extension/Typo3HtmlParser.php
typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Image.php
typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Link.php
typo3/sysext/rtehtmlarea/Classes/Extension/UndoRedo.php
typo3/sysext/rtehtmlarea/Classes/Extension/UserElements.php
typo3/sysext/rtehtmlarea/Classes/Form/Element/RichTextElement.php
typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaApi.php
typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaBase.php [deleted file]
typo3/sysext/rtehtmlarea/Resources/Private/Language/locallang_tooltips.xlf
typo3/sysext/rtehtmlarea/Resources/Public/Css/Skin/Plugins/default-inline.css [deleted file]
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Ajax/Ajax.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Configuration/Config.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Framework.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/HTMLArea.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/DefaultLink.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/SpellChecker.js
typo3/sysext/rtehtmlarea/ext_localconf.php
typo3/sysext/t3skin/rtehtmlarea/htmlarea.css

index 949b32c..d263126 100644 (file)
@@ -143,12 +143,6 @@ class RteController extends AbstractWizardController {
                        $formEngine = GeneralUtility::makeInstance(FormEngine::class);
                        // SPECIAL: Disables all wizards - we are NOT going to need them.
                        $formEngine->disableWizards = 1;
-                       // Initialize style for RTE object:
-                       // Getting reference to the RTE object used to render the field!
-                       $RTEObject = BackendUtility::RTEgetObj();
-                       if ($RTEObject->ID === 'rte') {
-                               $RTEObject->RTEdivStyle = 'position:relative; left:0px; top:0px; height:100%; width:100%; border:solid 0px;';
-                       }
                        // Fetching content of record:
                        /** @var DataPreprocessor $dataPreprocessor */
                        $dataPreprocessor = GeneralUtility::makeInstance(DataPreprocessor::class);
index ea6f338..0ae814c 100644 (file)
@@ -75,6 +75,7 @@ class SingleFieldContainer extends AbstractContainer {
                if (
                        $parameterArray['fieldConf']['exclude'] && !$backendUser->check('non_exclude_fields', $table . ':' . $fieldName)
                        || $parameterArray['fieldConf']['config']['type'] === 'passthrough'
+                       // @todo: Drop option "showIfRTE" ?
                        || !$backendUser->isRTE() && $parameterArray['fieldConf']['config']['showIfRTE']
                        || $GLOBALS['TCA'][$table]['ctrl']['languageField'] && !$parameterArray['fieldConf']['l10n_display'] && $parameterArray['fieldConf']['l10n_mode'] === 'exclude' && ($row[$GLOBALS['TCA'][$table]['ctrl']['languageField']] > 0)
                        || $GLOBALS['TCA'][$table]['ctrl']['languageField'] && $this->globalOptions['localizationMode'] && $this->globalOptions['localizationMode'] !== $parameterArray['fieldConf']['l10n_cat']
index ccd706f..d5952a8 100644 (file)
@@ -432,7 +432,6 @@ class FormEngine {
                        'inlineStructure' => $this->inlineStackProcessor->getStructure(),
                        'overruleTypesArray' => array(),
                        'hiddenFieldListArray' => $this->hiddenFieldListArr,
-                       'isAjaxContext' => FALSE,
                        'flexFormFieldIdentifierPrefix' => 'ID',
                        'nodeFactory' => $this->nodeFactory,
                );
@@ -535,7 +534,6 @@ class FormEngine {
                $options['inlineRelatedRecordToRender'] = $record;
                $options['inlineRelatedRecordConfig'] = $config;
                $options['inlineStructure'] = $this->inlineStackProcessor->getStructure();
-               $options['isAjaxContext'] = TRUE;
 
                $options['renderType'] = 'inlineRecordContainer';
                $childArray = $this->nodeFactory->create($options)->render();
@@ -657,7 +655,6 @@ class FormEngine {
                $options['inlineRelatedRecordToRender'] = $record;
                $options['inlineRelatedRecordConfig'] = $config;
                $options['inlineStructure'] = $this->inlineStackProcessor->getStructure();
-               $options['isAjaxContext'] = TRUE;
 
                $options['renderType'] = 'inlineRecordContainer';
                $childArray = $this->nodeFactory->create($options)->render();
@@ -756,7 +753,6 @@ class FormEngine {
                                $options['inlineRelatedRecordToRender'] = $row;
                                $options['inlineRelatedRecordConfig'] = $parent['config'];
                                $options['inlineStructure'] = $this->inlineStackProcessor->getStructure();
-                               $options['isAjaxContext'] = TRUE;
 
                                $options['renderType'] = 'inlineRecordContainer';
                                $childArray = $this->nodeFactory->create($options)->render();
@@ -1026,7 +1022,7 @@ class FormEngine {
         */
        protected function getInlineHeadTags() {
                $headTags = array();
-               $headDataRaw = $this->JStop() . $this->getJavaScriptAndStyleSheetsOfPageRenderer();
+               $headDataRaw = $this->JStop() . $this->getJavaScriptOfPageRenderer();
                if ($headDataRaw) {
                        // Create instance of the HTML parser:
                        $parseObj = GeneralUtility::makeInstance(HtmlParser::class);
@@ -1035,7 +1031,10 @@ class FormEngine {
                        // Removes leading spaces of a multi-line string:
                        $headDataRaw = trim(preg_replace('/(^|\\r|\\n)( |\\t)+/', '$1', $headDataRaw));
                        // Get script and link tags:
-                       $tags = array_merge($parseObj->getAllParts($parseObj->splitTags('link', $headDataRaw)), $parseObj->getAllParts($parseObj->splitIntoBlock('script', $headDataRaw)));
+                       $tags = array_merge(
+                               $parseObj->getAllParts($parseObj->splitTags('link', $headDataRaw)),
+                               $parseObj->getAllParts($parseObj->splitIntoBlock('script', $headDataRaw))
+                       );
                        foreach ($tags as $tagData) {
                                $tagAttributes = $parseObj->get_tag_attributes($parseObj->getFirstTag($tagData), TRUE);
                                $headTags[] = array(
@@ -1057,13 +1056,12 @@ class FormEngine {
         * @return string
         * @todo: aaaargs ...
         */
-       protected function getJavaScriptAndStyleSheetsOfPageRenderer() {
+       protected function getJavaScriptOfPageRenderer() {
                /** @var $pageRenderer \TYPO3\CMS\Core\Page\PageRenderer */
                $pageRenderer = clone $GLOBALS['SOBE']->doc->getPageRenderer();
                $pageRenderer->setCharSet($this->getLanguageService()->charSet);
                $pageRenderer->setTemplateFile('EXT:backend/Resources/Private/Templates/helper_javascript_css.html');
-               $javaScriptAndStyleSheets = $pageRenderer->render();
-               return $javaScriptAndStyleSheets;
+               return $pageRenderer->render();
        }
 
        /**
@@ -1202,12 +1200,8 @@ class FormEngine {
         */
        public function JStop() {
                $out = '';
-               // Additional top HTML:
                if (!empty($this->additionalCode_pre)) {
-                       $out .= implode('
-
-                               <!-- NEXT: -->
-                       ', $this->additionalCode_pre);
+                       $out = implode(LF, $this->additionalCode_pre) . LF;
                }
                return $out;
        }
@@ -1244,6 +1238,8 @@ class FormEngine {
                        $pageRenderer->loadPrototype();
                        $pageRenderer->loadJquery();
                        $pageRenderer->loadExtJS();
+                       // rtehtmlarea needs extjs quick tips (?)
+                       $pageRenderer->enableExtJSQuickTips();
                        $beUserAuth = $this->getBackendUserAuthentication();
                        // Make textareas resizable and flexible ("autogrow" in height)
                        $textareaSettings = array(
diff --git a/typo3/sysext/backend/Classes/Rte/AbstractRte.php b/typo3/sysext/backend/Classes/Rte/AbstractRte.php
deleted file mode 100644 (file)
index bf34fa4..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-<?php
-namespace TYPO3\CMS\Backend\Rte;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * RTE base class: Delivers browser-detection, TCEforms binding and transformation routines
- * for the "rte" extension, registering it with the RTE API
- * See "rte" extension for usage.
- *
- * @author Kasper Skårhøj <kasperYYYY@typo3.com>
- */
-class AbstractRte {
-
-       /**
-        * Error messages regarding non-availability is collected here.
-        *
-        * @var array
-        */
-       public $errorLog = array();
-
-       /**
-        * Set this to the extension key of the RTE so it can identify itself.
-        *
-        * @var string
-        */
-       public $ID = '';
-
-       /***********************************
-        *
-        * Main API functions;
-        * When you create alternative RTEs, simply override these functions in your parent class.
-        * See the "rte" or "rtehtmlarea" extension as an example!
-        *
-        **********************************/
-       /**
-        * Returns TRUE if the RTE is available. Here you check if the browser requirements are met.
-        * If there are reasons why the RTE cannot be displayed you simply enter them as text in ->errorLog
-        *
-        * @return bool TRUE if this RTE object offers an RTE in the current browser environment
-        */
-       public function isAvailable() {
-               return TRUE;
-       }
-
-       /**
-        * Draws the RTE as a form field or whatever is needed (inserts JavaApplet, creates iframe, renders ....)
-        * Default is to output the transformed content in a plain textarea field. This mode is great for debugging transformations!
-        *
-        * @param object $pObj parent object
-        * @param string $table The table name
-        * @param string $field The field name
-        * @param array $row The current row from which field is being rendered
-        * @param array $PA Array of standard content for rendering form fields from TCEforms. See TCEforms for details on this. Includes for instance the value and the form field name, java script actions and more.
-        * @param array $specConf "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
-        * @param array $thisConfig Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
-        * @param string $RTEtypeVal Record "type" field value.
-        * @param string $RTErelPath Relative path for images/links in RTE; this is used when the RTE edits content from static files where the path of such media has to be transformed forth and back!
-        * @param int $thePidValue PID value of record (true parent page id)
-        * @return string HTML code for RTE!
-        */
-       public function drawRTE($pObj, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue) {
-               // Transform value:
-               $value = $this->transformContent('rte', $PA['itemFormElValue'], $table, $field, $row, $specConf, $thisConfig, $RTErelPath, $thePidValue);
-               // Create item:
-               $item = '
-                       ' . $this->triggerField($PA['itemFormElName']) . '
-                       <textarea name="' . htmlspecialchars($PA['itemFormElName']) . '"' . $pObj->formWidth('48') . ' rows="20" wrap="off" style="background-color: #99eebb;">' . GeneralUtility::formatForTextarea($value) . '</textarea>';
-               // Return form item:
-               return $item;
-       }
-
-       /**
-        * Performs transformation of content to/from RTE. The keyword $dirRTE determines the direction.
-        * This function is called in two situations:
-        * a) Right before content from database is sent to the RTE (see ->drawRTE()) it might need transformation
-        * b) When content is sent from the RTE and into the database it might need transformation back again (going on in TCEmain class; You can't affect that.)
-        *
-        * @param string $dirRTE Keyword: "rte" means direction from db to rte, "db" means direction from Rte to DB
-        * @param string $value Value to transform.
-        * @param string $table The table name
-        * @param string $field The field name
-        * @param array $row The current row from which field is being rendered
-        * @param array $specConf "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
-        * @param array $thisConfig Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
-        * @param string $RTErelPath Relative path for images/links in RTE; this is used when the RTE edits content from static files where the path of such media has to be transformed forth and back!
-        * @param int $pid PID value of record (true parent page id)
-        * @return string Transformed content
-        */
-       public function transformContent($dirRTE, $value, $table, $field, $row, $specConf, $thisConfig, $RTErelPath, $pid) {
-               if ($specConf['rte_transform']) {
-                       $p = \TYPO3\CMS\Backend\Utility\BackendUtility::getSpecConfParametersFromArray($specConf['rte_transform']['parameters']);
-                       // There must be a mode set for transformation
-                       if ($p['mode']) {
-                               // Initialize transformation:
-                               $parseHTML = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Html\RteHtmlParser::class);
-                               $parseHTML->init($table . ':' . $field, $pid);
-                               $parseHTML->setRelPath($RTErelPath);
-                               // Perform transformation:
-                               $value = $parseHTML->RTE_transform($value, $specConf, $dirRTE, $thisConfig);
-                       }
-               }
-               return $value;
-       }
-
-       /***********************************
-        *
-        * Helper functions
-        *
-        **********************************/
-       /**
-        * Trigger field - this field tells the TCEmain that processing should be done on this value!
-        *
-        * @param string $fieldName Field name of the RTE field.
-        * @return string <input> field of type "hidden" with a flag telling the TCEmain that this fields content should be transformed back to database state.
-        */
-       public function triggerField($fieldName) {
-               $triggerFieldName = preg_replace('/\\[([^]]+)\\]$/', '[_TRANSFORM_\\1]', $fieldName);
-               return '<input type="hidden" name="' . htmlspecialchars($triggerFieldName) . '" value="RTE" />';
-       }
-
-}
index 0598087..48ca1af 100644 (file)
@@ -810,7 +810,7 @@ class BackendUtility {
         * Note: This method is very similar to \TYPO3\CMS\Backend\Form\FormEngine::getRTypeNum(),
         * however, it has two differences:
         * 1) The method in TCEForms also takes care of localization (which is difficult to do here as the whole infrastructure for language overlays is only in TCEforms).
-        * 2) The $rec array looks different in TCEForms, as in there it's not the raw record but the \TYPO3\CMS\Backend\Form\DataPreprocessor version of it, which changes e.g. how "select"
+        * 2) The $row array looks different in TCEForms, as in there it's not the raw record but the \TYPO3\CMS\Backend\Form\DataPreprocessor version of it, which changes e.g. how "select"
         * and "group" field values are stored, which makes different processing of the "foreign pointer field" type field variant necessary.
         *
         * @param string $table Table name present in TCA
@@ -867,7 +867,7 @@ class BackendUtility {
 
        /**
         * Parses "defaultExtras" of $GLOBALS['TCA'] columns config section to an array.
-        * Elements are splitted by ":" and within those parts, parameters are splitted by "|".
+        * Elements are split by ":" and within those parts, parameters are split by "|".
         *
         * See unit tests for details.
         *
@@ -3568,8 +3568,7 @@ class BackendUtility {
         * @internal
         */
        static public function getPidForModTSconfig($table, $uid, $pid) {
-               $retVal = $table == 'pages' && MathUtility::canBeInterpretedAsInteger($uid) ? $uid : $pid;
-               return $retVal;
+               return $table === 'pages' && MathUtility::canBeInterpretedAsInteger($uid) ? $uid : $pid;
        }
 
        /**
@@ -3605,7 +3604,8 @@ class BackendUtility {
         * @param string $table Table name
         * @param int $uid Record uid
         * @param int $pid Record pid
-        * @return array Array of two ints; first is the REAL PID of a record and if its a new record negative values are resolved to the true PID, second value is the PID value for TSconfig (uid if table is pages, otherwise the pid)
+        * @return array Array of two ints; first is the REAL PID of a record and if its a new record negative values are resolved to the true PID,
+        * second value is the PID value for TSconfig (uid if table is pages, otherwise the pid)
         * @internal
         * @see \TYPO3\CMS\Core\DataHandling\DataHandler::setHistory(), \TYPO3\CMS\Core\DataHandling\DataHandler::process_datamap()
         */
@@ -3660,7 +3660,8 @@ class BackendUtility {
        }
 
        /**
-        * Returns overlayered RTE setup from an array with TSconfig. Used in TCEforms and TCEmain
+        * Returns processed RTE setup from an array with TSconfig.
+        * Merges table and type specific RTE configuration into 'default.'
         *
         * @param array $RTEprop The properties of Page TSconfig in the key "RTE.
         * @param string $table Table name
@@ -3687,8 +3688,10 @@ class BackendUtility {
         * Usage: $RTEobj = BackendUtility::RTEgetObj();
         *
         * @return mixed If available, returns RTE object, otherwise an array of messages from possible RTEs
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8
         */
        static public function RTEgetObj() {
+               GeneralUtility::logDeprecatedFunction();
                // If no RTE object has been set previously, try to create it:
                if (!isset($GLOBALS['T3_VAR']['RTEobj'])) {
                        // Set the object string to blank by default:
index 42d746d..5b5b84a 100644 (file)
@@ -2045,7 +2045,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                        return FALSE;
                }
                $p = BackendUtility::getSpecConfParametersFromArray($specConf['rte_transform']['parameters']);
-               if (isset($specConf['richtext']) && (!$p['flag'] || !$row[$p['flag']])) {
+               if (isset($specConf['richtext'])) {
                        BackendUtility::fixVersioningPid($table, $row);
                        list($tscPID, $thePidValue) = BackendUtility::getTSCpid($table, $row['uid'], $row['pid']);
                        // If the pid-value is not negative (that is, a pid could NOT be fetched)
index 043dd0e..5024800 100644 (file)
@@ -72,7 +72,6 @@ return array(
        't3lib_recordList' => \TYPO3\CMS\Backend\RecordList\AbstractRecordList::class,
        'TBE_browser_recordList' => \TYPO3\CMS\Backend\RecordList\ElementBrowserRecordList::class,
        't3lib_localRecordListGetTableHook' => \TYPO3\CMS\Backend\RecordList\RecordListGetTableHookInterface::class,
-       't3lib_rteapi' => \TYPO3\CMS\Backend\Rte\AbstractRte::class,
        'extDirect_dataProvider_BackendLiveSearch' => \TYPO3\CMS\Backend\Search\LiveSearch\ExtDirect\LiveSearchDataProvider::class,
        't3lib_search_liveSearch' => \TYPO3\CMS\Backend\Search\LiveSearch\LiveSearch::class,
        't3lib_search_liveSearch_queryParser' => \TYPO3\CMS\Backend\Search\LiveSearch\QueryParser::class,
@@ -1164,7 +1163,6 @@ return array(
        'tx_rtehtmlarea_image_folderTree' => \TYPO3\CMS\Rtehtmlarea\FolderTree::class,
        'tx_rtehtmlarea_pageTree' => \TYPO3\CMS\Rtehtmlarea\PageTree::class,
        'tx_rtehtmlarea_api' => \TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi::class,
-       'tx_rtehtmlarea_base' => \TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase::class,
        'tx_rtehtmlarea_select_image' => \TYPO3\CMS\Rtehtmlarea\SelectImage::class,
        'tx_rtehtmlarea_user' => \TYPO3\CMS\Rtehtmlarea\Controller\UserElementsController::class,
        'TYPO3\\CMS\\Rtehtmlarea\\ImageFolderTree' => \TYPO3\CMS\Rtehtmlarea\FolderTree::class,
index efa7447..b912359 100644 (file)
@@ -369,11 +369,6 @@ interface t3lib_localRecordListGetTableHook extends \TYPO3\CMS\Backend\RecordLis
 /**
  * @deprecated since 6.0, removed since 7.0
  */
-abstract class t3lib_rteapi extends \TYPO3\CMS\Backend\Rte\AbstractRte {}
-
-/**
- * @deprecated since 6.0, removed since 7.0
- */
 class extDirect_dataProvider_BackendLiveSearch extends \TYPO3\CMS\Backend\Search\LiveSearch\ExtDirect\LiveSearchDataProvider {}
 
 /**
@@ -5779,11 +5774,6 @@ class tx_rtehtmlarea_api extends \TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi {}
 /**
  * @deprecated since 6.0, removed since 7.0
  */
-class tx_rtehtmlarea_base extends \TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase {}
-
-/**
- * @deprecated since 6.0, removed since 7.0
- */
 class tx_rtehtmlarea_select_image extends \TYPO3\CMS\Rtehtmlarea\SelectImage {}
 
 /**
index 7090b0d..a335d58 100644 (file)
@@ -27,7 +27,6 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
  * functions for the authentication process of backend users.
  *
  * @author Kasper Skårhøj <kasperYYYY@typo3.com>
- * @internal
  */
 class BackendUserAuthentication extends \TYPO3\CMS\Core\Authentication\AbstractUserAuthentication {
 
@@ -158,12 +157,6 @@ class BackendUserAuthentication extends \TYPO3\CMS\Core\Authentication\AbstractU
        public $userTS_dontGetCached = FALSE;
 
        /**
-        * RTE availability errors collected.
-        * @var array
-        */
-       public $RTE_errors = array();
-
-       /**
         * Contains last error message
         * @var string
         */
@@ -545,26 +538,12 @@ class BackendUserAuthentication extends \TYPO3\CMS\Core\Authentication\AbstractU
        }
 
        /**
-        * Returns TRUE if the RTE (Rich Text Editor) can be enabled for the user
-        * Strictly this is not permissions being checked but rather a series of settings like
-        * a loaded extension, browser/client type and a configuration option in ->uc[edit_RTE]
-        * The reasons for a FALSE return can be found in $this->RTE_errors
+        * Returns TRUE if the RTE (Rich Text Editor) is enabled for the user.
         *
         * @return bool
         */
        public function isRTE() {
-               // Start:
-               $this->RTE_errors = array();
-               if (!$this->uc['edit_RTE']) {
-                       $this->RTE_errors[] = 'RTE is not enabled for user!';
-               }
-               // Acquire RTE object:
-               $RTE = BackendUtility::RTEgetObj();
-               if (!is_object($RTE)) {
-                       $this->RTE_errors = array_merge($this->RTE_errors, $RTE);
-               }
-
-               return empty($this->RTE_errors);
+               return (bool)$this->uc['edit_RTE'];
        }
 
        /**
index aab2446..786084f 100644 (file)
@@ -22,6 +22,7 @@ use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
 use TYPO3\CMS\Core\Database\DatabaseConnection;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\CMS\Core\Database\RelationHandler;
+use TYPO3\CMS\Core\Html\RteHtmlParser;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
 use TYPO3\CMS\Core\Resource\ResourceFactory;
@@ -1545,13 +1546,9 @@ class DataHandler {
                                        }
                                        $RTEsetup = $this->BE_USER->getTSConfig('RTE', BackendUtility::getPagesTSconfig($tscPID));
                                        $thisConfig = BackendUtility::RTEsetup($RTEsetup['properties'], $table, $vconf['field'], $theTypeString);
-                                       // Get RTE object, draw form and set flag:
-                                       $RTEobj = BackendUtility::RTEgetObj();
-                                       if (is_object($RTEobj)) {
-                                               $fieldArray[$vconf['field']] = $RTEobj->transformContent('db', $fieldArray[$vconf['field']], $table, $vconf['field'], $currentRecord, $vconf['spec'], $thisConfig, '', $currentRecord['pid']);
-                                       } else {
-                                               debug('NO RTE OBJECT FOUND!');
-                                       }
+                                       $fieldArray[$vconf['field']] = $this->transformRichtextContentToDatabase(
+                                               $fieldArray[$vconf['field']], $table, $vconf['field'], $vconf['spec'], $thisConfig, $currentRecord['pid']
+                                       );
                                }
                        }
                }
@@ -1559,6 +1556,34 @@ class DataHandler {
                return $fieldArray;
        }
 
+       /**
+        * Performs transformation of content from richtext element to database.
+        *
+        * @param string $value Value to transform.
+        * @param string $table The table name
+        * @param string $field The field name
+        * @param array $defaultExtras Default extras configuration of this field - typically "richtext:rte_transform[mode=ts_css]"
+        * @param array $thisConfig Configuration for RTEs; A mix between TSconfig and others. Configuration for additional transformation information
+        * @param int $pid PID value of record (true parent page id)
+        * @return string Transformed content
+        */
+       protected function transformRichtextContentToDatabase($value, $table, $field, $defaultExtras, $thisConfig, $pid) {
+               if ($defaultExtras['rte_transform']) {
+                       $parameters = BackendUtility::getSpecConfParametersFromArray($defaultExtras['rte_transform']['parameters']);
+                       // There must be a mode set for transformation, this is typically 'ts_css'
+                       if ($parameters['mode']) {
+                               // Initialize transformation:
+                               $parseHTML = GeneralUtility::makeInstance(RteHtmlParser::class);
+                               $parseHTML->init($table . ':' . $field, $pid);
+                               $parseHTML->setRelPath('');
+                               // Perform transformation:
+                               $value = $parseHTML->RTE_transform($value, $defaultExtras, 'db', $thisConfig);
+                       }
+               }
+               return $value;
+       }
+
+
        /*********************************************
         *
         * Evaluation of input values
@@ -3011,13 +3036,9 @@ class DataHandler {
                                                                                // Find, thisConfig:
                                                                                $RTEsetup = $this->BE_USER->getTSConfig('RTE', BackendUtility::getPagesTSconfig($CVtscPID));
                                                                                $thisConfig = BackendUtility::RTEsetup($RTEsetup['properties'], $CVtable, $recFieldName, $theTypeString);
-                                                                               // Get RTE object, draw form and set flag:
-                                                                               $RTEobj = BackendUtility::RTEgetObj();
-                                                                               if (is_object($RTEobj)) {
-                                                                                       $res['value'] = $RTEobj->transformContent('db', $res['value'], $CVtable, $recFieldName, $this->checkValue_currentRecord, $specConf, $thisConfig, '', $CVrealPid);
-                                                                               } else {
-                                                                                       debug('NO RTE OBJECT FOUND!');
-                                                                               }
+                                                                               $res['value'] = $this->transformRichtextContentToDatabase(
+                                                                                       $res['value'], $CVtable, $recFieldName, $specConf, $thisConfig, $CVrealPid
+                                                                               );
                                                                        }
                                                                }
                                                        }
index 3dc2f0a..71e5e08 100644 (file)
@@ -146,7 +146,8 @@ class ExtensionManagementUtility {
                        throw new \BadFunctionCallException('TYPO3 Fatal Error: Extension key "' . $key . '" is NOT loaded!', 1365429673);
                }
                $relativePathToSiteRoot = self::siteRelPath($key);
-               if (substr($relativePathToSiteRoot, 0, $typo3MainDirLength = strlen(TYPO3_mainDir)) === TYPO3_mainDir) {
+               $typo3MainDirLength = strlen(TYPO3_mainDir);
+               if (substr($relativePathToSiteRoot, 0, $typo3MainDirLength) === TYPO3_mainDir) {
                        $relativePathToSiteRoot = substr($relativePathToSiteRoot, $typo3MainDirLength);
                } else {
                        $relativePathToSiteRoot = '../' . $relativePathToSiteRoot;
index 23d5c3c..936c37e 100644 (file)
@@ -309,7 +309,6 @@ return array(
                'diff_path' => 'diff',                                                  // Path to "diff" including the program name. Example: /somepath/specialdiff<br />For Windows this program can be downloaded here: <a href="http://unxutils.sourceforge.net/" target="_blank">unxutils.sourceforge.net</a>
                'fileadminDir' => 'fileadmin/',                                 // Path to the fileadmin dir. This is relative to PATH_site, DefaultStorage will be created with that configuration, do not access manually but ResourceFactory::getDefaultStorage()
                'RTE_imageStorageDir' => 'uploads/',                    // Default storage directory for Rich Text Editor files
-               'RTE_reg' => array(),                                                   // Contains arrays of possible RTEs available (keys=extKey, values=cfg-array). Each array contains a key, "objRef", which contains a user function call with prefixed script path and instanciating a persistent global object. This can report back if browser requirements are OK, draw the RTE and do the transformations needed.
                'lockRootPath' => '',                                                   // This path is used to evaluate if paths outside of PATH_site should be allowed. Ending slash required!
                'userHomePath' => '',                                                   // Combined folder identifier of the directory where TYPO3 backend-users have their home-dirs. A combined folder identifier looks like this: [storageUid]:[folderIdentifier]. Eg. '2:users/'. A home for backend user 2 would be: '2:users/2/'. Ending slash required!
                'groupHomePath' => '',                                                  // Combined folder identifier of the directory where TYPO3 backend-groups have their home-dirs. A combined folder identifier looks like this: [storageUid]:[folderIdentifier]. Eg. '2:groups/'. A home for backend group 1 would be: '2:groups/1/'. Ending slash required!
index 071e6d4..2cda7cb 100644 (file)
@@ -7,22 +7,74 @@ Description
 
 The ``RTE`` implementation was based on the main classes ``\TYPO3\CMS\Backend\Rte\AbstractRte``,
 ``\TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase`` and ``\TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi``. These
-three main API classes contain changed signatures and internal method calls.
+three main API were removed or changed method signatures and internal method calls.
+
+The functionality to render ``RTE`` standalone and out of a context of ``FormEngine`` was dropped.
 
 
 Impact
 ======
 
-Extensions that extend those classes and rely on methods being called are likely to break.
+Main API changes
+----------------
+
+* Method ``TYPO3\CMS\Backend\Utility\BackendUtility::RTEgetObj()`` is deprecated and no longer used.
+  ``FormEngine`` now creates a ``RichTextElement`` with ``NodeFactory`` and ``makeInstance()``, the
+  created object is not a singleton but a prototype.
+
+* With the deprecation of ``RTEgetObj`` method ``transformContent`` from ``AbstractRte`` has been inlined to
+  ``DataHandler``.
+
+* Method ``isAvailable`` from ``AbstractRte`` has been dropped. Every valid browser and browser version
+  for TYPO3 CMS 7 can render the default richtext editor nowadays. Custom checks may be implement via
+  ``NodeResolverInterface`` in ``FormEngine``.
+
+* Property ``RTE_errors`` in ``TYPO3\CMS\Core\Authentication\BackendUserAuthentication`` has been dropped along
+  with the ``RTEgetObj()`` deprecation.
+
+
+RTE registration
+----------------
+
+* Different richtext implementations can no longer register in ``$GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_reg']``.
+  Instead, registration in ``FormEngine`` must be done via ``NodeFactory`` API, method ``drawRTE`` has been dropped.
+
+* Transformations are not available via ``AbstractRte`` anymore, hooks within ``RteHtmlParser`` can
+  be used for custom transformations.
+
+
+PHP classes
+-----------
+
+* ``\TYPO3\CMS\Backend\Rte\AbstractRte`` has been dropped.
+
+* ``\TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase`` has been dropped and functionality moved to
+  ``\TYPO3\CMS\Rtehtmlarea\Form\Element\RichtextElement``. All methods and properties except
+  the main entry method ``render()`` used by ``FormEngine`` are protected.
+
+* ``\TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi`` has been refactored. Method ``main()`` receives
+  a configuration array instead of an instance of the parent object. Some methods were dropped
+  and are no longer called.
+
+
+RTE Plugin Configuration
+------------------------
+
+* Parameter ``$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['anExtensionKey']['plugins']['aPluginName']['addIconsToSkin']''
+  was dropped, plugin property ``relativePathToSkin`` is no longer evaluated.
+
+* A couple of helper methods were added to ``RteHtmlAreaApi``
+
+* This API may get further changes in the future.
 
 
 Affected Installations
 ======================
 
-Extensions that extend one of the above mentioned extensions.
+Extensions that extend one of the above mentioned extensions or API.
 
 
 Migration
 =========
 
-No details yet.
\ No newline at end of file
+Adapt the using code.
\ No newline at end of file
index 70f3fcd..e1d3993 100644 (file)
@@ -19,7 +19,8 @@ use TYPO3\CMS\Core\Database\QueryGenerator;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
+use TYPO3\CMS\Core\Database\DatabaseConnection;
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 
 /**
  * Abbreviation extension for htmlArea RTE
@@ -68,46 +69,47 @@ class Abbreviation extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject Reference to parent object
-        * @return bool TRUE if this plugin should be made available in the current environment and is correctly initialized
+        * @param array $configuration Configuration array given from calling object down to the single plugins
+        * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main(RteHtmlAreaBase $parentObject) {
+       public function main(array $configuration) {
+               $enabled = parent::main($configuration);
                // acronym button is deprecated as of TYPO3 CMS 7.0, use abbreviation instead
                // Convert the acronym button configuration
-               if (isset($this->thisConfig['buttons.']['acronym.']) && is_array($this->thisConfig['buttons.']['acronym.'])) {
-                       if (!isset($this->thisConfig['buttons.']['abbreviation.']) || !is_array($this->thisConfig['buttons.']['abbreviation.'])) {
-                               $this->thisConfig['buttons.']['abbreviation.'] = $this->thisConfig['buttons.']['acronym.'];
+               if (isset($this->configuration['thisConfig']['buttons.']['acronym.']) && is_array($this->configuration['thisConfig']['buttons.']['acronym.'])) {
+                       if (!isset($this->configuration['thisConfig']['buttons.']['abbreviation.']) || !is_array($this->configuration['thisConfig']['buttons.']['abbreviation.'])) {
+                               $this->configuration['thisConfig']['buttons.']['abbreviation.'] = $this->configuration['thisConfig']['buttons.']['acronym.'];
                        }
-                       unset($this->thisConfig['buttons.']['acronym.']);
+                       unset($this->configuration['thisConfig']['buttons.']['acronym.']);
                }
                // Convert any other reference to acronym two levels down in Page TSconfig, except in processing options and removeFieldsets property
-               foreach ($parentObject->thisConfig as $key => $config) {
+               foreach ($this->configuration['thisConfig'] as $key => $config) {
                        if ($key !== 'proc.') {
                                if (is_array($config)) {
                                        foreach ($config as $subKey => $subConfig) {
                                                if (is_array($subConfig)) {
                                                        foreach ($subConfig as $subSubKey => $subSubConfig) {
                                                                if ($subSubKey !== 'removeFieldsets') {
-                                                                       $parentObject->thisConfig[$key][$subKey][$subSubKey] = str_replace('acronym', 'abbreviation', $subSubConfig);
+                                                                       $this->configuration['thisConfig'][$key][$subKey][$subSubKey] = str_replace('acronym', 'abbreviation', $subSubConfig);
                                                                }
                                                        }
                                                } else {
                                                        if ($subKey !== 'removeFieldsets') {
-                                                               $parentObject->thisConfig[$key][$subKey] = str_replace('acronym', 'abbreviation', $subConfig);
+                                                               $this->configuration['thisConfig'][$key][$subKey] = str_replace('acronym', 'abbreviation', $subConfig);
                                                        }
                                                }
                                        }
                                } else {
                                        if ($key !== 'removeFieldsets') {
-                                               $parentObject->thisConfig[$key] = str_replace('acronym', 'abbreviation', $config);
+                                               $this->configuration['thisConfig'][$key] = str_replace('acronym', 'abbreviation', $config);
                                        }
                                }
                        }
                }
                // Convert any reference to acronym in special configuration options
-               if (is_array($parentObject->specConf['richtext']['parameters'])) {
-                       foreach ($parentObject->specConf['richtext']['parameters'] as $key => $config) {
-                               $parentObject->specConf['richtext']['parameters'][$key] = str_replace('acronym', 'abbreviation', $config);
+               if (is_array($this->configuration['specConf']['richtext']['parameters'])) {
+                       foreach ($this->configuration['specConf']['richtext']['parameters'] as $key => $config) {
+                               $this->configuration['specConf']['richtext']['parameters'][$key] = str_replace('acronym', 'abbreviation', $config);
                        }
                }
                // Convert any reference to acronym in user TSconfig
@@ -115,35 +117,27 @@ class Abbreviation extends RteHtmlAreaApi {
                        $GLOBALS['BE_USER']->userTS['options.']['RTEkeyList'] = str_replace('acronym', 'abbreviation', $GLOBALS['BE_USER']->userTS['options.']['RTEkeyList']);
                }
                // Remove button if all fieldsets are removed
-               $removedFieldsets = GeneralUtility::trimExplode(',', $this->thisConfig['buttons.']['abbreviation.']['removeFieldsets'], TRUE);
-               return parent::main($parentObject) && ExtensionManagementUtility::isLoaded('static_info_tables') && count($removedFieldsets) < 4;
+               $removedFieldsets = GeneralUtility::trimExplode(',', $this->configuration['thisConfig']['buttons.']['abbreviation.']['removeFieldsets'], TRUE);
+               return $enabled && ExtensionManagementUtility::isLoaded('static_info_tables') && count($removedFieldsets) < 4;
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins, in this case, JS configuration of block elements
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
                $button = 'abbreviation';
+               $jsArray = array();
                if (in_array($button, $this->toolbar)) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = new Object();';
                        }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.abbreviationUrl = "' . $this->htmlAreaRTE->writeTemporaryFile('abbreviation_' . $this->htmlAreaRTE->contentLanguageUid, 'js', $this->buildJSAbbreviationArray($this->htmlAreaRTE->contentLanguageUid)) . '";';
-                       // <abbr> was not supported by IE before version 7
-                       if ($this->htmlAreaRTE->client['browser'] == 'msie' && $this->htmlAreaRTE->client['version'] < 7) {
-                               $this->abbreviationIndex = 0;
-                       }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.noAcronym = ' . ($this->acronymIndex ? 'false' : 'true') . ';
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.noAbbr =  ' . ($this->abbreviationIndex ? 'false' : 'true') . ';';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.abbreviationUrl = "' . $this->writeTemporaryFile('abbreviation_' . $this->configuration['contentLanguageUid'], 'js', $this->buildJSAbbreviationArray()) . '";';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.noAcronym = ' . ($this->acronymIndex ? 'false' : 'true') . ';';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.noAbbr =  ' . ($this->abbreviationIndex ? 'false' : 'true') . ';';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
        /**
@@ -151,7 +145,9 @@ class Abbreviation extends RteHtmlAreaApi {
         *
         * @return string abbreviation Javascript array
         */
-       protected function buildJSAbbreviationArray($languageUid) {
+       protected function buildJSAbbreviationArray() {
+               $database = $this->getDatabaseConnection();
+               $backendUser = $this->getBackendUserAuthentication();
                $button = 'abbreviation';
                $acronymArray = array();
                $abbrArray = array();
@@ -162,21 +158,21 @@ class Abbreviation extends RteHtmlAreaApi {
                $whereClause = '1=1';
                $loadRecordsFromDatabase = TRUE;
                // Get all abbreviations on pages to which the user has access
-               $lockBeUserToDBmounts = isset($this->thisConfig['buttons.'][$button . '.']['lockBeUserToDBmounts']) ? $this->thisConfig['buttons.'][$button . '.']['lockBeUserToDBmounts'] : $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts'];
-               if (!$GLOBALS['BE_USER']->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts'] && $lockBeUserToDBmounts) {
+               $lockBeUserToDBmounts = isset($this->configuration['thisConfig']['buttons.'][$button . '.']['lockBeUserToDBmounts']) ? $this->configuration['thisConfig']['buttons.'][$button . '.']['lockBeUserToDBmounts'] : $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts'];
+               $savedGroupDataWebmounts = $backendUser->groupData['webmounts'];
+               if (!$backendUser->isAdmin() && $GLOBALS['TYPO3_CONF_VARS']['BE']['lockBeUserToDBmounts'] && $lockBeUserToDBmounts) {
                        // Temporarily setting alternative web browsing mounts
-                       $altMountPoints = trim($GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.altElementBrowserMountPoints'));
+                       $altMountPoints = trim($backendUser->getTSConfigVal('options.pageTree.altElementBrowserMountPoints'));
                        if ($altMountPoints) {
-                               $savedGroupDataWebmounts = $GLOBALS['BE_USER']->groupData['webmounts'];
-                               $GLOBALS['BE_USER']->groupData['webmounts'] = implode(',', array_unique(GeneralUtility::intExplode(',', $altMountPoints)));
+                               $backendUser->groupData['webmounts'] = implode(',', array_unique(GeneralUtility::intExplode(',', $altMountPoints)));
                        }
-                       $webMounts = $GLOBALS['BE_USER']->returnWebmounts();
-                       $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
-                       $recursive = isset($this->thisConfig['buttons.'][$button . '.']['recursive']) ? (int)$this->thisConfig['buttons.'][$button . '.']['recursive'] : 0;
-                       if (trim($this->thisConfig['buttons.'][$button . '.']['pages'])) {
-                               $pids = GeneralUtility::trimExplode(',', $this->thisConfig['buttons.'][$button . '.']['pages'], TRUE);
+                       $webMounts = $backendUser->returnWebmounts();
+                       $perms_clause = $backendUser->getPagePermsClause(1);
+                       $recursive = isset($this->configuration['thisConfig']['buttons.'][$button . '.']['recursive']) ? (int)$this->configuration['thisConfig']['buttons.'][$button . '.']['recursive'] : 0;
+                       if (trim($this->configuration['thisConfig']['buttons.'][$button . '.']['pages'])) {
+                               $pids = GeneralUtility::trimExplode(',', $this->configuration['thisConfig']['buttons.'][$button . '.']['pages'], TRUE);
                                foreach ($pids as $key => $val) {
-                                       if (!$GLOBALS['BE_USER']->isInWebMount($val, $perms_clause)) {
+                                       if (!$backendUser->isInWebMount($val, $perms_clause)) {
                                                unset($pids[$key]);
                                        }
                                }
@@ -184,9 +180,7 @@ class Abbreviation extends RteHtmlAreaApi {
                                $pids = $webMounts;
                        }
                        // Restoring webmounts
-                       if ($altMountPoints) {
-                               $GLOBALS['BE_USER']->groupData['webmounts'] = $savedGroupDataWebmounts;
-                       }
+                       $backendUser->groupData['webmounts'] = $savedGroupDataWebmounts;
                        $queryGenerator = GeneralUtility::makeInstance(QueryGenerator::class);
                        $pageTree = '';
                        $pageTreePrefix = '';
@@ -208,20 +202,20 @@ class Abbreviation extends RteHtmlAreaApi {
 
                if ($loadRecordsFromDatabase) {
                        // Restrict to abbreviations applicable to the language of current content element
-                       if ($this->htmlAreaRTE->contentLanguageUid > -1) {
-                               $whereClause .= ' AND (' . $tableA . '.sys_language_uid=' . $this->htmlAreaRTE->contentLanguageUid . ' OR ' . $tableA . '.sys_language_uid=-1) ';
+                       if ($this->configuration['contentLanguageUid'] > -1) {
+                               $whereClause .= ' AND (' . $tableA . '.sys_language_uid=' . $this->configuration['contentLanguageUid'] . ' OR ' . $tableA . '.sys_language_uid=-1) ';
                        }
                        // Restrict to abbreviations in certain languages
-                       if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['language.']) && isset($this->thisConfig['buttons.']['language.']['restrictToItems'])) {
-                               $languageList = implode('\',\'', GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_DB']->fullQuoteStr(strtoupper($this->thisConfig['buttons.']['language.']['restrictToItems']), $tableB)));
+                       if (is_array($this->configuration['thisConfig']['buttons.']) && is_array($this->configuration['thisConfig']['buttons.']['language.']) && isset($this->configuration['thisConfig']['buttons.']['language.']['restrictToItems'])) {
+                               $languageList = implode('\',\'', GeneralUtility::trimExplode(',', $database->fullQuoteStr(strtoupper($this->configuration['thisConfig']['buttons.']['language.']['restrictToItems']), $tableB)));
                                $whereClause .= ' AND ' . $tableB . '.lg_iso_2 IN (' . $languageList . ') ';
                        }
                        $whereClause .= BackendUtility::BEenableFields($tableA);
                        $whereClause .= BackendUtility::deleteClause($tableA);
                        $whereClause .= BackendUtility::BEenableFields($tableB);
                        $whereClause .= BackendUtility::deleteClause($tableB);
-                       $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $tableAB, $whereClause);
-                       while ($abbreviationRow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+                       $res = $database->exec_SELECTquery($fields, $tableAB, $whereClause);
+                       while ($abbreviationRow = $database->sql_fetch_assoc($res)) {
                                $item = array('term' => $abbreviationRow['term'], 'abbr' => $abbreviationRow['acronym'], 'language' => strtolower($abbreviationRow['lg_iso_2']) . ($abbreviationRow['lg_country_iso_2'] ? '-' . $abbreviationRow['lg_country_iso_2'] : ''));
                                if ($abbreviationRow['type'] == 1) {
                                        $acronymArray[] = $item;
@@ -229,6 +223,7 @@ class Abbreviation extends RteHtmlAreaApi {
                                        $abbrArray[] = $item;
                                }
                        }
+                       $database->sql_free_result($res);
                }
 
                $this->acronymIndex = count($acronymArray);
@@ -236,4 +231,18 @@ class Abbreviation extends RteHtmlAreaApi {
                return json_encode(array('abbr' => $abbrArray, 'acronym' => $acronymArray));
        }
 
+       /**
+        * @return DatabaseConnection
+        */
+       protected function getDatabaseConnection() {
+               return $GLOBALS['TYPO3_DB'];
+       }
+
+       /**
+        * @return BackendUserAuthentication
+        */
+       protected function getBackendUserAuthentication() {
+               return $GLOBALS['BE_USER'];
+       }
+
 }
index d62fbb9..3da1501 100644 (file)
@@ -13,6 +13,7 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  *
  * The TYPO3 project - inspiring people to share!
  */
+
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
 
 /**
@@ -48,10 +49,9 @@ class AboutEditor extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
index bc6bf1e..84b0f1d 100644 (file)
@@ -95,15 +95,13 @@ class BlockElements extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins, in this case, JS configuration of block elements
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                if (in_array('formatblock', $this->toolbar)) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.']['formatblock.'])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.formatblock = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.']['formatblock.'])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.formatblock = new Object();';
                        }
                        // Default block elements
                        $hideItems = array();
@@ -113,32 +111,28 @@ class BlockElements extends RteHtmlAreaApi {
                        $prefixLabelWithTag = FALSE;
                        $postfixLabelWithTag = FALSE;
                        // Processing PageTSConfig
-                       if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['formatblock.'])) {
+                       if (is_array($this->configuration['thisConfig']['buttons.']) && is_array($this->configuration['thisConfig']['buttons.']['formatblock.'])) {
                                // Removing elements
-                               if ($this->thisConfig['buttons.']['formatblock.']['removeItems']) {
-                                       if ($this->htmlAreaRTE->cleanList($this->thisConfig['buttons.']['formatblock.']['removeItems']) == '*') {
-                                               $hideItems = array_diff(array_keys($defaultBlockElements), array('none'));
-                                       } else {
-                                               $hideItems = GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList(GeneralUtility::strtolower($this->thisConfig['buttons.']['formatblock.']['removeItems'])), TRUE);
-                                       }
+                               if ($this->configuration['thisConfig']['buttons.']['formatblock.']['removeItems']) {
+                                       $hideItems = GeneralUtility::trimExplode(',', $this->cleanList(GeneralUtility::strtolower($this->configuration['thisConfig']['buttons.']['formatblock.']['removeItems'])), TRUE);
                                }
                                // Adding elements
-                               if ($this->thisConfig['buttons.']['formatblock.']['addItems']) {
-                                       $addItems = GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList(GeneralUtility::strtolower($this->thisConfig['buttons.']['formatblock.']['addItems'])), TRUE);
+                               if ($this->configuration['thisConfig']['buttons.']['formatblock.']['addItems']) {
+                                       $addItems = GeneralUtility::trimExplode(',', $this->cleanList(GeneralUtility::strtolower($this->configuration['thisConfig']['buttons.']['formatblock.']['addItems'])), TRUE);
                                }
                                // Restriction clause
-                               if ($this->thisConfig['buttons.']['formatblock.']['restrictToItems']) {
-                                       $restrictTo = GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList('none,' . GeneralUtility::strtolower($this->thisConfig['buttons.']['formatblock.']['restrictToItems'])), TRUE);
+                               if ($this->configuration['thisConfig']['buttons.']['formatblock.']['restrictToItems']) {
+                                       $restrictTo = GeneralUtility::trimExplode(',', $this->cleanList('none,' . GeneralUtility::strtolower($this->configuration['thisConfig']['buttons.']['formatblock.']['restrictToItems'])), TRUE);
                                }
                                // Elements order
-                               if ($this->thisConfig['buttons.']['formatblock.']['orderItems']) {
-                                       $blockElementsOrder = 'none,' . GeneralUtility::strtolower($this->thisConfig['buttons.']['formatblock.']['orderItems']);
+                               if ($this->configuration['thisConfig']['buttons.']['formatblock.']['orderItems']) {
+                                       $blockElementsOrder = 'none,' . GeneralUtility::strtolower($this->configuration['thisConfig']['buttons.']['formatblock.']['orderItems']);
                                }
-                               $prefixLabelWithTag = $this->thisConfig['buttons.']['formatblock.']['prefixLabelWithTag'] ? TRUE : $prefixLabelWithTag;
-                               $postfixLabelWithTag = $this->thisConfig['buttons.']['formatblock.']['postfixLabelWithTag'] ? TRUE : $postfixLabelWithTag;
+                               $prefixLabelWithTag = $this->configuration['thisConfig']['buttons.']['formatblock.']['prefixLabelWithTag'] ? TRUE : $prefixLabelWithTag;
+                               $postfixLabelWithTag = $this->configuration['thisConfig']['buttons.']['formatblock.']['postfixLabelWithTag'] ? TRUE : $postfixLabelWithTag;
                        }
                        // Adding custom items
-                       $blockElementsOrder = array_merge(GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList($blockElementsOrder), TRUE), $addItems);
+                       $blockElementsOrder = array_merge(GeneralUtility::trimExplode(',', $this->cleanList($blockElementsOrder), TRUE), $addItems);
                        // Add div element if indent is configured in the toolbar
                        if (in_array('indent', $this->toolbar) || in_array('outdent', $this->toolbar)) {
                                $blockElementsOrder = array_merge($blockElementsOrder, array('div'));
@@ -156,8 +150,8 @@ class BlockElements extends RteHtmlAreaApi {
                        // Localizing the options
                        $blockElementsOptions = array();
                        $labels = array();
-                       if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['formatblock.']) && is_array($this->thisConfig['buttons.']['formatblock.']['items.'])) {
-                               $labels = $this->thisConfig['buttons.']['formatblock.']['items.'];
+                       if (is_array($this->configuration['thisConfig']['buttons.']) && is_array($this->configuration['thisConfig']['buttons.']['formatblock.']) && is_array($this->configuration['thisConfig']['buttons.']['formatblock.']['items.'])) {
+                               $labels = $this->configuration['thisConfig']['buttons.']['formatblock.']['items.'];
                        }
                        foreach ($blockElementsOrder as $item) {
                                $blockElementsOptions[$item] = $this->getLanguageService()->sL(
@@ -165,13 +159,13 @@ class BlockElements extends RteHtmlAreaApi {
                                );
                                // Getting custom labels
                                if (is_array($labels[$item . '.']) && $labels[$item . '.']['label']) {
-                                       $blockElementsOptions[$item] = $this->htmlAreaRTE->getPageConfigLabel($labels[$item . '.']['label'], 0);
+                                       $blockElementsOptions[$item] = $this->getPageConfigLabel($labels[$item . '.']['label']);
                                }
                                $blockElementsOptions[$item] = ($prefixLabelWithTag && $item != 'none' ? $item . ' - ' : '') . $blockElementsOptions[$item] . ($postfixLabelWithTag && $item != 'none' ? ' - ' . $item : '');
                        }
                        $first = array_shift($blockElementsOptions);
                        // Sorting the options
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.']['formatblock.']) || !$this->thisConfig['buttons.']['formatblock.']['orderItems']) {
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.']['formatblock.']) || !$this->configuration['thisConfig']['buttons.']['formatblock.']['orderItems']) {
                                asort($blockElementsOptions);
                        }
                        // Generating the javascript options
@@ -180,13 +174,9 @@ class BlockElements extends RteHtmlAreaApi {
                        foreach ($blockElementsOptions as $item => $label) {
                                $JSBlockElements[] = array($label, $item);
                        }
-                       if ($this->htmlAreaRTE->is_FE()) {
-                               $GLOBALS['TSFE']->csConvObj->convArray($JSBlockElements, $this->htmlAreaRTE->OutputCharset, 'utf-8');
-                       }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.formatblock.options = ' . json_encode($JSBlockElements) . ';';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.formatblock.options = ' . json_encode($JSBlockElements) . ';';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
 }
index a706fab..76ebe41 100644 (file)
@@ -50,10 +50,9 @@ class CharacterMap extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
index 786c49a..0968c99 100644 (file)
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  */
 
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -35,34 +34,45 @@ class ContextMenu extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               return parent::main($parentObject) && !($this->htmlAreaRTE->client['browser'] == 'opera' || $this->thisConfig['contextMenu.']['disabled']);
+       public function main(array $configuration) {
+               return parent::main($configuration)
+                       && !($this->configuration['client']['browser'] === 'opera' || $this->configuration['thisConfig']['contextMenu.']['disabled']);
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
-               if (is_array($this->thisConfig['contextMenu.'])) {
-                       $registerRTEinJavascriptString .= '
-       RTEarea[' . $rteNumberPlaceholder . '].contextMenu =  ' . $this->htmlAreaRTE->buildNestedJSArray($this->thisConfig['contextMenu.']) . ';';
-                       if ($this->thisConfig['contextMenu.']['showButtons']) {
-                               $registerRTEinJavascriptString .= '
-       RTEarea[' . $rteNumberPlaceholder . '].contextMenu.showButtons = ' . json_encode(GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList(GeneralUtility::strtolower($this->thisConfig['contextMenu.']['showButtons'])), TRUE)) . ';';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
+               if (is_array($this->configuration['thisConfig']['contextMenu.'])) {
+                       $jsArray[] = 'RTEarea[editornumber].contextMenu =  ' . $this->buildNestedJSArray($this->configuration['thisConfig']['contextMenu.']) . ';';
+                       if ($this->configuration['thisConfig']['contextMenu.']['showButtons']) {
+                               $jsArray[] = 'RTEarea[editornumber].contextMenu.showButtons = ' . json_encode(GeneralUtility::trimExplode(',', $this->cleanList(GeneralUtility::strtolower($this->configuration['thisConfig']['contextMenu.']['showButtons'])), TRUE)) . ';';
                        }
-                       if ($this->thisConfig['contextMenu.']['hideButtons']) {
-                               $registerRTEinJavascriptString .= '
-       RTEarea[' . $rteNumberPlaceholder . '].contextMenu.hideButtons = ' . json_encode(GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList(GeneralUtility::strtolower($this->thisConfig['contextMenu.']['hideButtons'])), TRUE)) . ';';
+                       if ($this->configuration['thisConfig']['contextMenu.']['hideButtons']) {
+                               $jsArray[] = 'RTEarea[editornumber].contextMenu.hideButtons = ' . json_encode(GeneralUtility::trimExplode(',', $this->cleanList(GeneralUtility::strtolower($this->configuration['thisConfig']['contextMenu.']['hideButtons'])), TRUE)) . ';';
                        }
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
+       }
+
+       /**
+        * Translate Page TS Config array in JS nested array definition
+        * Replace 0 values with false
+        * Unquote regular expression values
+        * Replace empty arrays with empty objects
+        *
+        * @param array $conf: Page TSConfig configuration array
+        * @return string nested JS array definition
+        */
+       protected function buildNestedJSArray($conf) {
+               $convertedConf = GeneralUtility::removeDotsFromTS($conf);
+               return str_replace(array(':"0"', ':"\\/^(', ')$\\/i"', ':"\\/^(', ')$\\/"', '[]'), array(':false', ':/^(', ')$/i', ':/^(', ')$/', '{}'), json_encode($convertedConf));
        }
 
 }
index a181ae6..3af78ae 100644 (file)
@@ -16,7 +16,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
 
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * Copy Paste plugin for htmlArea RTE
@@ -64,14 +63,14 @@ class CopyPaste extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               $enabled = parent::main($parentObject);
+       public function main(array $configuration) {
+               $enabled = parent::main($configuration);
                // Hiding some buttons
-               if ($enabled && is_array($this->hideButtonsFromClient[$this->htmlAreaRTE->client['browser']])) {
-                       $this->pluginButtons = implode(',', array_diff(GeneralUtility::trimExplode(',', $this->pluginButtons, TRUE), $this->hideButtonsFromClient[$this->htmlAreaRTE->client['browser']]));
+               if ($enabled && is_array($this->hideButtonsFromClient[$this->configuration['client']['browser']])) {
+                       $this->pluginButtons = implode(',', array_diff(GeneralUtility::trimExplode(',', $this->pluginButtons, TRUE), $this->hideButtonsFromClient[$this->configuration['client']['browser']]));
                }
                // Force enabling the plugin even if no button remains in the tool bar, so that hot keys still are enabled
                $this->pluginAddsButtons = FALSE;
@@ -86,8 +85,8 @@ class CopyPaste extends RteHtmlAreaApi {
         */
        public function applyToolbarConstraints($show) {
                // Remove some buttons
-               if (is_array($this->hideButtonsFromClient[$this->htmlAreaRTE->client['browser']])) {
-                       return array_diff($show, $this->hideButtonsFromClient[$this->htmlAreaRTE->client['browser']]);
+               if (is_array($this->hideButtonsFromClient[$this->configuration['client']['browser']])) {
+                       return array_diff($show, $this->hideButtonsFromClient[$this->configuration['client']['browser']]);
                } else {
                        return $show;
                }
index b5eb9d3..e37cc4c 100644 (file)
@@ -16,7 +16,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
 
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * Default Clean extension for htmlArea RTE
@@ -51,31 +50,30 @@ class DefaultClean extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               return parent::main($parentObject) && $this->thisConfig['enableWordClean'] && !is_array($this->thisConfig['enableWordClean.']['HTMLparser.']);
+       public function main(array $configuration) {
+               return parent::main($configuration)
+                       && $this->configuration['thisConfig']['enableWordClean']
+                       && !is_array($this->configuration['thisConfig']['enableWordClean.']['HTMLparser.']);
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins, in this case, JS configuration of block elements
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                $button = 'cleanword';
                if (in_array($button, $this->toolbar)) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = new Object();';
                        }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = {"hotKey" : "' . ($this->thisConfig['enableWordClean.']['hotKey'] ? $this->thisConfig['enableWordClean.']['hotKey'] : '0') . '"};';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = {"hotKey" : "' . ($this->configuration['thisConfig']['enableWordClean.']['hotKey'] ? $this->configuration['thisConfig']['enableWordClean.']['hotKey'] : '0') . '"};';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
        /**
index 755ff0c..9762dcb 100644 (file)
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  */
 
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * Image plugin for htmlArea RTE
@@ -50,22 +49,25 @@ class DefaultImage extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
+       public function main(array $configuration) {
                // Check if this should be enabled based on extension configuration and Page TSConfig
                // The 'Minimal' and 'Typical' default configurations include Page TSConfig that removes images on the way to the database
-               return parent::main($parentObject) && !($this->thisConfig['proc.']['entryHTMLparser_db.']['tags.']['img.']['allowedAttribs'] == '0' && $this->thisConfig['proc.']['entryHTMLparser_db.']['tags.']['img.']['rmTagIfNoAttrib'] == '1');
+               return parent::main($configuration)
+                       && !(
+                               $this->configuration['thisConfig']['proc.']['entryHTMLparser_db.']['tags.']['img.']['allowedAttribs'] == '0'
+                               && $this->configuration['thisConfig']['proc.']['entryHTMLparser_db.']['tags.']['img.']['rmTagIfNoAttrib'] == '1'
+                       );
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
index 66d6116..18428e7 100644 (file)
@@ -31,13 +31,6 @@ class DefaultInline extends RteHtmlAreaApi {
        protected $pluginName = 'DefaultInline';
 
        /**
-        * Path to the skin file relative to the extension directory
-        *
-        * @var string
-        */
-       protected $relativePathToSkin = 'Resources/Public/Css/Skin/Plugins/default-inline.css';
-
-       /**
         * The comma-separated list of button names that the registered plugin is adding to the htmlArea RTE toolbar
         *
         * @var string
@@ -61,28 +54,10 @@ class DefaultInline extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
-       /**
-        * Return transformed content
-        *
-        * @param string $content: The content that is about to be sent to the RTE
-        * @return string the transformed content
-        */
-       public function transformContent($content) {
-               // Change the strong and em tags for gecko browsers
-               if ($this->htmlAreaRTE->client['browser'] == 'gecko') {
-                       // change <strong> to <b>
-                       $content = preg_replace('/<(\\/?)strong/i', '<$1b', $content);
-                       // change <em> to <i>
-                       $content = preg_replace('/<(\\/?)em([^b>]*>)/i', '<$1i$2', $content);
-               }
-               return $content;
-       }
-
 }
index 50ff787..9fb205c 100644 (file)
@@ -13,6 +13,7 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  *
  * The TYPO3 project - inspiring people to share!
  */
+
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
 
 /**
@@ -49,21 +50,10 @@ class DefaultLink extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
-               $button = 'link';
-               if (in_array($button, $this->toolbar) && $this->htmlAreaRTE->is_FE()) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . ']["buttons"]["' . $button . '"] = new Object();';
-                       }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.stripBaseUrl = true;';
-               }
-               return $registerRTEinJavascriptString;
+       public function buildJavascriptConfiguration() {
+               return '';
        }
 
 }
index fabdb17..70fe5ca 100644 (file)
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  */
 
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * Definition List plugin for htmlArea RTE
@@ -58,20 +57,20 @@ class DefinitionList extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               return (parent::main($parentObject) && $this->htmlAreaRTE->isPluginEnabled('BlockElements'));
+       public function main(array $configuration) {
+               return parent::main($configuration)
+                       && isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['BlockElements']);
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
index aac0086..420fdbb 100644 (file)
@@ -56,10 +56,9 @@ class EditElement extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
index 4054162..d36e9b1 100644 (file)
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  */
 
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * EditorMode plugin for htmlArea RTE
@@ -57,11 +56,11 @@ class EditorMode extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               parent::main($parentObject);
+       public function main(array $configuration) {
+               parent::main($configuration);
                // Do not disable this plugin even if the chMode button is disabled
                $this->pluginAddsButtons = FALSE;
                return TRUE;
index 04e901d..7ad7eb3 100644 (file)
@@ -49,10 +49,9 @@ class FindReplace extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
index 16ccb1e..dacdd52 100644 (file)
@@ -142,15 +142,13 @@ class InlineElements extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                if (in_array('formattext', $this->toolbar)) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.']['formattext.'])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.formattext = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.']['formattext.'])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.formattext = new Object();';
                        }
                        // Default inline elements
                        $hideItems = array();
@@ -159,25 +157,25 @@ class InlineElements extends RteHtmlAreaApi {
                        $prefixLabelWithTag = FALSE;
                        $postfixLabelWithTag = FALSE;
                        // Processing PageTSConfig
-                       if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['formattext.'])) {
+                       if (is_array($this->configuration['thisConfig']['buttons.']) && is_array($this->configuration['thisConfig']['buttons.']['formattext.'])) {
                                // Removing elements
-                               if ($this->thisConfig['buttons.']['formattext.']['removeItems']) {
-                                       $hideItems = GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList($this->thisConfig['buttons.']['formattext.']['removeItems']), TRUE);
+                               if ($this->configuration['thisConfig']['buttons.']['formattext.']['removeItems']) {
+                                       $hideItems = GeneralUtility::trimExplode(',', $this->cleanList($this->configuration['thisConfig']['buttons.']['formattext.']['removeItems']), TRUE);
                                }
                                // Restriction clause
-                               if ($this->thisConfig['buttons.']['formattext.']['restrictTo']) {
-                                       $restrictTo = GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList('none,' . $this->thisConfig['buttons.']['formattext.']['restrictTo']), TRUE);
-                               } elseif ($this->thisConfig['buttons.']['formattext.']['restrictToItems']) {
-                                       $restrictTo = GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList('none,' . $this->thisConfig['buttons.']['formattext.']['restrictToItems']), TRUE);
+                               if ($this->configuration['thisConfig']['buttons.']['formattext.']['restrictTo']) {
+                                       $restrictTo = GeneralUtility::trimExplode(',', $this->cleanList('none,' . $this->configuration['thisConfig']['buttons.']['formattext.']['restrictTo']), TRUE);
+                               } elseif ($this->configuration['thisConfig']['buttons.']['formattext.']['restrictToItems']) {
+                                       $restrictTo = GeneralUtility::trimExplode(',', $this->cleanList('none,' . $this->configuration['thisConfig']['buttons.']['formattext.']['restrictToItems']), TRUE);
                                }
                                // Elements order
-                               if ($this->thisConfig['buttons.']['formattext.']['orderItems']) {
-                                       $inlineElementsOrder = 'none,' . $this->thisConfig['buttons.']['formattext.']['orderItems'];
+                               if ($this->configuration['thisConfig']['buttons.']['formattext.']['orderItems']) {
+                                       $inlineElementsOrder = 'none,' . $this->configuration['thisConfig']['buttons.']['formattext.']['orderItems'];
                                }
-                               $prefixLabelWithTag = $this->thisConfig['buttons.']['formattext.']['prefixLabelWithTag'] ? TRUE : $prefixLabelWithTag;
-                               $postfixLabelWithTag = $this->thisConfig['buttons.']['formattext.']['postfixLabelWithTag'] ? TRUE : $postfixLabelWithTag;
+                               $prefixLabelWithTag = $this->configuration['thisConfig']['buttons.']['formattext.']['prefixLabelWithTag'] ? TRUE : $prefixLabelWithTag;
+                               $postfixLabelWithTag = $this->configuration['thisConfig']['buttons.']['formattext.']['postfixLabelWithTag'] ? TRUE : $postfixLabelWithTag;
                        }
-                       $inlineElementsOrder = array_diff(GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList($inlineElementsOrder), TRUE), $hideItems);
+                       $inlineElementsOrder = array_diff(GeneralUtility::trimExplode(',', $this->cleanList($inlineElementsOrder), TRUE), $hideItems);
                        if (!in_array('*', $restrictTo)) {
                                $inlineElementsOrder = array_intersect($inlineElementsOrder, $restrictTo);
                        }
@@ -191,7 +189,7 @@ class InlineElements extends RteHtmlAreaApi {
                        }
                        $first = array_shift($inlineElementsOptions);
                        // Sorting the options
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.']['formattext.']) || !$this->thisConfig['buttons.']['formattext.']['orderItems']) {
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.']['formattext.']) || !$this->configuration['thisConfig']['buttons.']['formattext.']['orderItems']) {
                                asort($inlineElementsOptions);
                        }
                        // Generating the javascript options
@@ -200,13 +198,9 @@ class InlineElements extends RteHtmlAreaApi {
                        foreach ($inlineElementsOptions as $item => $label) {
                                $JSInlineElements[] = array($label, $item);
                        }
-                       if ($this->htmlAreaRTE->is_FE()) {
-                               $GLOBALS['TSFE']->csConvObj->convArray($JSInlineElements, $this->htmlAreaRTE->OutputCharset, 'utf-8');
-                       }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.formattext.options = ' . json_encode($JSInlineElements) . ';';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.formattext.options = ' . json_encode($JSInlineElements) . ';';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
 }
index 45964f5..7f218d0 100644 (file)
@@ -49,10 +49,9 @@ class InsertSmiley extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
index 242ec1d..fd6b8c5 100644 (file)
@@ -14,10 +14,12 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  * The TYPO3 project - inspiring people to share!
  */
 
+use SJBR\StaticInfoTables\Utility\LocalizationUtility;
+use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
+use TYPO3\CMS\Core\Database\DatabaseConnection;
 
 /**
  * Language plugin for htmlArea RTE
@@ -55,28 +57,26 @@ class Language extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
+       public function main(array $configuration) {
                if (!ExtensionManagementUtility::isLoaded('static_info_tables')) {
                        $this->pluginButtons = GeneralUtility::rmFromList('language', $this->pluginButtons);
                }
-               return parent::main($parentObject);
+               return parent::main($configuration);
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                $button = 'language';
-               $registerRTEinJavascriptString = '';
-               if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = new Object();';
+               $jsArray = array();
+               if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = new Object();';
                }
                $languages = array(
                        'none' => $this->getLanguageService()->sL(
@@ -89,9 +89,8 @@ class Language extends RteHtmlAreaApi {
                        $languagesJSArray[] = array('text' => $key, 'value' => $value);
                }
                $languagesJSArray = json_encode(array('options' => $languagesJSArray));
-               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.dataUrl = "' . ($this->htmlAreaRTE->is_FE() && $GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . $this->htmlAreaRTE->writeTemporaryFile($button . '_' . $this->htmlAreaRTE->contentLanguageUid, 'js', $languagesJSArray) . '";';
-               return $registerRTEinJavascriptString;
+               $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.dataUrl = "' . $this->writeTemporaryFile($button . '_' . $this->configuration['contentLanguageUid'], 'js', $languagesJSArray) . '";';
+               return implode(LF, $jsArray);
        }
 
        /**
@@ -102,27 +101,32 @@ class Language extends RteHtmlAreaApi {
         *
         * @return array An array of names of languages
         */
-       public function getLanguages() {
+       protected function getLanguages() {
+               $databaseConnection = $this->getDatabaseConnection();
                $nameArray = array();
                if (ExtensionManagementUtility::isLoaded('static_info_tables')) {
                        $where = '1=1';
                        $table = 'static_languages';
-                       $lang = \SJBR\StaticInfoTables\Utility\LocalizationUtility::getCurrentLanguage();
-                       $titleFields = \SJBR\StaticInfoTables\Utility\LocalizationUtility::getLabelFields($table, $lang);
+                       $lang = LocalizationUtility::getCurrentLanguage();
+                       $titleFields = LocalizationUtility::getLabelFields($table, $lang);
                        $prefixedTitleFields = array();
                        foreach ($titleFields as $titleField) {
                                $prefixedTitleFields[] = $table . '.' . $titleField;
                        }
                        $labelFields = implode(',', $prefixedTitleFields);
                        // Restrict to certain languages
-                       if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['language.']) && isset($this->thisConfig['buttons.']['language.']['restrictToItems'])) {
-                               $languageList = implode('\',\'', GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_DB']->fullQuoteStr(strtoupper($this->thisConfig['buttons.']['language.']['restrictToItems']), $table)));
+                       if (is_array($this->configuration['thisConfig']['buttons.']) && is_array($this->configuration['thisConfig']['buttons.']['language.']) && isset($this->configuration['thisConfig']['buttons.']['language.']['restrictToItems'])) {
+                               $languageList = implode('\',\'', GeneralUtility::trimExplode(',', $databaseConnection->fullQuoteStr(strtoupper($this->configuration['thisConfig']['buttons.']['language.']['restrictToItems']), $table)));
                                $where .= ' AND ' . $table . '.lg_iso_2 IN (' . $languageList . ')';
                        }
-                       $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($table . '.lg_iso_2,' . $table . '.lg_country_iso_2,' . $labelFields, $table, $where . ' AND lg_constructed = 0 ' . ($this->htmlAreaRTE->is_FE() ? $GLOBALS['TSFE']->sys_page->enableFields($table) : \TYPO3\CMS\Backend\Utility\BackendUtility::BEenableFields($table) . \TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause($table)));
-                       $prefixLabelWithCode = (bool)$this->thisConfig['buttons.']['language.']['prefixLabelWithCode'];
-                       $postfixLabelWithCode = (bool)$this->thisConfig['buttons.']['language.']['postfixLabelWithCode'];
-                       while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+                       $res = $databaseConnection->exec_SELECTquery(
+                               $table . '.lg_iso_2,' . $table . '.lg_country_iso_2,' . $labelFields,
+                               $table,
+                               $where . ' AND lg_constructed = 0 ' . BackendUtility::BEenableFields($table) . BackendUtility::deleteClause($table)
+                       );
+                       $prefixLabelWithCode = (bool)$this->configuration['thisConfig']['buttons.']['language.']['prefixLabelWithCode'];
+                       $postfixLabelWithCode = (bool)$this->configuration['thisConfig']['buttons.']['language.']['postfixLabelWithCode'];
+                       while ($row = $databaseConnection->sql_fetch_assoc($res)) {
                                $code = strtolower($row['lg_iso_2']) . ($row['lg_country_iso_2'] ? '-' . strtoupper($row['lg_country_iso_2']) : '');
                                foreach ($titleFields as $titleField) {
                                        if ($row[$titleField]) {
@@ -131,7 +135,7 @@ class Language extends RteHtmlAreaApi {
                                        }
                                }
                        }
-                       $GLOBALS['TYPO3_DB']->sql_free_result($res);
+                       $databaseConnection->sql_free_result($res);
                        uasort($nameArray, 'strcoll');
                }
                return $nameArray;
@@ -151,4 +155,11 @@ class Language extends RteHtmlAreaApi {
                }
        }
 
+       /**
+        * @return DatabaseConnection
+        */
+       protected function getDatabaseConnection() {
+               return $GLOBALS['TYPO3_DB'];
+       }
+
 }
index a3a8d70..f309738 100644 (file)
@@ -50,25 +50,23 @@ class MicroDataSchema extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
                $schema = array(
                        'types' => array(),
                        'properties' => array()
                );
                // Parse configured schemas
-               if (is_array($this->thisConfig['schema.']) && is_array($this->thisConfig['schema.']['sources.'])) {
-                       foreach ($this->thisConfig['schema.']['sources.'] as $source) {
+               if (is_array($this->configuration['thisConfig']['schema.']) && is_array($this->configuration['thisConfig']['schema.']['sources.'])) {
+                       foreach ($this->configuration['thisConfig']['schema.']['sources.'] as $source) {
                                $fileName = trim($source);
                                $absolutePath = GeneralUtility::getFileAbsFileName($fileName);
                                // Fallback to default schema file if configured file does not exists or is of zero size
                                if (!$fileName || !file_exists($absolutePath) || !filesize($absolutePath)) {
                                        $fileName = 'EXT:' . $this->extensionKey . '/Resources/Public/Rdf/MicrodataSchema/SchemaOrgAll.rdf';
                                }
-                               $fileName = $this->htmlAreaRTE->getFullFileName($fileName);
+                               $fileName = $this->getFullFileName($fileName);
                                $rdf = GeneralUtility::getUrl($fileName);
                                if ($rdf) {
                                        $this->parseSchema($rdf, $schema);
@@ -83,13 +81,8 @@ class MicroDataSchema extends RteHtmlAreaApi {
                $noProperty = $languageService->sL('LLL:EXT:rtehtmlarea/Resources/Private/Language/Plugins/MicrodataSchema/locallang.xlf:No property');
                array_unshift($schema['types'], array('name' => 'none', 'label' => $noSchema));
                array_unshift($schema['properties'], array('name' => 'none', 'label' => $noProperty));
-               // Convert character set
-               if ($this->htmlAreaRTE->is_FE()) {
-                       $GLOBALS['TSFE']->csConvObj->convArray($schema, $this->htmlAreaRTE->outputCharset, 'utf-8');
-               }
                // Store json encoded array in temporary file
-               $registerRTEinJavascriptString = LF . TAB . 'RTEarea[editornumber].schemaUrl = "' . ($this->htmlAreaRTE->is_FE() && $GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . $this->htmlAreaRTE->writeTemporaryFile('schema_' . $this->htmlAreaRTE->language, 'js', json_encode($schema)) . '";';
-               return $registerRTEinJavascriptString;
+               return 'RTEarea[editornumber].schemaUrl = "' . $this->writeTemporaryFile('schema_' . $this->configuration['language'], 'js', json_encode($schema)) . '";';
        }
 
        /**
@@ -111,7 +104,6 @@ class MicroDataSchema extends RteHtmlAreaApi {
         * @return void
         */
        protected function parseSchema($string, &$schema) {
-               $resources = array();
                $types = array();
                $properties = array();
                // Load the document
@@ -120,7 +112,6 @@ class MicroDataSchema extends RteHtmlAreaApi {
                if ($document) {
                        // Scan resource descriptions
                        $items = $document->getElementsByTagName('Description');
-                       $itemsCount = $items->length;
                        foreach ($items as $item) {
                                $name = $item->getAttribute('rdf:about');
                                $type = $item->getElementsByTagName('type');
index 76026ca..54613a7 100644 (file)
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  */
 
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * Copy as Plain Text extension for htmlArea RTE
@@ -51,33 +50,31 @@ class Plaintext extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
+       public function main(array $configuration) {
                // Opera has no onPaste event to handle
-               return parent::main($parentObject) && $this->htmlAreaRTE->client['browser'] != 'opera';
+               return parent::main($configuration)
+                       && $this->configuration['client']['browser'] !== 'opera';
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                $button = 'pastebehaviour';
                // Get current TYPO3 User Setting, if available
                if (TYPO3_MODE === 'BE' && \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('setup') && is_array($GLOBALS['TYPO3_USER_SETTINGS']) && is_object($GLOBALS['BE_USER'])) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = new Object();';
                        }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.current = "' . (isset($GLOBALS['BE_USER']->uc['rteCleanPasteBehaviour']) ? $GLOBALS['BE_USER']->uc['rteCleanPasteBehaviour'] : 'plainText') . '";';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.current = "' . (isset($GLOBALS['BE_USER']->uc['rteCleanPasteBehaviour']) ? $GLOBALS['BE_USER']->uc['rteCleanPasteBehaviour'] : 'plainText') . '";';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
        /**
index f2d4018..bef37b9 100644 (file)
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  */
 
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * CharacterMap plugin for htmlArea RTE
index 9fbc32c..532f89d 100644 (file)
@@ -49,12 +49,10 @@ class RemoveFormat extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
-               return $registerRTEinJavascriptString;
+       public function buildJavascriptConfiguration() {
+               return '';
        }
 
 }
index 3e32618..cca676d 100644 (file)
@@ -16,7 +16,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
 
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * SelectFont extension for htmlArea RTE
@@ -87,55 +86,49 @@ class SelectFont extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               $enabled = parent::main($parentObject) && $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['allowStyleAttribute'];
-               if ($this->htmlAreaRTE->is_FE()) {
-                       $this->RTEProperties = $this->htmlAreaRTE->RTEsetup;
-               } else {
-                       $this->RTEProperties = $this->htmlAreaRTE->RTEsetup['properties'];
-               }
+       public function main(array $configuration) {
+               $enabled = parent::main($configuration) && $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['allowStyleAttribute'];
+               $this->RTEProperties = $this->configuration['RTEsetup']['properties'];
                return $enabled;
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                $pluginButtonsArray = GeneralUtility::trimExplode(',', $this->pluginButtons);
                // Process Page TSConfig configuration for each button
                foreach ($pluginButtonsArray as $buttonId) {
                        if (in_array($buttonId, $this->toolbar)) {
-                               $registerRTEinJavascriptString .= $this->buildJSFontItemsConfig($rteNumberPlaceholder, $buttonId);
+                               $jsArray[] = $this->buildJSFontItemsConfig($buttonId);
                        }
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
        /**
         * Return Javascript configuration of font faces
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @param string $buttonId: button id
         * @return string Javascript configuration of font faces
         */
-       protected function buildJSFontItemsConfig($rteNumberPlaceholder, $buttonId) {
-               $configureRTEInJavascriptString = '';
+       protected function buildJSFontItemsConfig($buttonId) {
+               $jsArray = array();
                $hideItems = '';
                $addItems = array();
                // Getting removal and addition configuration
-               if (is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.'][$buttonId . '.'])) {
-                       if ($this->thisConfig['buttons.'][$buttonId . '.']['removeItems']) {
-                               $hideItems = $this->thisConfig['buttons.'][$buttonId . '.']['removeItems'];
+               if (is_array($this->configuration['thisConfig']['buttons.']) && is_array($this->configuration['thisConfig']['buttons.'][$buttonId . '.'])) {
+                       if ($this->configuration['thisConfig']['buttons.'][$buttonId . '.']['removeItems']) {
+                               $hideItems = $this->configuration['thisConfig']['buttons.'][$buttonId . '.']['removeItems'];
                        }
-                       if ($this->thisConfig['buttons.'][$buttonId . '.']['addItems']) {
-                               $addItems = GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList($this->thisConfig['buttons.'][$buttonId . '.']['addItems']), TRUE);
+                       if ($this->configuration['thisConfig']['buttons.'][$buttonId . '.']['addItems']) {
+                               $addItems = GeneralUtility::trimExplode(',', $this->cleanList($this->configuration['thisConfig']['buttons.'][$buttonId . '.']['addItems']), TRUE);
                        }
                }
                $languageService = $this->getLanguageService();
@@ -155,7 +148,7 @@ class SelectFont extends RteHtmlAreaApi {
                        foreach ($this->defaultFont[$buttonId] as $name => $value) {
                                if (!GeneralUtility::inList($hideItems, strval(($index + 1)))) {
                                        $label = $languageService->sL('LLL:EXT:rtehtmlarea/Resources/Private/Language/Plugins/SelectFont/locallang.xlf:' . $name) ?: $name;
-                                       $items[$name] = array($label, $this->htmlAreaRTE->cleanList($value));
+                                       $items[$name] = array($label, $this->cleanList($value));
                                }
                                $index++;
                        }
@@ -165,33 +158,28 @@ class SelectFont extends RteHtmlAreaApi {
                        foreach ($this->RTEProperties[$buttonId == 'fontstyle' ? 'fonts.' : 'fontSizes.'] as $name => $conf) {
                                $name = substr($name, 0, -1);
                                if (in_array($name, $addItems)) {
-                                       $label = $this->htmlAreaRTE->getPageConfigLabel($conf['name'], 0);
-                                       $items[$name] = array($label, $this->htmlAreaRTE->cleanList($conf['value']));
+                                       $label = $this->getPageConfigLabel($conf['name']);
+                                       $items[$name] = array($label, $this->cleanList($conf['value']));
                                }
                        }
                }
                // Seting default item
-               if ($this->thisConfig['buttons.'][$buttonId . '.']['defaultItem'] && $items[$this->thisConfig['buttons.'][$buttonId . '.']['defaultItem']]) {
-                       $items['none'] = array($items[$this->thisConfig['buttons.'][$buttonId . '.']['defaultItem']][0], 'none');
-                       unset($items[$this->thisConfig['buttons.'][$buttonId . '.']['defaultItem']]);
+               if ($this->configuration['thisConfig']['buttons.'][$buttonId . '.']['defaultItem'] && $items[$this->configuration['thisConfig']['buttons.'][$buttonId . '.']['defaultItem']]) {
+                       $items['none'] = array($items[$this->configuration['thisConfig']['buttons.'][$buttonId . '.']['defaultItem']][0], 'none');
+                       unset($items[$this->configuration['thisConfig']['buttons.'][$buttonId . '.']['defaultItem']]);
                }
                // Setting the JS list of options
                $itemsJSArray = array();
                foreach ($items as $name => $option) {
                        $itemsJSArray[] = array('text' => $option[0], 'value' => $option[1]);
                }
-               if ($this->htmlAreaRTE->is_FE()) {
-                       $GLOBALS['TSFE']->csConvObj->convArray($itemsJSArray, $this->htmlAreaRTE->OutputCharset, 'utf-8');
-               }
                $itemsJSArray = json_encode(array('options' => $itemsJSArray));
                // Adding to button JS configuration
-               if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($buttonId . '.')])) {
-                       $configureRTEInJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $buttonId . ' = new Object();';
+               if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($buttonId . '.')])) {
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $buttonId . ' = new Object();';
                }
-               $configureRTEInJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $buttonId . '.dataUrl = "' . ($this->htmlAreaRTE->is_FE() && $GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . $this->htmlAreaRTE->writeTemporaryFile($buttonId . '_' . $this->htmlAreaRTE->contentLanguageUid, 'js', $itemsJSArray) . '";';
-               return $configureRTEInJavascriptString;
+               $jsArray[] = 'RTEarea[editornumber].buttons.' . $buttonId . '.dataUrl = "' . $this->writeTemporaryFile($buttonId . '_' . $this->configuration['contentLanguageUid'], 'js', $itemsJSArray) . '";';
+               return implode(LF, $jsArray);
        }
 
 }
index 88e9250..d32add1 100644 (file)
@@ -18,7 +18,6 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * Spell Checker plugin for htmlArea RTE
@@ -60,20 +59,25 @@ class Spellchecker extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               return parent::main($parentObject) && ExtensionManagementUtility::isLoaded('static_info_tables') && !in_array($this->htmlAreaRTE->language, GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->htmlAreaRTE->ID]['plugins'][$pluginName]['noSpellCheckLanguages'])) && ($this->htmlAreaRTE->contentCharset == 'iso-8859-1' || $this->htmlAreaRTE->contentCharset == 'utf-8');
+       public function main(array $configuration) {
+               return parent::main($configuration)
+                       && ExtensionManagementUtility::isLoaded('static_info_tables')
+                       && !in_array(
+                               $this->configuration['language'],
+                               GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['SpellChecker']['noSpellCheckLanguages'])
+                       );
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                $button = 'spellcheck';
                // Set the SpellChecker mode
                $spellCheckerMode = isset($GLOBALS['BE_USER']->userTS['options.']['HTMLAreaPspellMode']) ? trim($GLOBALS['BE_USER']->userTS['options.']['HTMLAreaPspellMode']) : 'normal';
@@ -81,26 +85,20 @@ class Spellchecker extends RteHtmlAreaApi {
                        $spellCheckerMode = 'normal';
                }
                // Set the use of personal dictionary
-               $enablePersonalDicts = $this->thisConfig['buttons.'][$button . '.']['enablePersonalDictionaries'] ? (isset($GLOBALS['BE_USER']->userTS['options.']['enablePersonalDicts']) && $GLOBALS['BE_USER']->userTS['options.']['enablePersonalDicts'] ? TRUE : FALSE) : FALSE;
-               if ($this->htmlAreaRTE->is_FE()) {
-                       $enablePersonalDicts = FALSE;
-               }
-               $registerRTEinJavascriptString = '';
+               $enablePersonalDicts = $this->configuration['thisConfig']['buttons.'][$button . '.']['enablePersonalDictionaries'] ? (isset($GLOBALS['BE_USER']->userTS['options.']['enablePersonalDicts']) && $GLOBALS['BE_USER']->userTS['options.']['enablePersonalDicts'] ? TRUE : FALSE) : FALSE;
                if (in_array($button, $this->toolbar)) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = new Object();';
                        }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.contentTypo3Language = "' . $this->htmlAreaRTE->contentTypo3Language . '";
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.contentISOLanguage = "' . $this->htmlAreaRTE->contentISOLanguage . '";
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.contentCharset = "' . $this->htmlAreaRTE->contentCharset . '";
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.spellCheckerMode = "' . $spellCheckerMode . '";
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.enablePersonalDicts = ' . ($enablePersonalDicts ? 'true' : 'false') . ';';
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.path = "' . ($this->htmlAreaRTE->is_FE() || $this->htmlAreaRTE->isFrontendEditActive() ? ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . 'index.php?eID=rtehtmlarea_spellchecker' : BackendUtility::getAjaxUrl('rtehtmlarea::spellchecker')) . '";';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.contentTypo3Language = "' . $this->configuration['contentTypo3Language'] . '";';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.contentISOLanguage = "' . $this->configuration['contentISOLanguage'] . '";';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.spellCheckerMode = "' . $spellCheckerMode . '";';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.enablePersonalDicts = ' . ($enablePersonalDicts ? 'true' : 'false') . ';';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.path = "' . ($this->isFrontend() || $this->isFrontendEditActive() ? ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . 'index.php?eID=rtehtmlarea_spellchecker' : BackendUtility::getAjaxUrl('rtehtmlarea::spellchecker')) . '";';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
+
+
 }
index 14b74e8..57ffd41 100644 (file)
@@ -16,7 +16,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
 
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * Table Operations extension for htmlArea RTE
@@ -79,13 +78,13 @@ class TableOperations extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               $available = parent::main($parentObject);
-               if ($this->htmlAreaRTE->client['browser'] == 'opera') {
-                       $this->thisConfig['hideTableOperationsInToolbar'] = 0;
+       public function main(array $configuration) {
+               $available = parent::main($configuration);
+               if ($this->configuration['client']['browser'] === 'opera') {
+                       $this->configuration['thisConfig']['hideTableOperationsInToolbar'] = 0;
                }
                return $available;
        }
@@ -93,16 +92,15 @@ class TableOperations extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins, in this case, JS configuration of block elements
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                if (in_array('table', $this->toolbar)) {
                        // Combining fieldset disablers as a list
                        $disabledFieldsets = array('Alignment', 'Borders', 'Color', 'Description', 'Layout', 'RowGroup', 'Spacing', 'Style');
                        foreach ($disabledFieldsets as $index => $fieldset) {
-                               if (!trim($this->thisConfig[('disable' . $fieldset . 'FieldsetInTableOperations')])) {
+                               if (!trim($this->configuration['thisConfig'][('disable' . $fieldset . 'FieldsetInTableOperations')])) {
                                        unset($disabledFieldsets[$index]);
                                }
                        }
@@ -112,24 +110,20 @@ class TableOperations extends RteHtmlAreaApi {
                                $dialogues = array('table', 'tableproperties', 'rowproperties', 'columnproperties', 'cellproperties');
                                foreach ($dialogues as $dialogue) {
                                        if (in_array($dialogue, $this->toolbar)) {
-                                               if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($dialogue . '.')])) {
-                                                       $registerRTEinJavascriptString .= '
-                                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $dialogue . ' = new Object();
-                                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $dialogue . '.removeFieldsets = "' . $disabledFieldsets . '";';
-                                               } elseif ($this->thisConfig['buttons.'][$dialogue . '.']['removeFieldsets']) {
-                                                       $registerRTEinJavascriptString .= '
-                                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $dialogue . '.removeFieldsets += ",' . $disabledFieldsets . '";';
+                                               if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($dialogue . '.')])) {
+                                                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $dialogue . ' = new Object();';
+                                                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $dialogue . '.removeFieldsets = "' . $disabledFieldsets . '";';
+                                               } elseif ($this->configuration['thisConfig']['buttons.'][$dialogue . '.']['removeFieldsets']) {
+                                                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $dialogue . '.removeFieldsets += ",' . $disabledFieldsets . '";';
                                                } else {
-                                                       $registerRTEinJavascriptString .= '
-                                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $dialogue . '.removeFieldsets = ",' . $disabledFieldsets . '";';
+                                                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $dialogue . '.removeFieldsets = ",' . $disabledFieldsets . '";';
                                                }
                                        }
                                }
                        }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].hideTableOperationsInToolbar = ' . (trim($this->thisConfig['hideTableOperationsInToolbar']) ? 'true' : 'false') . ';';
+                       $jsArray[] = 'RTEarea[editornumber].hideTableOperationsInToolbar = ' . (trim($this->configuration['thisConfig']['hideTableOperationsInToolbar']) ? 'true' : 'false') . ';';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
        /**
index cb22b99..0655048 100644 (file)
@@ -49,10 +49,9 @@ class TextIndicator extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
index d2e5863..984ba6a 100644 (file)
@@ -14,8 +14,8 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * TYPO3 Color plugin for htmlArea RTE
@@ -51,64 +51,43 @@ class Typo3Color extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               return parent::main($parentObject) && $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['allowStyleAttribute'];
-       }
-
-       /**
-        * Return JS configuration of the htmlArea plugins registered by the extension
-        *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
-        * @return string JS configuration for registered plugins
-        */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               // Process colors configuration
-               return $this->buildJSColorsConfig($rteNumberPlaceholder);
+       public function main(array $configuration) {
+               return parent::main($configuration)
+                       && $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['allowStyleAttribute'];
        }
 
        /**
         * Return Javascript configuration of colors
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string Javascript configuration of colors
         */
-       public function buildJSColorsConfig($rteNumberPlaceholder) {
-               if ($this->htmlAreaRTE->is_FE()) {
-                       $RTEProperties = $this->htmlAreaRTE->RTEsetup;
-               } else {
-                       $RTEProperties = $this->htmlAreaRTE->RTEsetup['properties'];
-               }
-               $configureRTEInJavascriptString = '';
-               $configureRTEInJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].disableColorPicker = ' . (trim($this->thisConfig['disableColorPicker']) ? 'true' : 'false') . ';';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
+               $jsArray[] = 'RTEarea[editornumber].disableColorPicker = ' . (trim($this->configuration['thisConfig']['disableColorPicker']) ? 'true' : 'false') . ';';
                // Building the array of configured colors
-               if (is_array($RTEProperties['colors.'])) {
-                       $HTMLAreaColorname = array();
-                       foreach ($RTEProperties['colors.'] as $colorName => $conf) {
+               $HTMLAreaColorName = array();
+               if (is_array($this->configuration['RTEsetup']['properties']['colors.'])) {
+                       foreach ($this->configuration['RTEsetup']['properties']['colors.'] as $colorName => $conf) {
                                $colorName = substr($colorName, 0, -1);
-                               $colorLabel = $this->htmlAreaRTE->getPageConfigLabel($conf['name'], 0);
-                               $HTMLAreaColorname[$colorName] = array($colorLabel, strtoupper(substr($conf['value'], 1, 6)));
+                               $colorLabel = $this->getPageConfigLabel($conf['name']);
+                               $HTMLAreaColorName[$colorName] = array($colorLabel, strtoupper(substr($conf['value'], 1, 6)));
                        }
                }
                // Setting the list of colors if specified in the RTE config
-               if ($this->thisConfig['colors']) {
-                       $HTMLAreaColors = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->htmlAreaRTE->cleanList($this->thisConfig['colors']));
+               if ($this->configuration['thisConfig']['colors']) {
+                       $HTMLAreaColors = GeneralUtility::trimExplode(',', $this->cleanList($this->configuration['thisConfig']['colors']));
                        $HTMLAreaJSColors = array();
                        foreach ($HTMLAreaColors as $colorName) {
-                               if ($HTMLAreaColorname[$colorName]) {
-                                       $HTMLAreaJSColors[] = $HTMLAreaColorname[$colorName];
+                               if ($HTMLAreaColorName[$colorName]) {
+                                       $HTMLAreaJSColors[] = $HTMLAreaColorName[$colorName];
                                }
                        }
-                       if ($this->htmlAreaRTE->is_FE()) {
-                               $GLOBALS['TSFE']->csConvObj->convArray($HTMLAreaJSColors, $this->htmlAreaRTE->OutputCharset, 'utf-8');
-                       }
-                       $configureRTEInJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].colors = ' . json_encode($HTMLAreaJSColors) . ';';
+                       $jsArray[] = 'RTEarea[editornumber].colors = ' . json_encode($HTMLAreaJSColors) . ';';
                }
-               return $configureRTEInJavascriptString;
+               return implode(LF, $jsArray);
        }
 
 }
index fcb376e..fdb07c8 100644 (file)
@@ -17,7 +17,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * TYPO3 HTML Parser extension for htmlArea RTE
@@ -52,33 +51,31 @@ class Typo3HtmlParser extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               return parent::main($parentObject) && $this->thisConfig['enableWordClean'] && is_array($this->thisConfig['enableWordClean.']['HTMLparser.']);
+       public function main(array $configuration) {
+               return parent::main($configuration)
+                       && $this->configuration['thisConfig']['enableWordClean']
+                       && is_array($this->configuration['thisConfig']['enableWordClean.']['HTMLparser.']);
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins, in this case, JS configuration of block elements
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                $button = 'cleanword';
                if (in_array($button, $this->toolbar)) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = new Object();';
                        }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.pathParseHtmlModule = ' .
-                               GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('rtehtmlarea_wizard_parse_html')) . ';
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.hotKey = "' . ($this->thisConfig['enableWordClean.']['hotKey'] ?: '0') . '";';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.pathParseHtmlModule = ' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('rtehtmlarea_wizard_parse_html')) . ';';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.hotKey = "' . ($this->configuration['thisConfig']['enableWordClean.']['hotKey'] ?: '0') . '";';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
        /**
index 76f6016..d5ee2ff 100644 (file)
@@ -17,7 +17,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * TYPO3 Image plugin for htmlArea RTE
@@ -52,36 +51,35 @@ class Typo3Image extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               $enabled = parent::main($parentObject);
+       public function main(array $configuration) {
                // Check if this should be enabled based on extension configuration and Page TSConfig
                // The 'Minimal' and 'Typical' default configurations include Page TSConfig that removes images on the way to the database
-               $enabled = $enabled && !($this->thisConfig['proc.']['entryHTMLparser_db.']['tags.']['img.']['allowedAttribs'] == '0' && $this->thisConfig['proc.']['entryHTMLparser_db.']['tags.']['img.']['rmTagIfNoAttrib'] == '1') && !$this->thisConfig['buttons.']['image.']['TYPO3Browser.']['disabled'];
-               return $enabled;
+               return parent::main($configuration)
+                       && !(
+                               $this->configuration['thisConfig']['proc.']['entryHTMLparser_db.']['tags.']['img.']['allowedAttribs'] == '0'
+                               && $this->configuration['thisConfig']['proc.']['entryHTMLparser_db.']['tags.']['img.']['rmTagIfNoAttrib'] == '1'
+                       )
+                       && !$this->configuration['thisConfig']['buttons.']['image.']['TYPO3Browser.']['disabled'];
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins, in this case, JS configuration of block elements
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                $button = 'image';
                if (in_array($button, $this->toolbar)) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . ']["buttons"]["' . $button . '"] = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                               $jsArray[] = 'RTEarea[editornumber]["buttons"]["' . $button . '"] = new Object();';
                        }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.pathImageModule = ' .
-                               GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('rtehtmlarea_wizard_select_image')) . ';';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.pathImageModule = ' .GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('rtehtmlarea_wizard_select_image')) . ';';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
 }
index 68ecd83..438f411 100644 (file)
@@ -17,7 +17,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
-use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase;
 
 /**
  * TYPO3Link plugin for htmlArea RTE
@@ -53,44 +52,34 @@ class Typo3Link extends RteHtmlAreaApi {
        /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               $enabled = parent::main($parentObject);
+       public function main(array $configuration) {
                // Check if this should be enabled based on Page TSConfig
-               return $enabled && !$this->thisConfig['buttons.']['link.']['TYPO3Browser.']['disabled'];
+               return parent::main($configuration)
+                       && !$this->configuration['thisConfig']['buttons.']['link.']['TYPO3Browser.']['disabled'];
        }
 
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins, in this case, JS configuration of block elements
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                $button = 'link';
                if (in_array($button, $this->toolbar)) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = new Object();';
                        }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.pathLinkModule = ' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('rtehtmlarea_wizard_browse_links')) . ';';
-                       if ($this->htmlAreaRTE->is_FE()) {
-                               $RTEProperties = $this->htmlAreaRTE->RTEsetup;
-                       } else {
-                               $RTEProperties = $this->htmlAreaRTE->RTEsetup['properties'];
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.pathLinkModule = ' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('rtehtmlarea_wizard_browse_links')) . ';';
+                       if (is_array($this->configuration['RTEsetup']['properties']['classesAnchor.'])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.classesAnchorUrl = "' . $this->writeTemporaryFile('classesAnchor_' . $this->configuration['contentLanguageUid'], 'js', $this->buildJSClassesAnchorArray()) . '";';
                        }
-                       if (is_array($RTEProperties['classesAnchor.'])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.classesAnchorUrl = "' . $this->htmlAreaRTE->writeTemporaryFile('classesAnchor_' . $this->htmlAreaRTE->contentLanguageUid, 'js', $this->buildJSClassesAnchorArray()) . '";';
-                       }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.additionalAttributes = "data-htmlarea-external' . ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extensionKey]['plugins'][$this->pluginName]['additionalAttributes'] ? ',' . $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extensionKey]['plugins'][$this->pluginName]['additionalAttributes'] : '') . '";';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.additionalAttributes = "data-htmlarea-external' . ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extensionKey]['plugins'][$this->pluginName]['additionalAttributes'] ? ',' . $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extensionKey]['plugins'][$this->pluginName]['additionalAttributes'] : '') . '";';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
        /**
@@ -99,9 +88,9 @@ class Typo3Link extends RteHtmlAreaApi {
         * @return string classesAnchor array definition
         */
        public function buildJSClassesAnchorArray() {
-               $JSClassesAnchorArray .= 'HTMLArea.classesAnchorSetup = [ ' . LF;
+               $JSClassesAnchorArray = 'HTMLArea.classesAnchorSetup = [ ' . LF;
                $classesAnchorIndex = 0;
-               foreach ($this->htmlAreaRTE->RTEsetup['properties']['classesAnchor.'] as $label => $conf) {
+               foreach ($this->configuration['RTEsetup']['properties']['classesAnchor.'] as $label => $conf) {
                        if (is_array($conf) && $conf['class']) {
                                $JSClassesAnchorArray .= ($classesAnchorIndex++ ? ',' : '') . ' { ' . LF;
                                $index = 0;
@@ -110,15 +99,15 @@ class Typo3Link extends RteHtmlAreaApi {
                                        $JSClassesAnchorArray .= ($index++ ? ',' : '') . 'type : "' . str_replace('"', '', str_replace('\'', '', $conf['type'])) . '"' . LF;
                                }
                                if (trim(str_replace('\'', '', str_replace('"', '', $conf['image'])))) {
-                                       $JSClassesAnchorArray .= ($index++ ? ',' : '') . 'image : "' . $this->htmlAreaRTE->siteURL . GeneralUtility::resolveBackPath((TYPO3_mainDir . $this->htmlAreaRTE->getFullFileName(trim(str_replace('\'', '', str_replace('"', '', $conf['image'])))))) . '"' . LF;
+                                       $JSClassesAnchorArray .= ($index++ ? ',' : '') . 'image : "' . GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . GeneralUtility::resolveBackPath((TYPO3_mainDir . $this->getFullFileName(trim(str_replace('\'', '', str_replace('"', '', $conf['image'])))))) . '"' . LF;
                                }
                                $JSClassesAnchorArray .= ($index++ ? ',' : '') . 'addIconAfterLink : ' . ($conf['addIconAfterLink'] ? 'true' : 'false') . LF;
                                if (trim($conf['altText'])) {
-                                       $string = $this->htmlAreaRTE->getLLContent(trim($conf['altText']));
+                                       $string = GeneralUtility::quoteJSvalue($this->getLanguageService()->sL(trim($conf['altText'])));
                                        $JSClassesAnchorArray .= ($index++ ? ',' : '') . 'altText : ' . str_replace('"', '\\"', str_replace('\\\'', '\'', $string)) . LF;
                                }
                                if (trim($conf['titleText'])) {
-                                       $string = $this->htmlAreaRTE->getLLContent(trim($conf['titleText']));
+                                       $string = GeneralUtility::quoteJSvalue($this->getLanguageService()->sL(trim($conf['titleText'])));
                                        $JSClassesAnchorArray .= ($index++ ? ',' : '') . 'titleText : ' . str_replace('"', '\\"', str_replace('\\\'', '\'', $string)) . LF;
                                }
                                if (trim($conf['target'])) {
index 4e0be09..2274851 100644 (file)
@@ -50,10 +50,9 @@ class UndoRedo extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
+       public function buildJavascriptConfiguration() {
                return '';
        }
 
index 0824ed0..75ebe4c 100644 (file)
@@ -51,22 +51,18 @@ class UserElements extends RteHtmlAreaApi {
        /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins, in this case, JS configuration of block elements
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                $button = 'user';
                if (in_array($button, $this->toolbar)) {
-                       if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                               $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = new Object();';
+                       if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                               $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = new Object();';
                        }
-                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . '.pathUserModule = ' .
-                               GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('rtehtmlarea_wizard_user_elements')) . ';';
+                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . '.pathUserModule = ' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('rtehtmlarea_wizard_user_elements')) . ';';
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
 }
index e0fd308..e4a36cf 100644 (file)
@@ -17,10 +17,19 @@ namespace TYPO3\CMS\Rtehtmlarea\Form\Element;
 use TYPO3\CMS\Backend\Form\Element\AbstractFormElement;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Core\Utility\MathUtility;
-use TYPO3\CMS\Backend\Form\FormEngine;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
-use TYPO3\CMS\Backend\Form\NodeFactory;
+use TYPO3\CMS\Core\FrontendEditing\FrontendEditingController;
+use TYPO3\CMS\Core\Html\RteHtmlParser;
+use TYPO3\CMS\Core\Localization\Locales;
+use TYPO3\CMS\Core\Utility\ArrayUtility;
+use TYPO3\CMS\Core\Utility\ClientUtility;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Backend\Form\InlineStackProcessor;
+use TYPO3\CMS\Core\Database\DatabaseConnection;
+use TYPO3\CMS\Core\Utility\MathUtility;
+use TYPO3\CMS\Lang\LanguageService;
+use TYPO3\CMS\Core\Page\PageRenderer;
+use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi;
 
 /**
  * Render rich text editor in FormEngine
@@ -28,6 +37,174 @@ use TYPO3\CMS\Backend\Form\NodeFactory;
 class RichTextElement extends AbstractFormElement {
 
        /**
+        * Main result array as defined in initializeResultArray() of AbstractNode
+        *
+        * @var array
+        */
+       protected $resultArray;
+
+       /**
+        * pid of page record the TSconfig is located at.
+        * This is pid of record if table is not pages, or uid if table is pages
+        *
+        * @var int
+        */
+       protected $pidOfPageRecord;
+
+       /**
+        * pid of fixed versioned record.
+        * This is the pid of the record in normal cases, but is changed to the pid
+        * of the "mother" record in case the handled record is a versioned overlay
+        * and "mother" is located at a different pid.
+        *
+        * @var int
+        */
+       protected $pidOfVersionedMotherRecord;
+
+       /**
+        * Native, not further processed TsConfig of RTE section for this record on given pid.
+        *
+        * Example:
+        *
+        * RTE = foo
+        * RTE.bar = xy
+        *
+        * array(
+        *      'value' => 'foo',
+        *      'properties' => array(
+        *              'bar' => 'xy',
+        *      ),
+        * );
+        *
+        * @var array
+        */
+       protected $vanillaRteTsConfig;
+
+       /**
+        * Based on $vanillaRteTsConfig, this property contains "processed" configuration
+        * where table and type specific RTE setup is merged into 'default.' array.
+        *
+        * @var array
+        */
+       protected $processedRteConfiguration;
+
+       /**
+        * An unique identifier based on field name to have id attributes in HTML referenced in javascript.
+        *
+        * @var string
+        */
+       protected $domIdentifier;
+
+       /**
+        * Parsed "defaultExtras" TCA
+        *
+        * @var array
+        */
+       protected $defaultExtras;
+
+       /**
+        * Some client info containing "user agent", "browser", "version", "system"
+        *
+        * @var array
+        */
+       protected $client;
+
+       /**
+        * Selected language
+        *
+        * @var string
+        */
+       protected $language;
+
+       /**
+        * TYPO3 language code of the content language
+        *
+        * @var string
+        */
+       protected $contentTypo3Language;
+
+       /**
+        * ISO language code of the content language
+        *
+        * @var string
+        */
+       protected $contentISOLanguage;
+
+       /**
+        * Uid of chosen content language
+        *
+        * @var int
+        */
+       protected $contentLanguageUid;
+
+       /**
+        * The order of the toolbar: the name is the TYPO3-button name
+        *
+        * @var string
+        */
+       protected $defaultToolbarOrder;
+
+       /**
+        * Conversion array: TYPO3 button names to htmlArea button names
+        *
+        * @var array
+        */
+       protected $convertToolbarForHtmlAreaArray = array(
+               'space' => 'space',
+               'bar' => 'separator',
+               'linebreak' => 'linebreak'
+       );
+
+       /**
+        * Final toolbar array
+        *
+        * @var array
+        */
+       protected $toolbar = array();
+
+       /**
+        * Save the buttons for the toolbar
+        *
+        * @var array
+        */
+       protected $toolbarOrderArray = array();
+
+       /**
+        * Plugin buttons
+        *
+        * @var array
+        */
+       protected $pluginButton = array();
+
+       /**
+        * Plugin labels
+        *
+        * @var array
+        */
+       protected $pluginLabel = array();
+
+       /**
+        * Array of plugin id's enabled in the current RTE editing area
+        *
+        * @var array
+        */
+       protected $pluginEnabledArray = array();
+
+       /**
+        * Cumulative array of plugin id's enabled so far in any of the RTE editing areas of the form
+        *
+        * @var array
+        */
+       protected $pluginEnabledCumulativeArray = array();
+
+       /**
+        * Array of registered plugins indexed by their plugin Id's
+        *
+        * @var array
+        */
+       protected $registeredPlugins = array();
+
+       /**
         * This will render a <textarea> OR RTE area form field,
         * possibly with various control/validation features
         *
@@ -38,69 +215,1128 @@ class RichTextElement extends AbstractFormElement {
                $fieldName = $this->globalOptions['fieldName'];
                $row = $this->globalOptions['databaseRow'];
                $parameterArray = $this->globalOptions['parameterArray'];
-               $resultArray = $this->initializeResultArray();
-               $backendUser = $this->getBackendUserAuthentication();
-
-               $validationConfig = array();
 
-               // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. Traditionally, this is where RTE configuration has been found.
-               $specialConfiguration = BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras']);
-               // Setting up the altItem form field, which is a hidden field containing the value
-               $altItem = '<input type="hidden" name="' . htmlspecialchars($parameterArray['itemFormElName']) . '" value="' . htmlspecialchars($parameterArray['itemFormElValue']) . '" />';
+               $backendUser = $this->getBackendUserAuthentication();
+               $pageRenderer = $this->getPageRenderer();
 
+               $this->resultArray = $this->initializeResultArray();
+               $this->defaultExtras = BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras']);
+               $this->pidOfPageRecord = $table === 'pages' && MathUtility::canBeInterpretedAsInteger($row['uid']) ? (int)$row['uid'] : (int)$row['pid'];
                BackendUtility::fixVersioningPid($table, $row);
-               list($recordPid, $tsConfigPid) = BackendUtility::getTSCpidCached($table, $row['uid'], $row['pid']);
-
-               // If the pid-value is not negative (that is, a pid could NOT be fetched)
-               $rteSetup = $backendUser->getTSConfig('RTE', BackendUtility::getPagesTSconfig($recordPid));
-               $rteTcaTypeValue = BackendUtility::getTCAtypeValue($table, $row);
-               $rteSetupConfiguration = BackendUtility::RTEsetup($rteSetup['properties'], $table, $fieldName, $rteTcaTypeValue);
-
-               // Get RTE object, draw form and set flag:
-               $rteObject = BackendUtility::RTEgetObj();
-               $dummyFormEngine = new FormEngine();
-               $rteResult = $rteObject->drawRTE(
-                       $dummyFormEngine,
+               $this->pidOfVersionedMotherRecord = (int)$row['pid'];
+               $this->vanillaRteTsConfig = $backendUser->getTSConfig('RTE', BackendUtility::getPagesTSconfig($this->pidOfPageRecord));
+               $this->processedRteConfiguration = BackendUtility::RTEsetup(
+                       $this->vanillaRteTsConfig['properties'],
                        $table,
                        $fieldName,
-                       $row,
-                       $parameterArray,
-                       $specialConfiguration,
-                       $rteSetupConfiguration,
-                       $rteTcaTypeValue,
-                       '',
-                       $tsConfigPid,
-                       $this->globalOptions,
-                       $this->initializeResultArray(),
-                       $this->getValidationDataAsDataAttribute($validationConfig)
+                       $this->globalOptions['recordTypeValue']
                );
-               // This is a compat layer for "other" RTE's: If the result is not an array, it is the html string,
-               // otherwise it is a structure similar to our casual return array
-               // @todo: This interface needs a full re-definition, RTE should probably be its own type in the
-               // @todo: end, and other RTE implementations could then just override this.
-               if (is_array($rteResult)) {
-                       $html = $rteResult['html'];
-                       $rteResult['html'] = '';
-                       $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $rteResult);
-               } else {
-                       $html = $rteResult;
-               }
+               $this->client = $this->clientInfo();
+               $this->domIdentifier = preg_replace('/[^a-zA-Z0-9_:.-]/', '_', $parameterArray['itemFormElName']);
+               $this->domIdentifier = htmlspecialchars(preg_replace('/^[^a-zA-Z]/', 'x', $this->domIdentifier));
+
+               $this->initializeLanguageRelatedProperties();
+
+               // Get skin file name from Page TSConfig if any
+               $skinFilename = trim($this->processedRteConfiguration['skin']) ?: 'EXT:rtehtmlarea/Resources/Public/Css/Skin/htmlarea.css';
+               $skinFilename = $this->getFullFileName($skinFilename);
+               $skinDirectory = dirname($skinFilename);
+               // jQuery UI Resizable style sheet and main skin stylesheet
+               $this->resultArray['additionalHeadTags'][] = '<link rel="stylesheet" type="text/css" href="' . $skinDirectory . '/jquery-ui-resizable.css' . '" />';
+               $this->resultArray['additionalHeadTags'][] = '<link rel="stylesheet" type="text/css" href="' . $skinFilename . '" />';
+
+               $this->enableRegisteredPlugins();
+
+               // Configure toolbar
+               $this->setToolbar();
+
+               // Check if some plugins need to be disabled
+               $this->setPlugins();
+
+               // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
+               $this->pluginEnabledCumulativeArray = $this->pluginEnabledArray;
+
+
+               $this->addInstanceJavaScriptRegistration();
+
+               $this->addOnSubmitJavaScriptCode();
+
+               // Add TYPO3 notifications JavaScript
+               $pageRenderer->addJsFile('sysext/backend/Resources/Public/JavaScript/notifications.js');
+               // Add RTE JavaScript
+               $this->addRteJsFiles();
+               $pageRenderer->addJsFile($this->createJavaScriptLanguageLabelsFromFiles());
+               $pageRenderer->addJsInlineCode('HTMLArea-init', $this->getRteInitJsCode(), TRUE);
 
-               // Wizard
-               $html = $this->renderWizards(
-                       array($html, $altItem),
+               $html = $this->getMainHtml();
+
+               $this->resultArray['html'] = $this->renderWizards(
+                       array(
+                               $html,
+                               '<input type="hidden" name="' . htmlspecialchars($parameterArray['itemFormElName']) . '" value="' . htmlspecialchars($parameterArray['itemFormElValue']) . '" />',
+                       ),
                        $parameterArray['fieldConf']['config']['wizards'],
                        $table,
                        $row,
                        $fieldName,
                        $parameterArray,
                        $parameterArray['itemFormElName'],
-                       $specialConfiguration,
+                       $this->defaultExtras,
                        TRUE
                );
 
-               $resultArray['html'] = $html;
-               return $resultArray;
+               return $this->resultArray;
+       }
+
+       /**
+        * Create main HTML elements
+        *
+        * @return string Main RTE html
+        */
+       protected function getMainHtml() {
+               $backendUser = $this->getBackendUserAuthentication();
+
+               if ($this->isInFullScreenMode()) {
+                       $width = '100%';
+                       $height = '100%';
+                       $paddingRight = '0px';
+                       $editorWrapWidth = '100%';
+               } else {
+                       $options = $backendUser->userTS['options.'];
+                       $width = 530 + (isset($options['RTELargeWidthIncrement']) ? (int)$options['RTELargeWidthIncrement'] : 150);
+                       /** @var InlineStackProcessor  $inlineStackProcessor */
+                       $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
+                       $inlineStackProcessor->initializeByGivenStructure($this->globalOptions['inlineStructure']);
+                       $inlineStructureDepth = $inlineStackProcessor->getStructureDepth();
+                       $width -= $inlineStructureDepth > 0 ? ($inlineStructureDepth + 1) * 12 : 0;
+                       $widthOverride = isset($backendUser->uc['rteWidth']) && trim($backendUser->uc['rteWidth']) ?: trim($this->processedRteConfiguration['RTEWidthOverride']);
+                       if ($widthOverride) {
+                               if (strstr($widthOverride, '%')) {
+                                       if ($this->client['browser'] !== 'msie') {
+                                               $width = (int)$widthOverride > 0 ? (int)$widthOverride : '100%';
+                                       }
+                               } else {
+                                       $width = (int)$widthOverride > 0 ? (int)$widthOverride : $width;
+                               }
+                       }
+                       $width = strstr($width, '%') ? $width : $width . 'px';
+                       $height = 380 + (isset($options['RTELargeHeightIncrement']) ? (int)$options['RTELargeHeightIncrement'] : 0);
+                       $heightOverride = isset($backendUser->uc['rteHeight']) && (int)$backendUser->uc['rteHeight'] ?: (int)$this->processedRteConfiguration['RTEHeightOverride'];
+                       $height = $heightOverride > 0 ? $heightOverride . 'px' : $height . 'px';
+                       $paddingRight = '2';
+                       $editorWrapWidth = '99%';
+               }
+               $rteDivStyle = 'position:relative; left:0px; top:0px; height:' . $height . '; width:' . $width . '; border: 1px solid black; padding: 2 ' . $paddingRight . ' 2 2;';
+
+               $itemFormElementName = $this->globalOptions['parameterArray']['itemFormElName'];
+
+               // This seems to result in:
+               //      _TRANSFORM_bodytext (the handled field name) in case the field is a direct DB field
+               //      _TRANSFORM_vDEF (constant string) in case the RTE is within a flex form
+               $triggerFieldName = preg_replace('/\\[([^]]+)\\]$/', '[_TRANSFORM_\\1]', $itemFormElementName);
+
+               $value = $this->transformDatabaseContentToEditor($this->globalOptions['parameterArray']['itemFormElValue']);
+
+               $result = array();
+               // The hidden field tells the DataHandler that processing should be done on this value.
+               $result[] = '<input type="hidden" name="' . htmlspecialchars($triggerFieldName) . '" value="RTE" />';
+               $result[] = '<div id="pleasewait' . $this->domIdentifier . '" class="pleasewait" style="display: block;" >';
+               $result[] =     $this->getLanguageService()->sL('LLL:EXT:rtehtmlarea/locallang.xlf:Please wait');
+               $result[] = '</div>';
+               $result[] = '<div id="editorWrap' . $this->domIdentifier . '" class="editorWrap" style="visibility: hidden; width:' . $editorWrapWidth . '; height:100%;">';
+               $result[] =     '<textarea id="RTEarea' . $this->domIdentifier . '" name="' . htmlspecialchars($itemFormElementName) . '" rows="0" cols="0" style="' . htmlspecialchars($rteDivStyle) . '">';
+               $result[] =             GeneralUtility::formatForTextarea($value);
+               $result[] =     '</textarea>';
+               $result[] = '</div>';
+
+               return implode(LF, $result);
+       }
+
+       /**
+        * Add registered plugins to the array of enabled plugins
+        *
+        * @return void
+        */
+       protected function enableRegisteredPlugins() {
+               // Traverse registered plugins
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins'])) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins'] as $pluginId => $pluginObjectConfiguration) {
+                               if (is_array($pluginObjectConfiguration) && isset($pluginObjectConfiguration['objectReference'])) {
+                                       /** @var RteHtmlAreaApi $plugin */
+                                       $plugin = GeneralUtility::makeInstance($pluginObjectConfiguration['objectReference']);
+                                       $configuration = array(
+                                               'language' => $this->language,
+                                               'contentTypo3Language' => $this->contentTypo3Language,
+                                               'contentISOLanguage' => $this->contentISOLanguage,
+                                               'contentLanguageUid' => $this->contentLanguageUid,
+                                               'RTEsetup' => $this->vanillaRteTsConfig,
+                                               'client' => $this->client,
+                                               'thisConfig' => $this->processedRteConfiguration,
+                                               'specConf' => $this->defaultExtras,
+                                       );
+                                       if ($plugin->main($configuration)) {
+                                               $this->registeredPlugins[$pluginId] = $plugin;
+                                               // Override buttons from previously registered plugins
+                                               $pluginButtons = GeneralUtility::trimExplode(',', $plugin->getPluginButtons(), TRUE);
+                                               foreach ($this->pluginButton as $previousPluginId => $buttonList) {
+                                                       $this->pluginButton[$previousPluginId] = implode(',', array_diff(GeneralUtility::trimExplode(',', $this->pluginButton[$previousPluginId], TRUE), $pluginButtons));
+                                               }
+                                               $this->pluginButton[$pluginId] = $plugin->getPluginButtons();
+                                               $pluginLabels = GeneralUtility::trimExplode(',', $plugin->getPluginLabels(), TRUE);
+                                               foreach ($this->pluginLabel as $previousPluginId => $labelList) {
+                                                       $this->pluginLabel[$previousPluginId] = implode(',', array_diff(GeneralUtility::trimExplode(',', $this->pluginLabel[$previousPluginId], TRUE), $pluginLabels));
+                                               }
+                                               $this->pluginLabel[$pluginId] = $plugin->getPluginLabels();
+                                               $this->pluginEnabledArray[] = $pluginId;
+                                       }
+                               }
+                       }
+               }
+               // Process overrides
+               $hidePlugins = array();
+               foreach ($this->registeredPlugins as $pluginId => $plugin) {
+                       /** @var RteHtmlAreaApi $plugin */
+                       if ($plugin->addsButtons() && !$this->pluginButton[$pluginId]) {
+                               $hidePlugins[] = $pluginId;
+                       }
+               }
+               $this->pluginEnabledArray = array_unique(array_diff($this->pluginEnabledArray, $hidePlugins));
+       }
+
+       /**
+        * Set the toolbar config (only in this PHP-Object, not in JS):
+        *
+        * @return void
+        */
+       protected function setToolbar() {
+               $backendUser = $this->getBackendUserAuthentication();
+
+               if ($this->client['browser'] === 'msie' || $this->client['browser'] === 'opera') {
+                       $this->processedRteConfiguration['keepButtonGroupTogether'] = 0;
+               }
+               $this->defaultToolbarOrder = 'bar, blockstylelabel, blockstyle, textstylelabel, textstyle, linebreak,
+                       bar, formattext, bold,  strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code,'
+                               . 'definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span,
+                       bar, fontstyle, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, line,
+                       bar, left, center, right, justifyfull,
+                       bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent,
+                       bar, language, showlanguagemarks,lefttoright, righttoleft,
+                       bar, textcolor, bgcolor, textindicator,
+                       bar, editelement, showmicrodata,
+                       bar, image, emoticon, insertcharacter, insertsofthyphen, abbreviation, user,
+                       bar, link, unlink,
+                       bar, table,'
+                               . ($this->processedRteConfiguration['hideTableOperationsInToolbar']
+                                       && is_array($this->processedRteConfiguration['buttons.'])
+                                       && is_array($this->processedRteConfiguration['buttons.']['toggleborders.'])
+                                       && $this->processedRteConfiguration['buttons.']['toggleborders.']['keepInToolbar'] ? ' toggleborders,' : '')
+                       . 'bar, findreplace, spellcheck,
+                       bar, chMode, inserttag, removeformat, bar, copy, cut, paste, pastetoggle, pastebehaviour, bar, undo, redo, bar, about, linebreak,'
+                       . ($this->processedRteConfiguration['hideTableOperationsInToolbar'] ? '' : 'bar, toggleborders,')
+                       . ' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
+                       columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
+                       cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
+
+               // Additional buttons from registered plugins
+               foreach ($this->registeredPlugins as $pluginId => $plugin) {
+                       /** @var RteHtmlAreaApi $plugin */
+                       if ($this->isPluginEnabled($pluginId)) {
+                               $pluginButtons = $plugin->getPluginButtons();
+                               //Add only buttons not yet in the default toolbar order
+                               $addButtons = implode(
+                                       ',',
+                                       array_diff(
+                                               GeneralUtility::trimExplode(',', $pluginButtons, TRUE),
+                                               GeneralUtility::trimExplode(',', $this->defaultToolbarOrder, TRUE)
+                                       )
+                               );
+                               $this->defaultToolbarOrder = ($addButtons ? 'bar,' . $addButtons . ',linebreak,' : '') . $this->defaultToolbarOrder;
+                       }
+               }
+               $toolbarOrder = $this->processedRteConfiguration['toolbarOrder'] ?: $this->defaultToolbarOrder;
+               // Getting rid of undefined buttons
+               $this->toolbarOrderArray = array_intersect(GeneralUtility::trimExplode(',', $toolbarOrder, TRUE), GeneralUtility::trimExplode(',', $this->defaultToolbarOrder, TRUE));
+               $toolbarOrder = array_unique(array_values($this->toolbarOrderArray));
+               // Fetching specConf for field from backend
+               $pList = is_array($this->defaultExtras['richtext']['parameters']) ? implode(',', $this->defaultExtras['richtext']['parameters']) : '';
+               if ($pList !== '*') {
+                       // If not all
+                       $show = is_array($this->defaultExtras['richtext']['parameters']) ? $this->defaultExtras['richtext']['parameters'] : array();
+                       if ($this->processedRteConfiguration['showButtons']) {
+                               if (!GeneralUtility::inList($this->processedRteConfiguration['showButtons'], '*')) {
+                                       $show = array_unique(array_merge($show, GeneralUtility::trimExplode(',', $this->processedRteConfiguration['showButtons'], TRUE)));
+                               } else {
+                                       $show = array_unique(array_merge($show, $toolbarOrder));
+                               }
+                       }
+                       if (is_array($this->processedRteConfiguration['showButtons.'])) {
+                               foreach ($this->processedRteConfiguration['showButtons.'] as $buttonId => $value) {
+                                       if ($value) {
+                                               $show[] = $buttonId;
+                                       }
+                               }
+                               $show = array_unique($show);
+                       }
+               } else {
+                       $show = $toolbarOrder;
+               }
+               $RTEkeyList = isset($backendUser->userTS['options.']['RTEkeyList']) ? $backendUser->userTS['options.']['RTEkeyList'] : '*';
+               if ($RTEkeyList !== '*') {
+                       // If not all
+                       $show = array_intersect($show, GeneralUtility::trimExplode(',', $RTEkeyList, TRUE));
+               }
+               // Hiding buttons of disabled plugins
+               $hideButtons = array('space', 'bar', 'linebreak');
+               foreach ($this->pluginButton as $pluginId => $buttonList) {
+                       if (!$this->isPluginEnabled($pluginId)) {
+                               $buttonArray = GeneralUtility::trimExplode(',', $buttonList, TRUE);
+                               foreach ($buttonArray as $button) {
+                                       $hideButtons[] = $button;
+                               }
+                       }
+               }
+               // Hiding labels of disabled plugins
+               foreach ($this->pluginLabel as $pluginId => $label) {
+                       if (!$this->isPluginEnabled($pluginId)) {
+                               $hideButtons[] = $label;
+                       }
+               }
+               // Hiding buttons
+               $show = array_diff($show, GeneralUtility::trimExplode(',', $this->processedRteConfiguration['hideButtons'], TRUE));
+               // Apply toolbar constraints from registered plugins
+               foreach ($this->registeredPlugins as $pluginId => $plugin) {
+                       if ($this->isPluginEnabled($pluginId) && method_exists($plugin, 'applyToolbarConstraints')) {
+                               $show = $plugin->applyToolbarConstraints($show);
+                       }
+               }
+               // Getting rid of the buttons for which we have no position
+               $show = array_intersect($show, $toolbarOrder);
+               foreach ($this->registeredPlugins as $pluginId => $plugin) {
+                       /** @var RteHtmlAreaApi $plugin */
+                       $plugin->setToolbar($show);
+               }
+               $this->toolbar = $show;
+       }
+
+       /**
+        * Disable some plugins
+        *
+        * @return void
+        */
+       protected function setPlugins() {
+               // Disabling a plugin that adds buttons if none of its buttons is in the toolbar
+               $hidePlugins = array();
+               foreach ($this->pluginButton as $pluginId => $buttonList) {
+                       /** @var RteHtmlAreaApi $plugin */
+                       $plugin = $this->registeredPlugins[$pluginId];
+                       if ($plugin->addsButtons()) {
+                               $showPlugin = FALSE;
+                               $buttonArray = GeneralUtility::trimExplode(',', $buttonList, TRUE);
+                               foreach ($buttonArray as $button) {
+                                       if (in_array($button, $this->toolbar)) {
+                                               $showPlugin = TRUE;
+                                       }
+                               }
+                               if (!$showPlugin) {
+                                       $hidePlugins[] = $pluginId;
+                               }
+                       }
+               }
+               $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
+               // Hiding labels of disabled plugins
+               $hideLabels = array();
+               foreach ($this->pluginLabel as $pluginId => $label) {
+                       if (!$this->isPluginEnabled($pluginId)) {
+                               $hideLabels[] = $label;
+                       }
+               }
+               $this->toolbar = array_diff($this->toolbar, $hideLabels);
+               // Adding plugins declared as prerequisites by enabled plugins
+               $requiredPlugins = array();
+               foreach ($this->registeredPlugins as $pluginId => $plugin) {
+                       /** @var RteHtmlAreaApi $plugin */
+                       if ($this->isPluginEnabled($pluginId)) {
+                               $requiredPlugins = array_merge($requiredPlugins, GeneralUtility::trimExplode(',', $plugin->getRequiredPlugins(), TRUE));
+                       }
+               }
+               $requiredPlugins = array_unique($requiredPlugins);
+               foreach ($requiredPlugins as $pluginId) {
+                       if (is_object($this->registeredPlugins[$pluginId]) && !$this->isPluginEnabled($pluginId)) {
+                               $this->pluginEnabledArray[] = $pluginId;
+                       }
+               }
+               $this->pluginEnabledArray = array_unique($this->pluginEnabledArray);
+               // Completing the toolbar conversion array for htmlArea
+               foreach ($this->registeredPlugins as $pluginId => $plugin) {
+                       /** @var RteHtmlAreaApi $plugin */
+                       if ($this->isPluginEnabled($pluginId)) {
+                               $this->convertToolbarForHtmlAreaArray = array_unique(array_merge($this->convertToolbarForHtmlAreaArray, $plugin->getConvertToolbarForHtmlAreaArray()));
+                       }
+               }
+       }
+
+       /**
+        * Add RTE main scripts and plugin scripts
+        *
+        * @return void
+        */
+       protected function addRteJsFiles() {
+               $pageRenderer = $this->getPageRenderer();
+               // Component files. Order is important.
+               $components = array(
+                       'Util/Wrap.open',
+                       'NameSpace/NameSpace',
+                       'UserAgent/UserAgent',
+                       'Util/Util',
+                       'Util/Color',
+                       'Util/Resizable',
+                       'Util/String',
+                       'Util/Tips',
+                       'Util/TYPO3',
+                       'Ajax/Ajax',
+                       'DOM/DOM',
+                       'Event/Event',
+                       'Event/KeyMap',
+                       'CSS/Parser',
+                       'DOM/BookMark',
+                       'DOM/Node',
+                       'DOM/Selection',
+                       'DOM/Walker',
+                       'Configuration/Config',
+                       'Toolbar/Button',
+                       'Toolbar/ToolbarText',
+                       'Toolbar/Select',
+                       'Extjs/ColorPalette',
+                       'Extjs/ux/ColorMenu',
+                       'Extjs/ux/ColorPaletteField',
+                       'LoremIpsum',
+                       'Plugin/Plugin'
+               );
+               $components2 = array(
+                       'Editor/Toolbar',
+                       'Editor/Iframe',
+                       'Editor/TextAreaContainer',
+                       'Editor/StatusBar',
+                       'Editor/Framework',
+                       'Editor/Editor',
+                       'HTMLArea',
+                       'Util/Wrap.close',
+               );
+               foreach ($components as $component) {
+                       $pageRenderer->addJsFile($this->getFullFileName('EXT:rtehtmlarea/Resources/Public/JavaScript/HTMLArea/' . $component . '.js'));
+               }
+               foreach ($this->pluginEnabledCumulativeArray as $pluginId) {
+                       /** @var RteHtmlAreaApi $plugin */
+                       $plugin = $this->registeredPlugins[$pluginId];
+                       $extensionKey = is_object($plugin) ? $plugin->getExtensionKey() : 'rtehtmlarea';
+                       $fileName = 'EXT:' . $extensionKey . '/Resources/Public/JavaScript/Plugins/' . $pluginId . '.js';
+                       $absolutePath = GeneralUtility::getFileAbsFileName($fileName);
+                       if (file_exists($absolutePath)) {
+                               $pageRenderer->addJsFile($this->getFullFileName($fileName));
+                       }
+               }
+               foreach ($components2 as $component) {
+                       $pageRenderer->addJsFile($this->getFullFileName('EXT:rtehtmlarea/Resources/Public/JavaScript/HTMLArea/' . $component . '.js'));
+               }
+       }
+
+       /**
+        * Return RTE initialization inline JavaScript code
+        *
+        * @return string RTE initialization inline JavaScript code
+        */
+       protected function getRteInitJsCode() {
+               $skinFilename = trim($this->processedRteConfiguration['skin']) ?: 'EXT:rtehtmlarea/Resources/Public/Css/Skin/htmlarea.css';
+               $skinFilename = $this->getFullFileName($skinFilename);
+               $skinDirectory = dirname($skinFilename);
+               // Editing area style sheet
+               $editedContentCSS = GeneralUtility::createVersionNumberedFilename($skinDirectory . '/htmlarea-edited-content.css');
+
+               return 'require(["TYPO3/CMS/Rtehtmlarea/HTMLArea/HTMLArea"], function (HTMLArea) {
+                       if (typeof RTEarea === "undefined") {
+                               RTEarea = new Object();
+                               RTEarea[0] = new Object();
+                               RTEarea[0].version = "' . $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['version'] . '";
+                               RTEarea[0].editorUrl = "' . ExtensionManagementUtility::extRelPath('rtehtmlarea') . '";
+                               RTEarea[0].editorSkin = "' . $skinDirectory . '/";
+                               RTEarea[0].editedContentCSS = "' . $editedContentCSS . '";
+                               RTEarea.init = function() {
+                                       if (typeof HTMLArea === "undefined" || !Ext.isReady) {
+                                               window.setTimeout(function () {
+                                                       RTEarea.init();
+                                               }, 10);
+                                       } else {
+                                               Ext.QuickTips.init();
+                                               HTMLArea.init();
+                                       }
+                               };
+                               RTEarea.initEditor = function(editorNumber) {
+                                       if (typeof HTMLArea === "undefined" || !HTMLArea.isReady) {
+                                               window.setTimeout(function () {
+                                                       RTEarea.initEditor(editorNumber);
+                                               }, 40);
+                                       } else {
+                                               HTMLArea.initEditor(editorNumber);
+                                       }
+                               };
+                       }
+                       RTEarea.init();
+               });';
+       }
+
+       /**
+        * Return the Javascript code for configuring the RTE
+        *
+        * @return void
+        */
+       protected function addInstanceJavaScriptRegistration() {
+               $backendUser = $this->getBackendUserAuthentication();
+
+               $jsArray = array();
+               $jsArray[] = 'if (typeof configureEditorInstance === "undefined") {';
+               $jsArray[] = '  configureEditorInstance = new Object();';
+               $jsArray[] = '}';
+               $jsArray[] = 'configureEditorInstance["' . $this->domIdentifier . '"] = function() {';
+               $jsArray[] = 'if (typeof RTEarea === "undefined" || typeof HTMLArea === "undefined") {';
+               $jsArray[] = '  window.setTimeout("configureEditorInstance[\'' . $this->domIdentifier . '\']();", 40);';
+               $jsArray[] = '} else {';
+               $jsArray[] = 'editornumber = "' . $this->domIdentifier . '";';
+               $jsArray[] = 'RTEarea[editornumber] = new Object();';
+               $jsArray[] = 'RTEarea[editornumber].RTEtsConfigParams = "&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams()) . '";';
+               $jsArray[] = 'RTEarea[editornumber].number = editornumber;';
+               $jsArray[] = 'RTEarea[editornumber].deleted = false;';
+               $jsArray[] = 'RTEarea[editornumber].textAreaId = "' . $this->domIdentifier . '";';
+               $jsArray[] = 'RTEarea[editornumber].id = "RTEarea" + editornumber;';
+               $jsArray[] = 'RTEarea[editornumber].RTEWidthOverride = "'
+                       . (isset($backendUser->uc['rteWidth']) && trim($backendUser->uc['rteWidth'])
+                               ? trim($backendUser->uc['rteWidth'])
+                               : trim($this->processedRteConfiguration['RTEWidthOverride'])) . '";';
+               $jsArray[] = 'RTEarea[editornumber].RTEHeightOverride = "'
+                       . (isset($backendUser->uc['rteHeight']) && (int)$backendUser->uc['rteHeight']
+                               ? (int)$backendUser->uc['rteHeight']
+                               : (int)$this->processedRteConfiguration['RTEHeightOverride']) . '";';
+               $jsArray[] = 'RTEarea[editornumber].resizable = '
+                       . (isset($backendUser->uc['rteResize']) && $backendUser->uc['rteResize']
+                               ? 'true;'
+                               : (trim($this->processedRteConfiguration['rteResize']) ? 'true;' : 'false;'));
+               $jsArray[] = 'RTEarea[editornumber].maxHeight = "'
+                       . (isset($backendUser->uc['rteMaxHeight']) && (int)$backendUser->uc['rteMaxHeight']
+                               ? trim($backendUser->uc['rteMaxHeight'])
+                               : ((int)$this->processedRteConfiguration['rteMaxHeight'] ?: '2000')) . '";';
+               $jsArray[] = 'RTEarea[editornumber].fullScreen = ' . ($this->isInFullScreenMode() ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].showStatusBar = ' . (trim($this->processedRteConfiguration['showStatusBar']) ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].enableWordClean = ' . (trim($this->processedRteConfiguration['enableWordClean']) ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].htmlRemoveComments = ' . (trim($this->processedRteConfiguration['removeComments']) ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].disableEnterParagraphs = ' . (trim($this->processedRteConfiguration['disableEnterParagraphs']) ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].disableObjectResizing = ' . (trim($this->processedRteConfiguration['disableObjectResizing']) ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].removeTrailingBR = ' . (trim($this->processedRteConfiguration['removeTrailingBR']) ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].useCSS = ' . (trim($this->processedRteConfiguration['useCSS']) ? 'true' : 'false') . ';';
+               $jsArray[] = 'RTEarea[editornumber].keepButtonGroupTogether = ' . (trim($this->processedRteConfiguration['keepButtonGroupTogether']) ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].disablePCexamples = ' . (trim($this->processedRteConfiguration['disablePCexamples']) ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].showTagFreeClasses = ' . (trim($this->processedRteConfiguration['showTagFreeClasses']) ? 'true;' : 'false;');
+               $jsArray[] = 'RTEarea[editornumber].tceformsNested = ' . (count($this->globalOptions) ? json_encode($this->globalOptions['tabAndInlineStack']) : '[]') . ';';
+               $jsArray[] = 'RTEarea[editornumber].dialogueWindows = new Object();';
+               if (isset($this->processedRteConfiguration['dialogueWindows.']['defaultPositionFromTop'])) {
+                       $jsArray[] = 'RTEarea[editornumber].dialogueWindows.positionFromTop = ' . (int)$this->processedRteConfiguration['dialogueWindows.']['defaultPositionFromTop'] . ';';
+               }
+               if (isset($this->processedRteConfiguration['dialogueWindows.']['defaultPositionFromLeft'])) {
+                       $jsArray[] = 'RTEarea[editornumber].dialogueWindows.positionFromLeft = ' . (int)$this->processedRteConfiguration['dialogueWindows.']['defaultPositionFromLeft'] . ';';
+               }
+               $jsArray[] = 'RTEarea[editornumber].sys_language_content = "' . $this->contentLanguageUid . '";';
+               $jsArray[] = 'RTEarea[editornumber].typo3ContentLanguage = "' . $this->contentTypo3Language . '";';
+               $jsArray[] = 'RTEarea[editornumber].userUid = "' . 'BE_' . $backendUser->user['uid'] . '";';
+
+               // Setting the plugin flags
+               $jsArray[] = 'RTEarea[editornumber].plugin = new Object();';
+               foreach ($this->pluginEnabledArray as $pluginId) {
+                       $jsArray[] = 'RTEarea[editornumber].plugin.' . $pluginId . ' = true;';
+               }
+
+               // Setting the buttons configuration
+               $jsArray[] = 'RTEarea[editornumber].buttons = new Object();';
+               if (is_array($this->processedRteConfiguration['buttons.'])) {
+                       foreach ($this->processedRteConfiguration['buttons.'] as $buttonIndex => $conf) {
+                               $button = substr($buttonIndex, 0, -1);
+                               if (is_array($conf)) {
+                                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = ' . $this->buildNestedJSArray($conf) . ';';
+                               }
+                       }
+               }
+
+               // Setting the list of tags to be removed if specified in the RTE config
+               if (trim($this->processedRteConfiguration['removeTags'])) {
+                       $jsArray[] = 'RTEarea[editornumber].htmlRemoveTags = /^(' . implode('|', GeneralUtility::trimExplode(',', $this->processedRteConfiguration['removeTags'], TRUE)) . ')$/i;';
+               }
+
+               // Setting the list of tags to be removed with their contents if specified in the RTE config
+               if (trim($this->processedRteConfiguration['removeTagsAndContents'])) {
+                       $jsArray[] = 'RTEarea[editornumber].htmlRemoveTagsAndContents = /^(' . implode('|', GeneralUtility::trimExplode(',', $this->processedRteConfiguration['removeTagsAndContents'], TRUE)) . ')$/i;';
+               }
+
+               // Setting array of custom tags if specified in the RTE config
+               if (!empty($this->processedRteConfiguration['customTags'])) {
+                       $customTags = GeneralUtility::trimExplode(',', $this->processedRteConfiguration['customTags'], TRUE);
+                       if (!empty($customTags)) {
+                               $jsArray[] = 'RTEarea[editornumber].customTags= ' . json_encode($customTags) . ';';
+                       }
+               }
+
+               // Setting array of content css files if specified in the RTE config
+               $versionNumberedFileNames = array();
+               $contentCssFileNames = $this->getContentCssFileNames();
+               foreach ($contentCssFileNames as $contentCssFileName) {
+                       $versionNumberedFileNames[] = GeneralUtility::createVersionNumberedFilename($contentCssFileName);
+               }
+               $jsArray[] = 'RTEarea[editornumber].pageStyle = ["' . implode('","', $versionNumberedFileNames) . '"];';
+
+               $jsArray[] = 'RTEarea[editornumber].classesUrl = "' . $this->writeTemporaryFile(('classes_' . $this->language), 'js', $this->buildJSClassesArray()) . '";';
+
+               // Add Javascript configuration for registered plugins
+               foreach ($this->registeredPlugins as $pluginId => $plugin) {
+                       /** @var RteHtmlAreaApi $plugin */
+                       if ($this->isPluginEnabled($pluginId)) {
+                               $jsPluginString = $plugin->buildJavascriptConfiguration();
+                               if ($jsPluginString) {
+                                       $jsArray[] = $plugin->buildJavascriptConfiguration();
+                               }
+                       }
+               }
+
+               // Avoid premature reference to HTMLArea when being initially loaded by IRRE Ajax call
+               $jsArray[] = 'RTEarea[editornumber].toolbar = ' . $this->getJSToolbarArray() . ';';
+               $jsArray[] = 'RTEarea[editornumber].convertButtonId = ' . json_encode(array_flip($this->convertToolbarForHtmlAreaArray)) . ';';
+               $jsArray[] = 'RTEarea.initEditor(editornumber);';
+               $jsArray[] = '}';
+               $jsArray[] = '}';
+               $jsArray[] = 'configureEditorInstance["' . $this->domIdentifier . '"]();';
+
+               $this->resultArray['additionalJavaScriptPost'][] =  implode(LF, $jsArray);
+       }
+
+       /**
+        * Get the name of the contentCSS files to use
+        *
+        * @return array An array of full file name of the content css files to use
+        */
+       protected function getContentCssFileNames() {
+               $contentCss = is_array($this->processedRteConfiguration['contentCSS.']) ? $this->processedRteConfiguration['contentCSS.'] : array();
+               if (isset($this->processedRteConfiguration['contentCSS'])) {
+                       $contentCss[] = trim($this->processedRteConfiguration['contentCSS']);
+               }
+               $contentCssFiles = array();
+               if (!empty($contentCss)) {
+                       foreach ($contentCss as $contentCssKey => $contentCssfile) {
+                               $fileName = trim($contentCssfile);
+                               $absolutePath = GeneralUtility::getFileAbsFileName($fileName);
+                               if (file_exists($absolutePath) && filesize($absolutePath)) {
+                                       $contentCssFiles[$contentCssKey] = $this->getFullFileName($fileName);
+                               }
+                       }
+               } else {
+                       // Fallback to default content css file if none of the configured files exists and is not empty
+                       $contentCssFiles['default'] = $this->getFullFileName('EXT:rtehtmlarea/Resources/Public/Css/ContentCss/Default.css');
+               }
+               return array_unique($contentCssFiles);
+       }
+
+       /**
+        * Return TRUE, if the plugin can be loaded
+        *
+        * @param string $pluginId: The identification string of the plugin
+        * @return bool TRUE if the plugin can be loaded
+        */
+       protected function isPluginEnabled($pluginId) {
+               return in_array($pluginId, $this->pluginEnabledArray);
+       }
+
+       /**
+        * Return JS arrays of classes configuration
+        *
+        * @return string JS classes arrays
+        */
+       protected function buildJSClassesArray() {
+               $RTEProperties = $this->vanillaRteTsConfig['properties'];
+               // Declare sub-arrays
+               $classesArray = array(
+                       'labels' => array(),
+                       'values' => array(),
+                       'noShow' => array(),
+                       'alternating' => array(),
+                       'counting' => array(),
+                       'selectable' => array(),
+                       'requires' => array(),
+                       'requiredBy' => array(),
+                       'XOR' => array()
+               );
+               $JSClassesArray = '';
+               // Scanning the list of classes if specified in the RTE config
+               if (is_array($RTEProperties['classes.'])) {
+                       foreach ($RTEProperties['classes.'] as $className => $conf) {
+                               $className = rtrim($className, '.');
+                               $label = $this->getLanguageService()->sL(trim($conf['name']));
+                               $label = str_replace('"', '\\"', str_replace('\\\'', '\'', $label));
+                               $classesArray['labels'][$className] = trim($conf['name']) ? $label : '';
+                               $classesArray['values'][$className] = str_replace('\\\'', '\'', $conf['value']);
+                               if (isset($conf['noShow'])) {
+                                       $classesArray['noShow'][$className] = $conf['noShow'];
+                               }
+                               if (is_array($conf['alternating.'])) {
+                                       $classesArray['alternating'][$className] = $conf['alternating.'];
+                               }
+                               if (is_array($conf['counting.'])) {
+                                       $classesArray['counting'][$className] = $conf['counting.'];
+                               }
+                               if (isset($conf['selectable'])) {
+                                       $classesArray['selectable'][$className] = $conf['selectable'];
+                               }
+                               if (isset($conf['requires'])) {
+                                       $classesArray['requires'][$className] = explode(',', GeneralUtility::rmFromList($className, $this->cleanList($conf['requires'])));
+                               }
+                       }
+                       // Remove circularities from classes dependencies
+                       $requiringClasses = array_keys($classesArray['requires']);
+                       foreach ($requiringClasses as $requiringClass) {
+                               if ($this->hasCircularDependency($classesArray, $requiringClass, $requiringClass)) {
+                                       unset($classesArray['requires'][$requiringClass]);
+                               }
+                       }
+                       // Reverse relationship for the dependency checks when removing styles
+                       $requiringClasses = array_keys($classesArray['requires']);
+                       foreach ($requiringClasses as $className) {
+                               foreach ($classesArray['requires'][$className] as $requiredClass) {
+                                       if (!is_array($classesArray['requiredBy'][$requiredClass])) {
+                                               $classesArray['requiredBy'][$requiredClass] = array();
+                                       }
+                                       if (!in_array($className, $classesArray['requiredBy'][$requiredClass])) {
+                                               $classesArray['requiredBy'][$requiredClass][] = $className;
+                                       }
+                               }
+                       }
+               }
+               // Scanning the list of sets of mutually exclusives classes if specified in the RTE config
+               if (is_array($RTEProperties['mutuallyExclusiveClasses.'])) {
+                       foreach ($RTEProperties['mutuallyExclusiveClasses.'] as $listName => $conf) {
+                               $classSet = GeneralUtility::trimExplode(',', $conf, TRUE);
+                               $classList = implode(',', $classSet);
+                               foreach ($classSet as $className) {
+                                       $classesArray['XOR'][$className] = '/^(' . implode('|', GeneralUtility::trimExplode(',', GeneralUtility::rmFromList($className, $classList), TRUE)) . ')$/';
+                               }
+                       }
+               }
+               foreach ($classesArray as $key => $subArray) {
+                       $JSClassesArray .= 'HTMLArea.classes' . ucfirst($key) . ' = ' . $this->buildNestedJSArray($subArray) . ';' . LF;
+               }
+               return $JSClassesArray;
+       }
+
+       /**
+        * Check for possible circularity in classes dependencies
+        *
+        * @param array $classesArray: reference to the array of classes dependencies
+        * @param string $requiringClass: class requiring at some iteration level from the initial requiring class
+        * @param string $initialClass: initial class from which a circular relationship is being searched
+        * @param int $recursionLevel: depth of recursive call
+        * @return boolean TRUE, if a circular relationship is found
+        */
+       protected function hasCircularDependency(&$classesArray, $requiringClass, $initialClass, $recursionLevel = 0) {
+               if (is_array($classesArray['requires'][$requiringClass])) {
+                       if (in_array($initialClass, $classesArray['requires'][$requiringClass])) {
+                               return TRUE;
+                       } else {
+                               if ($recursionLevel++ < 20) {
+                                       foreach ($classesArray['requires'][$requiringClass] as $requiringClass2) {
+                                               if ($this->hasCircularDependency($classesArray, $requiringClass2, $initialClass, $recursionLevel)) {
+                                                       return TRUE;
+                                               }
+                                       }
+                               }
+                               return FALSE;
+                       }
+               } else {
+                       return FALSE;
+               }
+       }
+
+       /**
+        * Translate Page TS Config array in JS nested array definition
+        * Replace 0 values with false
+        * Unquote regular expression values
+        * Replace empty arrays with empty objects
+        *
+        * @param array $conf: Page TSConfig configuration array
+        * @return string nested JS array definition
+        */
+       protected function buildNestedJSArray($conf) {
+               $convertedConf = GeneralUtility::removeDotsFromTS($conf);
+               return str_replace(
+                       array(':"0"', ':"\\/^(', ')$\\/i"', ':"\\/^(', ')$\\/"', '[]'),
+                       array(':false', ':/^(', ')$/i', ':/^(', ')$/', '{}'), json_encode($convertedConf)
+               );
+       }
+
+       /**
+        * Writes contents in a file in typo3temp and returns the file name
+        *
+        * @param string $label: A label to insert at the beginning of the name of the file
+        * @param string $fileExtension: The file extension of the file, defaulting to 'js'
+        * @param string $contents: The contents to write into the file
+        * @return string The name of the file written to typo3temp
+        * @throws \RuntimeException If writing to file failed
+        */
+       protected function writeTemporaryFile($label, $fileExtension = 'js', $contents = '') {
+               $relativeFilename = 'typo3temp/rtehtmlarea_' . str_replace('-', '_', $label) . '_' . GeneralUtility::shortMD5($contents, 20) . '.' . $fileExtension;
+               $destination = PATH_site . $relativeFilename;
+               if (!file_exists($destination)) {
+                       $minifiedJavaScript = '';
+                       if ($fileExtension === 'js' && $contents !== '') {
+                               $minifiedJavaScript = GeneralUtility::minifyJavaScript($contents);
+                       }
+                       $failure = GeneralUtility::writeFileToTypo3tempDir($destination, $minifiedJavaScript ? $minifiedJavaScript : $contents);
+                       if ($failure) {
+                               throw new \RuntimeException($failure, 1294585668);
+                       }
+               }
+               if (isset($GLOBALS['TSFE'])) {
+                       $fileName = $relativeFilename;
+               } else {
+                       $fileName = '../' . $relativeFilename;
+               }
+               return GeneralUtility::resolveBackPath($fileName);
+       }
+
+       /**
+        * Both rte framework and rte plugins can have label files that are
+        * used in JS. The methods gathers those and creates a JS object from
+        * file labels.
+        *
+        * @return string
+        */
+       protected function createJavaScriptLanguageLabelsFromFiles() {
+               $labelArray = array();
+               // Load labels of 3 base files into JS
+               foreach (array('tooltips', 'msg', 'dialogs') as $identifier) {
+                       $fileName = 'EXT:rtehtmlarea/Resources/Private/Language/locallang_' . $identifier . '.xlf';
+                       $newLabels = $this->getMergedLabelsFromFile($fileName);
+                       if (!empty($newLabels)) {
+                               $labelArray[$identifier] = $newLabels;
+                       }
+               }
+               // Load labels of plugins into JS
+               foreach ($this->pluginEnabledCumulativeArray as $pluginId) {
+                       /** @var RteHtmlAreaApi $plugin */
+                       $plugin = $this->registeredPlugins[$pluginId];
+                       $extensionKey = is_object($plugin) ? $plugin->getExtensionKey() : 'rtehtmlarea';
+                       $fileName = 'EXT:' . $extensionKey . '/Resources/Private/Language/Plugins/' . $pluginId . '/locallang_js.xlf';
+                       $newLabels = $this->getMergedLabelsFromFile($fileName);
+                       if (!empty($newLabels)) {
+                               $labelArray[$pluginId] = $newLabels;
+                       }
+               }
+               $javaScriptString = 'HTMLArea.I18N = new Object();' . LF;
+               $javaScriptString .= 'HTMLArea.I18N = ' . json_encode($labelArray);
+               return $this->writeTemporaryFile($this->language, 'js', $javaScriptString);
+       }
+
+       /**
+        * Get all labels from a specific label file, merge default
+        * labels and target language labels.
+        *
+        * @param string $fileName The file to merge labels from
+        * @return array Label keys and values
+        */
+       protected function getMergedLabelsFromFile($fileName) {
+               $localizationArray = GeneralUtility::readLLfile($fileName, $this->language, 'utf-8', 1);
+               if (is_array($localizationArray) && !empty($localizationArray)) {
+                       if (!empty($localizationArray[$this->language])) {
+                               $finalLocalLang = $localizationArray['default'];
+                               ArrayUtility::mergeRecursiveWithOverrule($finalLocalLang, $localizationArray[$this->language], TRUE, FALSE);
+                               $localizationArray[$this->language] = $finalLocalLang;
+                       } else {
+                               $localizationArray[$this->language] = $localizationArray['default'];
+                       }
+               } else {
+                       $localizationArray = array();
+               }
+               return $localizationArray[$this->language];
+       }
+
+       /**
+        * Return the JS code of the toolbar configuration for the HTMLArea editor
+        *
+        * @return string The JS code as nested JS arrays
+        */
+       protected function getJSToolbarArray() {
+               // The toolbar array
+               $toolbar = array();
+               // The current row;  a "linebreak" ends the current row
+               $row = array();
+               // The current group; each group is between "bar"s; a "linebreak" ends the current group
+               $group = array();
+               // Process each toolbar item in the toolbar order list
+               foreach ($this->toolbarOrderArray as $item) {
+                       switch ($item) {
+                               case 'linebreak':
+                                       // Add row to toolbar if not empty
+                                       if (!empty($group)) {
+                                               $row[] = $group;
+                                               $group = array();
+                                       }
+                                       if (!empty($row)) {
+                                               $toolbar[] = $row;
+                                               $row = array();
+                                       }
+                                       break;
+                               case 'bar':
+                                       // Add group to row if not empty
+                                       if (!empty($group)) {
+                                               $row[] = $group;
+                                               $group = array();
+                                       }
+                                       break;
+                               case 'space':
+                                       if (end($group) != $this->convertToolbarForHtmlAreaArray[$item]) {
+                                               $group[] = $this->convertToolbarForHtmlAreaArray[$item];
+                                       }
+                                       break;
+                               default:
+                                       if (in_array($item, $this->toolbar)) {
+                                               // Add the item to the group
+                                               $convertedItem = $this->convertToolbarForHtmlAreaArray[$item];
+                                               if ($convertedItem) {
+                                                       $group[] = $convertedItem;
+                                               }
+                                       }
+                       }
+               }
+               // Add the last group and last line, if not empty
+               if (!empty($group)) {
+                       $row[] = $group;
+               }
+               if (!empty($row)) {
+                       $toolbar[] = $row;
+               }
+               return json_encode($toolbar);
+       }
+
+       /**
+        * Make a file name relative to the PATH_site or to the PATH_typo3
+        *
+        * @param string $filename: a file name of the form EXT:.... or relative to the PATH_site
+        * @return string the file name relative to the PATH_site if in frontend or relative to the PATH_typo3 if in backend
+        */
+       protected function getFullFileName($filename) {
+               if (substr($filename, 0, 4) === 'EXT:') {
+                       // extension
+                       list($extKey, $local) = explode('/', substr($filename, 4), 2);
+                       $newFilename = '';
+                       if ((string)$extKey !== '' && ExtensionManagementUtility::isLoaded($extKey) && (string)$local !== '') {
+                               $newFilename = ($this->isFrontendEditActive()
+                                               ? ExtensionManagementUtility::siteRelPath($extKey)
+                                               : ExtensionManagementUtility::extRelPath($extKey))
+                                       . $local;
+                       }
+               } else {
+                       $path = ($this->isFrontendEditActive() ? '' : '../');
+                       $newFilename = $path . ($filename[0] === '/' ? substr($filename, 1) : $filename);
+               }
+               return GeneralUtility::resolveBackPath($newFilename);
+       }
+
+       /**
+        * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
+        *
+        * @return void
+        */
+       protected function addOnSubmitJavaScriptCode() {
+               $onSubmitCode = array();
+               $onSubmitCode[] = 'if (RTEarea["' . $this->domIdentifier . '"]) {';
+               $onSubmitCode[] =       'document.editform["' . $this->globalOptions['parameterArray']['itemFormElName'] . '"].value = RTEarea["' . $this->domIdentifier . '"].editor.getHTML();';
+               $onSubmitCode[] = '} else {';
+               $onSubmitCode[] =       'OK = 0;';
+               $onSubmitCode[] = '};';
+               $this->resultArray['additionalJavaScriptSubmit'][] = implode(LF, $onSubmitCode);
+       }
+
+       /**
+        * Checks if frontend editing is active.
+        *
+        * @return bool TRUE if frontend editing is active
+        */
+       protected function isFrontendEditActive() {
+               return is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->beUserLogin && $GLOBALS['BE_USER']->frontendEdit instanceof FrontendEditingController;
+       }
+
+       /**
+        * Client Browser Information
+        *
+        * @return array Contains keys "user agent", "browser", "version", "system"
+        */
+       protected function clientInfo() {
+               $userAgent = GeneralUtility::getIndpEnv('HTTP_USER_AGENT');
+               $browserInfo = ClientUtility::getBrowserInfo($userAgent);
+               // Known engines: order is not irrelevant!
+               $knownEngines = array('opera', 'msie', 'gecko', 'webkit');
+               if (is_array($browserInfo['all'])) {
+                       foreach ($knownEngines as $engine) {
+                               if ($browserInfo['all'][$engine]) {
+                                       $browserInfo['browser'] = $engine;
+                                       $browserInfo['version'] = ClientUtility::getVersion($browserInfo['all'][$engine]);
+                                       break;
+                               }
+                       }
+               }
+               return $browserInfo;
+       }
+
+       /**
+        * Initialize a couple of language related local properties
+        *
+        * @return void
+        */
+       public function initializeLanguageRelatedProperties() {
+               $database = $this->getDatabaseConnection();
+               $this->language = $GLOBALS['LANG']->lang;
+               if ($this->language === 'default' || !$this->language) {
+                       $this->language = 'en';
+               }
+               $this->contentLanguageUid = max($this->globalOptions['databaseRow']['sys_language_uid'], 0);
+               if ($this->contentLanguageUid) {
+                       $this->contentISOLanguage = $this->language;
+                       if (ExtensionManagementUtility::isLoaded('static_info_tables')) {
+                               $tableA = 'sys_language';
+                               $tableB = 'static_languages';
+                               $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2';
+                               $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
+                               $whereClause = $tableA . '.uid = ' . intval($this->contentLanguageUid);
+                               $whereClause .= BackendUtility::BEenableFields($tableA);
+                               $whereClause .= BackendUtility::deleteClause($tableA);
+                               $res = $database->exec_SELECTquery($selectFields, $tableAB, $whereClause);
+                               while ($languageRow = $database->sql_fetch_assoc($res)) {
+                                       $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']) . (trim($languageRow['lg_country_iso_2']) ? '_' . trim($languageRow['lg_country_iso_2']) : ''));
+                               }
+                               $database->sql_free_result($res);
+                       }
+               } else {
+                       $this->contentISOLanguage = trim($this->processedRteConfiguration['defaultContentLanguage']) ?: 'en';
+                       $languageCodeParts = explode('_', $this->contentISOLanguage);
+                       $this->contentISOLanguage = strtolower($languageCodeParts[0]) . ($languageCodeParts[1] ? '_' . strtoupper($languageCodeParts[1]) : '');
+                       // Find the configured language in the list of localization locales
+                       /** @var $locales Locales */
+                       $locales = GeneralUtility::makeInstance(Locales::class);
+                       // If not found, default to 'en'
+                       if (!in_array($this->contentISOLanguage, $locales->getLocales())) {
+                               $this->contentISOLanguage = 'en';
+                       }
+               }
+               $this->contentTypo3Language = $this->contentISOLanguage === 'en' ? 'default' : $this->contentISOLanguage;
+       }
+
+       /**
+        * Log usage of deprecated Page TS Config Property
+        *
+        * @param string $deprecatedProperty: Name of deprecated property
+        * @param string $useProperty: Name of property to use instead
+        * @param string $version: Version of TYPO3 in which the property will be removed
+        * @return void
+        */
+       protected function logDeprecatedProperty($deprecatedProperty, $useProperty, $version) {
+               $backendUser = $this->getBackendUserAuthentication();
+               if (!$this->processedRteConfiguration['logDeprecatedProperties.']['disabled']) {
+                       $message = sprintf(
+                               'RTE Page TSConfig property "%1$s" used on page id #%4$s is DEPRECATED and will be removed in TYPO3 %3$s. Use "%2$s" instead.',
+                               $deprecatedProperty,
+                               $useProperty,
+                               $version,
+                               $this->globalOptions['databaseRow']['pid']
+                       );
+                       GeneralUtility::deprecationLog($message);
+                       if ($this->processedRteConfiguration['logDeprecatedProperties.']['logAlsoToBELog']) {
+                               $message = sprintf(
+                                       $this->getLanguageService()->sL('LLL:EXT:rtehtmlarea/locallang.xlf:deprecatedPropertyMessage'),
+                                       $deprecatedProperty,
+                                       $useProperty,
+                                       $version,
+                                       $this->globalOptions['databaseRow']['pid']
+                               );
+                               $backendUser->simplelog($message, 'rtehtmlarea');
+                       }
+               }
+       }
+
+       /**
+        * A list of parameters that is mostly given as GET/POST to other RTE controllers.
+        *
+        * @return string
+        */
+       protected function RTEtsConfigParams() {
+               $parameters = BackendUtility::getSpecConfParametersFromArray($this->defaultExtras['rte_transform']['parameters']);
+               $result = array(
+                       $this->globalOptions['table'],
+                       $this->globalOptions['databaseRow']['uid'],
+                       $this->globalOptions['fieldName'],
+                       $this->pidOfVersionedMotherRecord,
+                       $this->globalOptions['recordTypeValue'],
+                       $this->pidOfPageRecord,
+                       $parameters['imgpath'],
+               );
+               return implode(':', $result);
+       }
+
+       /**
+        * Clean list
+        *
+        * @param string $str String to clean
+        * @return string Cleaned string
+        */
+       protected function cleanList($str) {
+               if (strstr($str, '*')) {
+                       $str = '*';
+               } else {
+                       $str = implode(',', array_unique(GeneralUtility::trimExplode(',', $str, TRUE)));
+               }
+               return $str;
+       }
+
+       /**
+        * Performs transformation of content from database to richtext editor
+        *
+        * @param string $value Value to transform.
+        * @return string Transformed content
+        */
+       protected function transformDatabaseContentToEditor($value) {
+               // change <strong> to <b>
+               $value = preg_replace('/<(\\/?)strong/i', '<$1b', $value);
+               // change <em> to <i>
+               $value = preg_replace('/<(\\/?)em([^b>]*>)/i', '<$1i$2', $value);
+
+               if ($this->defaultExtras['rte_transform']) {
+                       $parameters = BackendUtility::getSpecConfParametersFromArray($this->defaultExtras['rte_transform']['parameters']);
+                       // There must be a mode set for transformation
+                       if ($parameters['mode']) {
+                               /** @var RteHtmlParser $parseHTML */
+                               $parseHTML = GeneralUtility::makeInstance(RteHtmlParser::class);
+                               $parseHTML->init($this->globalOptions['table'] . ':' . $this->globalOptions['fieldName'], $this->pidOfVersionedMotherRecord);
+                               $parseHTML->setRelPath('');
+                               $value = $parseHTML->RTE_transform($value, $this->defaultExtras, 'rte', $this->processedRteConfiguration);
+                       }
+               }
+               return $value;
+       }
+
+       /**
+        * True if RTE is in full screen mode / called via wizard controller
+        *
+        * @return bool
+        */
+       protected function isInFullScreenMode() {
+               return GeneralUtility::_GP('M') === 'wizard_rte';
+       }
+
+       /**
+        * @return LanguageService
+        */
+       protected function getLanguageService() {
+               return $GLOBALS['LANG'];
        }
 
        /**
@@ -110,4 +1346,18 @@ class RichTextElement extends AbstractFormElement {
                return $GLOBALS['BE_USER'];
        }
 
+       /**
+        * @return DatabaseConnection
+        */
+       protected function getDatabaseConnection() {
+               return $GLOBALS['TYPO3_DB'];
+       }
+
+       /**
+        * @return PageRenderer
+        */
+       protected function getPageRenderer() {
+               return $GLOBALS['SOBE']->doc->getPageRenderer();
+       }
+
 }
index f5cf9a0..cf59aa7 100644 (file)
@@ -16,6 +16,8 @@ namespace TYPO3\CMS\Rtehtmlarea;
 
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Lang\LanguageService;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Core\FrontendEditing\FrontendEditingController;
 
 /**
  * API for extending htmlArea RTE
@@ -46,28 +48,7 @@ abstract class RteHtmlAreaApi {
        protected $relativePathToSkin = '';
 
        /**
-        * Reference to the invoking object
-        *
-        * @var RteHtmlAreaBase
-        */
-       protected $htmlAreaRTE;
-
-       /**
-        * The extension key of the RTE
-        *
-        * @var string
-        */
-       protected $rteExtensionKey;
-
-       /**
-        * Reference to RTE PageTSConfig
-        *
-        * @var array
-        */
-       protected $thisConfig;
-
-       /**
-        * Reference to RTE toolbar array
+        * Toolbar array
         *
         * @var array
         */
@@ -116,70 +97,45 @@ abstract class RteHtmlAreaApi {
        protected $requiredPlugins = '';
 
        /**
+        * Configuration array with settings given down from calling class
+        *
+        * @var array
+        */
+       protected $configuration;
+
+       /**
         * Returns TRUE if the plugin is available and correctly initialized
         *
-        * @param RteHtmlAreaBase $parentObject parent object
+        * @param array $configuration Configuration array given from calling object down to the single plugins
         * @return bool TRUE if this plugin object should be made available in the current environment and is correctly initialized
         */
-       public function main($parentObject) {
-               $this->htmlAreaRTE = $parentObject;
-               $this->rteExtensionKey = &$this->htmlAreaRTE->ID;
-               $this->thisConfig = &$this->htmlAreaRTE->thisConfig;
-               $this->toolbar = &$this->htmlAreaRTE->toolbar;
+       public function main(array $configuration) {
+               $this->configuration = $configuration;
                // Set the value of this boolean based on the initial value of $this->pluginButtons
                $this->pluginAddsButtons = !empty($this->pluginButtons);
                // Check if the plugin should be disabled in frontend
-               if ($this->htmlAreaRTE->is_FE() && $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->rteExtensionKey]['plugins'][$this->pluginName]['disableInFE']) {
+               if ($this->isFrontend() && $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins'][$this->pluginName]['disableInFE']) {
                        return FALSE;
                }
                return TRUE;
        }
 
        /**
-        * Returns a modified toolbar order string
-        *
-        * @return string a modified tollbar order list
-        */
-       public function addButtonsToToolbar() {
-               //Add only buttons not yet in the default toolbar order
-               $addButtons = implode(',', array_diff(GeneralUtility::trimExplode(',', $this->pluginButtons, TRUE), GeneralUtility::trimExplode(',', $this->htmlAreaRTE->defaultToolbarOrder, TRUE)));
-               return ($addButtons ? 'bar,' . $addButtons . ',linebreak,' : '') . $this->htmlAreaRTE->defaultToolbarOrder;
-       }
-
-       /**
-        * Returns the path to the skin component (button icons) that should be added to linked stylesheets
-        *
-        * @return string path to the skin (css) file
-        */
-       public function getPathToSkin() {
-               if (
-                       isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->rteExtensionKey]['plugins'][$this->pluginName]['addIconsToSkin'])
-                       && $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->rteExtensionKey]['plugins'][$this->pluginName]['addIconsToSkin']
-               ) {
-                       return $this->relativePathToSkin;
-               } else {
-                       return '';
-               }
-       }
-
-       /**
         * Return JS configuration of the htmlArea plugins registered by the extension
         *
-        * @param string $rteNumberPlaceholder A dummy string for JS arrays
         * @return string JS configuration for registered plugins
         */
-       public function buildJavascriptConfiguration($rteNumberPlaceholder) {
-               $registerRTEinJavascriptString = '';
+       public function buildJavascriptConfiguration() {
+               $jsArray = array();
                $pluginButtons = GeneralUtility::trimExplode(',', $this->pluginButtons, TRUE);
                foreach ($pluginButtons as $button) {
                        if (in_array($button, $this->toolbar)) {
-                               if (!is_array($this->thisConfig['buttons.']) || !is_array($this->thisConfig['buttons.'][($button . '.')])) {
-                                       $registerRTEinJavascriptString .= '
-                       RTEarea[' . $rteNumberPlaceholder . '].buttons.' . $button . ' = new Object();';
+                               if (!is_array($this->configuration['thisConfig']['buttons.']) || !is_array($this->configuration['thisConfig']['buttons.'][($button . '.')])) {
+                                       $jsArray[] = 'RTEarea[editornumber].buttons.' . $button . ' = new Object();';
                                }
                        }
                }
-               return $registerRTEinJavascriptString;
+               return implode(LF, $jsArray);
        }
 
        /**
@@ -246,16 +202,124 @@ abstract class RteHtmlAreaApi {
        }
 
        /**
-        * Get language service, instantiate if not there, yet
+        * Set toolbal
         *
-        * @return LanguageService
+        * @param array $toolbar
         */
-       protected function getLanguageService() {
-               if (isset($GLOBALS['LANG'])) {
-                       return $GLOBALS['LANG'];
+       public function setToolbar(array $toolbar) {
+               $this->toolbar = $toolbar;
+       }
+
+       /**
+        * Clean list
+        *
+        * @param string $str
+        * @return string
+        */
+       protected function cleanList($str) {
+               if (strstr($str, '*')) {
+                       $str = '*';
                } else {
-                       return GeneralUtility::makeInstance(LanguageService::class);
+                       $str = implode(',', array_unique(GeneralUtility::trimExplode(',', $str, TRUE)));
                }
+               return $str;
        }
 
+       /**
+        * Resolve a label and do some funny quoting.
+        *
+        * @param string $string Given label name
+        * @return string Resolved label
+        */
+       protected function getPageConfigLabel($string) {
+               $label = $this->getLanguageService()->sL(trim($string));
+               // @todo: find out why this is done and if it could be substituted with quoteJSvalue
+               $label = str_replace('"', '\\"', str_replace('\\\'', '\'', $label));
+               return $label;
+       }
+
+       /**
+        * Return TRUE if we are in the FE, but not in the FE editing feature of BE.
+        *
+        * @return bool
+        */
+       protected function isFrontend() {
+               return is_object($GLOBALS['TSFE'])
+                       && !$this->isFrontendEditActive()
+                       && TYPO3_MODE == 'FE';
+       }
+
+       /**
+        * Checks whether frontend editing is active.
+        *
+        * @return bool
+        */
+       protected function isFrontendEditActive() {
+               return is_object($GLOBALS['TSFE'])
+                       && $GLOBALS['TSFE']->beUserLogin
+                       && $GLOBALS['BE_USER']->frontendEdit instanceof FrontendEditingController;
+       }
+
+       /**
+        * Make a file name relative to the PATH_site or to the PATH_typo3
+        *
+        * @param string $filename: a file name of the form EXT:.... or relative to the PATH_site
+        * @return string the file name relative to the PATH_site if in frontend or relative to the PATH_typo3 if in backend
+        */
+       protected function getFullFileName($filename) {
+               if (substr($filename, 0, 4) === 'EXT:') {
+                       // extension
+                       list($extKey, $local) = explode('/', substr($filename, 4), 2);
+                       $newFilename = '';
+                       if ((string)$extKey !== '' && ExtensionManagementUtility::isLoaded($extKey) && (string)$local !== '') {
+                               $newFilename = ($this->isFrontend() || $this->isFrontendEditActive()
+                                               ? ExtensionManagementUtility::siteRelPath($extKey)
+                                               : ExtensionManagementUtility::extRelPath($extKey))
+                                       . $local;
+                       }
+               } else {
+                       $path = ($this->isFrontend() || $this->isFrontendEditActive() ? '' : '../');
+                       $newFilename = $path . ($filename[0] === '/' ? substr($filename, 1) : $filename);
+               }
+               return GeneralUtility::resolveBackPath($newFilename);
+       }
+
+       /**
+        * Writes contents in a file in typo3temp and returns the file name
+        *
+        * @param string $label: A label to insert at the beginning of the name of the file
+        * @param string $fileExtension: The file extension of the file, defaulting to 'js'
+        * @param string $contents: The contents to write into the file
+        * @return string The name of the file written to typo3temp
+        * @throws \RuntimeException If writing to file failed
+        */
+       protected function writeTemporaryFile($label, $fileExtension = 'js', $contents = '') {
+               $relativeFilename = 'typo3temp/rtehtmlarea_' . str_replace('-', '_', $label) . '_' . GeneralUtility::shortMD5($contents, 20) . '.' . $fileExtension;
+               $destination = PATH_site . $relativeFilename;
+               if (!file_exists($destination)) {
+                       $minifiedJavaScript = '';
+                       if ($fileExtension === 'js' && $contents !== '') {
+                               $minifiedJavaScript = GeneralUtility::minifyJavaScript($contents);
+                       }
+                       $failure = GeneralUtility::writeFileToTypo3tempDir($destination, $minifiedJavaScript ? $minifiedJavaScript : $contents);
+                       if ($failure) {
+                               throw new \RuntimeException($failure, 1294585668);
+                       }
+               }
+               if (isset($GLOBALS['TSFE'])) {
+                       $fileName = $relativeFilename;
+               } else {
+                       $fileName = '../' . $relativeFilename;
+               }
+               return GeneralUtility::resolveBackPath($fileName);
+       }
+
+       /**
+        * Get language service, instantiate if not there, yet
+        *
+        * @return LanguageService
+        */
+       protected function getLanguageService() {
+               return $GLOBALS['LANG'];
+       }
 }
diff --git a/typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaBase.php b/typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaBase.php
deleted file mode 100644 (file)
index 70064aa..0000000
+++ /dev/null
@@ -1,1587 +0,0 @@
-<?php
-namespace TYPO3\CMS\Rtehtmlarea;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Backend\Form\FormEngine;
-use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Utility\ArrayUtility;
-use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Backend\Form\InlineStackProcessor;
-use TYPO3\CMS\Core\Database\DatabaseConnection;
-use TYPO3\CMS\Lang\LanguageService;
-use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
-use TYPO3\CMS\Core\Page\PageRenderer;
-
-/**
- * A RTE using the htmlArea editor
- *
- * @author Philipp Borgmann <philipp.borgmann@gmx.de>
- * @author Stanislas Rolland <typo3(arobas)sjbr.ca>
- */
-class RteHtmlAreaBase extends \TYPO3\CMS\Backend\Rte\AbstractRte {
-
-       // Configuration of supported browsers
-       /**
-        * @var array
-        */
-       public $conf_supported_browser = array(
-               'msie' => array(
-                       array(
-                               'version' => 9.0,
-                               'system' => array(
-                                       'allowed' => array(
-                                               'winNT',
-                                               'win98',
-                                               'win95'
-                                       )
-                               )
-                       )
-               ),
-               'gecko' => array(
-                       array(
-                               'version' => 1.8
-                       )
-               ),
-               'webkit' => array(
-                       array(
-                               'version' => 534
-                       ),
-                       array(
-                               'version' => 523,
-                               'system' => array(
-                                       'disallowed' => array(
-                                               'iOS',
-                                               'android'
-                                       )
-                               )
-                       )
-               ),
-               'opera' => array(
-                       array(
-                               'version' => 9.62,
-                               'system' => array(
-                                       'disallowed' => array(
-                                               'iOS',
-                                               'android'
-                                       )
-                               )
-                       )
-               )
-       );
-
-       // Always hide these toolbar buttons (TYPO3 button name)
-       /**
-        * @var array
-        */
-       public $conf_toolbar_hide = array(
-               'showhelp'
-       );
-
-       // The order of the toolbar: the name is the TYPO3-button name
-       /**
-        * @var string
-        */
-       public $defaultToolbarOrder;
-
-       // Conversion array: TYPO3 button names to htmlArea button names
-       /**
-        * @var array
-        */
-       public $convertToolbarForHtmlAreaArray = array(
-               'showhelp' => 'ShowHelp',
-               'space' => 'space',
-               'bar' => 'separator',
-               'linebreak' => 'linebreak'
-       );
-
-       /**
-        * @var array
-        */
-       public $pluginButton = array();
-
-       /**
-        * @var array
-        */
-       public $pluginLabel = array();
-
-       // Alternative style for RTE <div> tag.
-       public $RTEdivStyle;
-
-       // Relative path to this extension. It ends with "/"
-       public $extHttpPath;
-
-       // TYPO3 site url
-       public $siteURL;
-
-       // TYPO3 host url
-       public $hostURL;
-
-       // Typo3 version
-       public $typoVersion;
-
-       // Identifies the RTE as being the one from the "rtehtmlarea" extension if any external code needs to know
-       /**
-        * @var string
-        */
-       public $ID = 'rtehtmlarea';
-
-       // For the editor
-       /**
-        * @var array
-        */
-       public $client;
-
-       /**
-        * @var string
-        */
-       public $elementId;
-
-       /**
-        * @var array
-        */
-       public $elementParts;
-
-       /**
-        * @var string
-        */
-       public $tscPID;
-
-       /**
-        * @var string
-        */
-       public $typeVal;
-
-       /**
-        * @var int
-        */
-       public $thePid;
-
-       /**
-        * @var array
-        */
-       public $RTEsetup;
-
-       /**
-        * @var array
-        */
-       public $thisConfig;
-
-       public $language;
-       /**
-        * TYPO3 language code of the content language
-        */
-       public $contentTypo3Language;
-       /**
-        * ISO language code of the content language
-        */
-       public $contentISOLanguage;
-       /**
-        * Language service object for localization to the content language
-        */
-       protected $contentLanguageService;
-       public $charset = 'utf-8';
-
-       public $contentCharset = 'utf-8';
-
-       public $OutputCharset = 'utf-8';
-
-       /**
-        * @var string
-        */
-       public $editorCSS;
-
-       /**
-        * @var array
-        */
-       public $specConf;
-
-       /**
-        * @var array
-        */
-       public $toolbar = array();
-
-       // Save the buttons for the toolbar
-       /**
-        * @var array
-        */
-       public $toolbarOrderArray = array();
-
-       protected $pluginEnabledArray = array();
-
-       // Array of plugin id's enabled in the current RTE editing area
-       protected $pluginEnabledCumulativeArray = array();
-
-       // Cumulative array of plugin id's enabled so far in any of the RTE editing areas of the form
-       public $registeredPlugins = array();
-
-       // Array of registered plugins indexed by their plugin Id's
-       protected $fullScreen = FALSE;
-
-       /**
-        * Page renderer object
-        *
-        * @var PageRenderer
-        */
-       protected $pageRenderer;
-
-       /**
-        * A list of global options given from parent to child elements
-        *
-        * @var array
-        */
-       protected $globalOptions = array();
-
-       /**
-        * Returns TRUE if the RTE is available. Here you check if the browser requirements are met.
-        * If there are reasons why the RTE cannot be displayed you simply enter them as text in ->errorLog
-        *
-        * @return bool TRUE if this RTE object offers an RTE in the current browser environment
-        */
-       public function isAvailable() {
-               $this->client = $this->clientInfo();
-               $this->errorLog = array();
-               $rteIsAvailable = FALSE;
-               $rteConfBrowser = $this->conf_supported_browser;
-               if (is_array($rteConfBrowser)) {
-                       foreach ($rteConfBrowser as $browser => $browserConf) {
-                               if ($browser == $this->client['browser']) {
-                                       // Config for Browser found, check it:
-                                       if (is_array($browserConf)) {
-                                               foreach ($browserConf as $browserConfSub) {
-                                                       if ($browserConfSub['version'] <= $this->client['version'] || empty($browserConfSub['version'])) {
-                                                               // Version is supported
-                                                               if (is_array($browserConfSub['system'])) {
-                                                                       // Check against allowed systems
-                                                                       if (is_array($browserConfSub['system']['allowed'])) {
-                                                                               foreach ($browserConfSub['system']['allowed'] as $system) {
-                                                                                       if (in_array($system, $this->client['all_systems'])) {
-                                                                                               $rteIsAvailable = TRUE;
-                                                                                               break;
-                                                                                       }
-                                                                               }
-                                                                       } else {
-                                                                               // All allowed
-                                                                               $rteIsAvailable = TRUE;
-                                                                       }
-                                                                       // Check against disallowed systems
-                                                                       if (is_array($browserConfSub['system']['disallowed'])) {
-                                                                               foreach ($browserConfSub['system']['disallowed'] as $system) {
-                                                                                       if (in_array($system, $this->client['all_systems'])) {
-                                                                                               $rteIsAvailable = FALSE;
-                                                                                               break;
-                                                                                       }
-                                                                               }
-                                                                       }
-                                                               } else {
-                                                                       // No system config: system is supported
-                                                                       $rteIsAvailable = TRUE;
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-                                       } else {
-                                               // no config for this browser found, so all versions or system with this browsers are allow
-                                               $rteIsAvailable = TRUE;
-                                               break;
-                                       }
-                               }
-                       }
-               } else {
-
-               }
-               if (!$rteIsAvailable) {
-                       $this->errorLog[] = 'RTE: Browser not supported.';
-               }
-
-               return $rteIsAvailable;
-       }
-
-       /**
-        * Draws the RTE as an iframe
-        *
-        * @param FormEngine $_ Reference to parent object, which is an instance of the TCEforms. Obsolete DUMMY object only!
-        * @param string $table The table name
-        * @param string $field The field name
-        * @param array $row The current row from which field is being rendered
-        * @param array $PA Array of standard content for rendering form fields from TCEforms. See TCEforms for details on this. Includes for instance the value and the form field name, java script actions and more.
-        * @param array $specConf "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
-        * @param array $thisConfig Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
-        * @param string $RTEtypeVal Record "type" field value.
-        * @param string $RTErelPath Relative path for images/links in RTE; this is used when the RTE edits content from static files where the path of such media has to be transformed forth and back!
-        * @param int $thePidValue PID value of record (true parent page id)
-        * @param array $globalOptions Global options like 'readonly' for all elements. This is a hack until RTE is an own type
-        * @param array $resultArray Initialized final result array that is returned later filled with content. This is a hack until RTE is an own type
-        * @param string $validatationDataAttribute the validation data attribute.
-        * @return string HTML code for RTE!
-        */
-       public function drawRTE($_, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue, $globalOptions, $resultArray, $validatationDataAttribute = '') {
-               $languageService = $this->getLanguageService();
-               $backendUser = $this->getBackendUserAuthentication();
-               $database = $this->getDatabaseConnection();
-
-               $this->globalOptions = $globalOptions;
-               $languageService->includeLLFile('EXT:rtehtmlarea/locallang.xlf');
-               $this->client = $this->clientInfo();
-               $this->typoVersion = \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version);
-               $this->userUid = 'BE_' . $GLOBALS['BE_USER']->user['uid'];
-
-               // Draw real RTE
-               /* =======================================
-                * INIT THE EDITOR-SETTINGS
-                * =======================================
-                */
-               // Get the path to this extension:
-               $this->extHttpPath = ExtensionManagementUtility::extRelPath('rtehtmlarea');
-               // Get the site URL
-               $this->siteURL = GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
-               // Get the host URL
-               $this->hostURL = $this->siteURL . TYPO3_mainDir;
-               // Element ID + pid
-               $this->elementId = $PA['itemFormElName'];
-               // Form element name
-               $this->elementParts = explode('][', preg_replace('/\\]$/', '', preg_replace('/^(TSFE_EDIT\\[data\\]\\[|data\\[)/', '', $this->elementId)));
-               // Find the page PIDs:
-               list($this->tscPID, $this->thePid) = BackendUtility::getTSCpid(trim($this->elementParts[0]), trim($this->elementParts[1]), $thePidValue);
-               // Record "types" field value:
-               $this->typeVal = $RTEtypeVal;
-               // TCA "types" value for record
-               // Find "thisConfig" for record/editor:
-               unset($this->RTEsetup);
-               $this->RTEsetup = $backendUser->getTSConfig('RTE', BackendUtility::getPagesTSconfig($this->tscPID));
-               $this->thisConfig = $thisConfig;
-               // Special configuration and default extras:
-               $this->specConf = $specConf;
-               if ($this->thisConfig['forceHTTPS']) {
-                       $this->extHttpPath = preg_replace('/^(http|https)/', 'https', $this->extHttpPath);
-                       $this->siteURL = preg_replace('/^(http|https)/', 'https', $this->siteURL);
-                       $this->hostURL = preg_replace('/^(http|https)/', 'https', $this->hostURL);
-               }
-               // Register RTE windows
-               $textAreaId = preg_replace('/[^a-zA-Z0-9_:.-]/', '_', $PA['itemFormElName']);
-               $textAreaId = htmlspecialchars(preg_replace('/^[^a-zA-Z]/', 'x', $textAreaId));
-               /* =======================================
-                * LANGUAGES & CHARACTER SETS
-                * =======================================
-                */
-               // Languages: interface and content
-               $this->language = $GLOBALS['LANG']->lang;
-               if ($this->language === 'default' || !$this->language) {
-                       $this->language = 'en';
-               }
-               $this->contentLanguageUid = max($row['sys_language_uid'], 0);
-               if ($this->contentLanguageUid) {
-                       $this->contentISOLanguage = $this->language;
-                       if (ExtensionManagementUtility::isLoaded('static_info_tables')) {
-                               $tableA = 'sys_language';
-                               $tableB = 'static_languages';
-                               $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2';
-                               $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
-                               $whereClause = $tableA . '.uid = ' . intval($this->contentLanguageUid);
-                               $whereClause .= BackendUtility::BEenableFields($tableA);
-                               $whereClause .= BackendUtility::deleteClause($tableA);
-                               $res = $database->exec_SELECTquery($selectFields, $tableAB, $whereClause);
-                               while ($languageRow = $database->sql_fetch_assoc($res)) {
-                                       $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']) . (trim($languageRow['lg_country_iso_2']) ? '_' . trim($languageRow['lg_country_iso_2']) : ''));
-                               }
-                       }
-               } else {
-                       $this->contentISOLanguage = trim($this->thisConfig['defaultContentLanguage']) ?: 'en';
-                       $languageCodeParts = explode('_', $this->contentISOLanguage);
-                       $this->contentISOLanguage = strtolower($languageCodeParts[0]) . ($languageCodeParts[1] ? '_' . strtoupper($languageCodeParts[1]) : '');
-                       // Find the configured language in the list of localization locales
-                       /** @var $locales \TYPO3\CMS\Core\Localization\Locales */
-                       $locales = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Localization\Locales::class);
-                       // If not found, default to 'en'
-                       if (!in_array($this->contentISOLanguage, $locales->getLocales())) {
-                               $this->contentISOLanguage = 'en';
-                       }
-               }
-               // Create content laguage service
-               $this->contentLanguageService = GeneralUtility::makeInstance(\TYPO3\CMS\Lang\LanguageService::class);
-               $this->contentTypo3Language = $this->contentISOLanguage === 'en' ? 'default' : $this->contentISOLanguage;
-               $this->contentLanguageService->init($this->contentTypo3Language);
-               /* =======================================
-                * TOOLBAR CONFIGURATION
-                * =======================================
-                */
-               $this->initializeToolbarConfiguration();
-               /* =======================================
-                * SET STYLES
-                * =======================================
-                */
-               // Check if wizard_rte called this for fullscreen edtition
-               if (GeneralUtility::_GP('M') === 'wizard_rte') {
-                       $this->fullScreen = TRUE;
-                       $RTEWidth = '100%';
-                       $RTEHeight = '100%';
-                       $RTEPaddingRight = '0';
-                       $editorWrapWidth = '100%';
-               } else {
-                       $options = $GLOBALS['BE_USER']->userTS['options.'];
-                       $RTEWidth = 530 + (isset($options['RTELargeWidthIncrement']) ? (int)$options['RTELargeWidthIncrement'] : 150);
-                       /** @var InlineStackProcessor  $inlineStackProcessor */
-                       $inlineStackProcessor = GeneralUtility::makeInstance(InlineStackProcessor::class);
-                       $inlineStackProcessor->initializeByGivenStructure($globalOptions['inlineStructure']);
-                       $inlineStructureDepth = $inlineStackProcessor->getStructureDepth();
-                       $RTEWidth -= $inlineStructureDepth > 0 ? ($inlineStructureDepth + 1) * 12 : 0;
-                       $RTEWidthOverride = is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteWidth']) && trim($GLOBALS['BE_USER']->uc['rteWidth']) ? trim($GLOBALS['BE_USER']->uc['rteWidth']) : trim($this->thisConfig['RTEWidthOverride']);
-                       if ($RTEWidthOverride) {
-                               if (strstr($RTEWidthOverride, '%')) {
-                                       if ($this->client['browser'] != 'msie') {
-                                               $RTEWidth = (int)$RTEWidthOverride > 0 ? $RTEWidthOverride : '100%';
-                                       }
-                               } else {
-                                       $RTEWidth = (int)$RTEWidthOverride > 0 ? (int)$RTEWidthOverride : $RTEWidth;
-                               }
-                       }
-                       $RTEWidth = strstr($RTEWidth, '%') ? $RTEWidth : $RTEWidth . 'px';
-                       $RTEHeight = 380 + (isset($options['RTELargeHeightIncrement']) ? (int)$options['RTELargeHeightIncrement'] : 0);
-                       $RTEHeightOverride = is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteHeight']) && (int)$GLOBALS['BE_USER']->uc['rteHeight'] ? (int)$GLOBALS['BE_USER']->uc['rteHeight'] : (int)$this->thisConfig['RTEHeightOverride'];
-                       $RTEHeight = $RTEHeightOverride > 0 ? $RTEHeightOverride : $RTEHeight;
-                       $RTEPaddingRight = '2px';
-                       $editorWrapWidth = '99%';
-               }
-               $editorWrapHeight = '100%';
-               $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:' . $RTEHeight . 'px; width:' . $RTEWidth . '; border: 1px solid black; padding: 2px ' . $RTEPaddingRight . ' 2px 2px;';
-               /* =======================================
-                * LOAD CSS AND JAVASCRIPT
-                * =======================================
-                */
-               $this->pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
-               // Preloading the pageStyle and including RTE skin stylesheets
-               $resultArray = $this->addPageStyle($resultArray);
-               $resultArray = $this->addSkin($resultArray);
-               // Register RTE in JS
-               $resultArray['additionalJavaScriptPost'][] = $this->registerRTEinJS(NULL, $table, $row['uid'], $field, $textAreaId);
-               // Set the save option for the RTE
-               $resultArray['additionalJavaScriptSubmit'][] = $this->setSaveRTE(NULL, 'editform', $textAreaId, $PA['itemFormElName']);
-               // Loading ExtJs inline code
-               $this->pageRenderer->enableExtJSQuickTips();
-               // Add TYPO3 notifications JavaScript
-               $this->pageRenderer->addJsFile('sysext/backend/Resources/Public/JavaScript/notifications.js');
-               // Add RTE JavaScript
-               $this->addRteJsFiles();
-               $this->pageRenderer->addJsFile($this->createJavaScriptLanguageLabelsFromFiles());
-               $this->pageRenderer->addJsInlineCode('HTMLArea-init', $this->getRteInitJsCode(), TRUE);
-               /* =======================================
-                * DRAW THE EDITOR
-                * =======================================
-                */
-               // Transform value:
-               $value = $this->transformContent('rte', $PA['itemFormElValue'], $table, $field, $row, $specConf, $thisConfig, $RTErelPath, $thePidValue);
-               // Further content transformation by registered plugins
-               foreach ($this->registeredPlugins as $pluginId => $plugin) {
-                       if ($this->isPluginEnabled($pluginId) && method_exists($plugin, 'transformContent')) {
-                               $value = $plugin->transformContent($value);
-                       }
-               }
-               // Draw the textarea
-               $item = $this->triggerField($PA['itemFormElName']) . '
-                       <div id="pleasewait' . $textAreaId . '" class="pleasewait" style="display: block;" >' . $languageService->getLL('Please wait') . '</div>
-                       <div id="editorWrap' . $textAreaId . '" class="editorWrap" style="visibility: hidden; width:' . $editorWrapWidth . '; height:' . $editorWrapHeight . ';">
-                       <textarea id="RTEarea' . $textAreaId . '" ' . $validatationDataAttribute . ' name="' . htmlspecialchars($PA['itemFormElName']) . '" rows="0" cols="0" style="' . htmlspecialchars($this->RTEdivStyle, ENT_COMPAT, 'UTF-8', FALSE) . '">' . GeneralUtility::formatForTextarea($value) . '</textarea>
-                       </div>' . LF;
-
-               $resultArray['html'] = $item;
-               return $resultArray;
-       }
-
-       /**
-        * Add links to content style sheets to document header
-        *
-        * @param $resultArray array Incoming result array
-        * @return array Modified result array
-        */
-       protected function addPageStyle(array $resultArray) {
-               $contentCssFileNames = $this->getContentCssFileNames();
-               foreach ($contentCssFileNames as $contentCssKey => $contentCssFile) {
-                       $resultArray = $this->addStyleSheet('rtehtmlarea-content-' . $contentCssKey, $contentCssFile, 'htmlArea RTE Content CSS', 'alternate stylesheet', $resultArray);
-               }
-               return $resultArray;
-       }
-
-       /**
-        * Get the name of the contentCSS files to use
-        *
-        * @return array An array of full file name of the content css files to use
-        */
-       protected function getContentCssFileNames() {
-               $contentCss = is_array($this->thisConfig['contentCSS.']) ? $this->thisConfig['contentCSS.'] : array();
-               if (isset($this->thisConfig['contentCSS'])) {
-                       $contentCss[] = trim($this->thisConfig['contentCSS']);
-               }
-               $contentCssFiles = array();
-               if (count($contentCss)) {
-                       foreach ($contentCss as $contentCssKey => $contentCssfile) {
-                               $fileName = trim($contentCssfile);
-                               $absolutePath = GeneralUtility::getFileAbsFileName($fileName);
-                               if (file_exists($absolutePath) && filesize($absolutePath)) {
-                                       $contentCssFiles[$contentCssKey] = $this->getFullFileName($fileName);
-                               }
-                       }
-               }
-               // Fallback to default content css file if none of the configured files exists and is not empty
-               if (count($contentCssFiles) === 0) {
-                       $contentCssFiles['default'] = $this->getFullFileName('EXT:' . $this->ID . '/Resources/Public/Css/ContentCss/Default.css');
-               }
-               return array_unique($contentCssFiles);
-       }
-
-       /**
-        * Add links to skin style sheet(s) to document header
-        *
-        * @param array $resultArray array Incoming result array
-        * @return array Modified result array
-        */
-       protected function addSkin(array $resultArray) {
-               // Get skin file name from Page TSConfig if any
-               $skinFilename = trim($this->thisConfig['skin']) ?: 'EXT:rtehtmlarea/Resources/Public/Css/Skin/htmlarea.css';
-               $this->editorCSS = $this->getFullFileName($skinFilename);
-               $skinDir = dirname($this->editorCSS);
-               // Editing area style sheet
-               $this->editedContentCSS = $skinDir . '/htmlarea-edited-content.css';
-               $resultArray = $this->addStyleSheet('rtehtmlarea-editing-area-skin', $this->editedContentCSS, '', 'stylesheet', $resultArray);
-               // jQuery UI Resizable style sheet
-               $resultArray = $this->addStyleSheet('jquery-ui-resizable', $skinDir . '/jquery-ui-resizable.css', '', 'stylesheet', $resultArray);
-               // Main skin
-               $resultArray = $this->addStyleSheet('rtehtmlarea-skin', $this->editorCSS, '', 'stylesheet', $resultArray);
-               // Additional icons from registered plugins
-               foreach ($this->pluginEnabledCumulativeArray as $pluginId) {
-                       if (is_object($this->registeredPlugins[$pluginId])) {
-                               $pathToSkin = $this->registeredPlugins[$pluginId]->getPathToSkin();
-                               if ($pathToSkin) {
-                                       $key = $this->registeredPlugins[$pluginId]->getExtensionKey();
-                                       $resultArray = $this->addStyleSheet(
-                                               'rtehtmlarea-plugin-' . $pluginId . '-skin',
-                                               ($this->is_FE() ? ExtensionManagementUtility::siteRelPath($key) : ExtensionManagementUtility::extRelPath($key)) . $pathToSkin,
-                                               '',
-                                               'stylesheet',
-                                               $resultArray
-                                       );
-                               }
-                       }
-               }
-               return $resultArray;
-       }
-
-       /**
-        * Add style sheet file to document header
-        *
-        * @param string $key: some key identifying the style sheet
-        * @param string $href: uri to the style sheet file
-        * @param string $title: value for the title attribute of the link element
-        * @param string $relation: value for the rel attribute of the link element
-        * @param $resultArray array Incoming result array
-        * @return array Modified result array
-        */
-       protected function addStyleSheet($key, $href, $title = '', $relation = 'stylesheet', array $resultArray) {
-               // If it was not known that an RTE-enabled CE would be created when the page was first created, the css would not be added to head
-               if ($this->globalOptions['isAjaxContext']) {
-                       $resultArray['additionalHeadTags'][] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '" title="' . $title . '" />';
-               } else {
-                       $this->pageRenderer->addCssFile($href, $relation, 'screen', $title);
-               }
-               return $resultArray;
-       }
-
-       /**
-        * Initialize toolbar configuration and enable registered plugins
-        *
-        * @return void
-        */
-       protected function initializeToolbarConfiguration() {
-               // Enable registred plugins
-               $this->enableRegisteredPlugins();
-               // Configure toolbar
-               $this->setToolbar();
-               // Check if some plugins need to be disabled
-               $this->setPlugins();
-               // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
-               $this->pluginEnabledCumulativeArray = $this->pluginEnabledArray;
-       }
-
-       /**
-        * Add registered plugins to the array of enabled plugins
-        */
-       public function enableRegisteredPlugins() {
-               // Traverse registered plugins
-               if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['plugins'])) {
-                       foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['plugins'] as $pluginId => $pluginObjectConfiguration) {
-                               $plugin = FALSE;
-                               if (is_array($pluginObjectConfiguration) && count($pluginObjectConfiguration)) {
-                                       $plugin = GeneralUtility::getUserObj($pluginObjectConfiguration['objectReference']);
-                               }
-                               if (is_object($plugin)) {
-                                       if ($plugin->main($this)) {
-                                               $this->registeredPlugins[$pluginId] = $plugin;
-                                               // Override buttons from previously registered plugins
-                                               $pluginButtons = GeneralUtility::trimExplode(',', $plugin->getPluginButtons(), TRUE);
-                                               foreach ($this->pluginButton as $previousPluginId => $buttonList) {
-                                                       $this->pluginButton[$previousPluginId] = implode(',', array_diff(GeneralUtility::trimExplode(',', $this->pluginButton[$previousPluginId], TRUE), $pluginButtons));
-                                               }
-                                               $this->pluginButton[$pluginId] = $plugin->getPluginButtons();
-                                               $pluginLabels = GeneralUtility::trimExplode(',', $plugin->getPluginLabels(), TRUE);
-                                               foreach ($this->pluginLabel as $previousPluginId => $labelList) {
-                                                       $this->pluginLabel[$previousPluginId] = implode(',', array_diff(GeneralUtility::trimExplode(',', $this->pluginLabel[$previousPluginId], TRUE), $pluginLabels));
-                                               }
-                                               $this->pluginLabel[$pluginId] = $plugin->getPluginLabels();
-                                               $this->pluginEnabledArray[] = $pluginId;
-                                       }
-                               }
-                       }
-               }
-               // Process overrides
-               $hidePlugins = array();
-               foreach ($this->registeredPlugins as $pluginId => $plugin) {
-                       if ($plugin->addsButtons() && !$this->pluginButton[$pluginId]) {
-                               $hidePlugins[] = $pluginId;
-                       }
-               }
-               $this->pluginEnabledArray = array_unique(array_diff($this->pluginEnabledArray, $hidePlugins));
-       }
-
-       /**
-        * Set the toolbar config (only in this PHP-Object, not in JS):
-        */
-       public function setToolbar() {
-               if ($this->client['browser'] == 'msie' || $this->client['browser'] == 'opera') {
-                       $this->thisConfig['keepButtonGroupTogether'] = 0;
-               }
-               $this->defaultToolbarOrder = 'bar, blockstylelabel, blockstyle, textstylelabel, textstyle, linebreak,
-                       bar, formattext, bold,  strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code, definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span,
-                       bar, fontstyle, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, line,
-                       bar, left, center, right, justifyfull,
-                       bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent,
-                       bar, language, showlanguagemarks,lefttoright, righttoleft,
-                       bar, textcolor, bgcolor, textindicator,
-                       bar, editelement, showmicrodata,
-                       bar, image, emoticon, insertcharacter, insertsofthyphen, abbreviation, user,
-                       bar, link, unlink,
-                       bar, table,' . ($this->thisConfig['hideTableOperationsInToolbar'] && is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['toggleborders.']) && $this->thisConfig['buttons.']['toggleborders.']['keepInToolbar'] ? ' toggleborders,' : '') . '
-                       bar, findreplace, spellcheck,
-                       bar, chMode, inserttag, removeformat, bar, copy, cut, paste, pastetoggle, pastebehaviour, bar, undo, redo, bar, showhelp, about, linebreak,
-                       ' . ($this->thisConfig['hideTableOperationsInToolbar'] ? '' : 'bar, toggleborders,') . ' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
-                       columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
-                       cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
-               // Additional buttons from registered plugins
-               foreach ($this->registeredPlugins as $pluginId => $plugin) {
-                       if ($this->isPluginEnabled($pluginId)) {
-                               $this->defaultToolbarOrder = $plugin->addButtonsToToolbar();
-                       }
-               }
-               $toolbarOrder = $this->thisConfig['toolbarOrder'] ?: $this->defaultToolbarOrder;
-               // Getting rid of undefined buttons
-               $this->toolbarOrderArray = array_intersect(GeneralUtility::trimExplode(',', $toolbarOrder, TRUE), GeneralUtility::trimExplode(',', $this->defaultToolbarOrder, TRUE));
-               $toolbarOrder = array_unique(array_values($this->toolbarOrderArray));
-               // Fetching specConf for field from backend
-               $pList = is_array($this->specConf['richtext']['parameters']) ? implode(',', $this->specConf['richtext']['parameters']) : '';
-               if ($pList != '*') {
-                       // If not all
-                       $show = is_array($this->specConf['richtext']['parameters']) ? $this->specConf['richtext']['parameters'] : array();
-                       if ($this->thisConfig['showButtons']) {
-                               if (!GeneralUtility::inList($this->thisConfig['showButtons'], '*')) {
-                                       $show = array_unique(array_merge($show, GeneralUtility::trimExplode(',', $this->thisConfig['showButtons'], TRUE)));
-                               } else {
-                                       $show = array_unique(array_merge($show, $toolbarOrder));
-                               }
-                       }
-                       if (is_array($this->thisConfig['showButtons.'])) {
-                               foreach ($this->thisConfig['showButtons.'] as $buttonId => $value) {
-                                       if ($value) {
-                                               $show[] = $buttonId;
-                                       }
-                               }
-                               $show = array_unique($show);
-                       }
-               } else {
-                       $show = $toolbarOrder;
-               }
-               // Resticting to RTEkeyList for backend user
-               if (is_object($GLOBALS['BE_USER'])) {
-                       $RTEkeyList = isset($GLOBALS['BE_USER']->userTS['options.']['RTEkeyList']) ? $GLOBALS['BE_USER']->userTS['options.']['RTEkeyList'] : '*';
-                       if ($RTEkeyList != '*') {
-                               // If not all
-                               $show = array_intersect($show, GeneralUtility::trimExplode(',', $RTEkeyList, TRUE));
-                       }
-               }
-               // Hiding buttons of disabled plugins
-               $hideButtons = array('space', 'bar', 'linebreak');
-               foreach ($this->pluginButton as $pluginId => $buttonList) {
-                       if (!$this->isPluginEnabled($pluginId)) {
-                               $buttonArray = GeneralUtility::trimExplode(',', $buttonList, TRUE);
-                               foreach ($buttonArray as $button) {
-                                       $hideButtons[] = $button;
-                               }
-                       }
-               }
-               // Hiding labels of disabled plugins
-               foreach ($this->pluginLabel as $pluginId => $label) {
-                       if (!$this->isPluginEnabled($pluginId)) {
-                               $hideButtons[] = $label;
-                       }
-               }
-               // Hiding buttons
-               $show = array_diff($show, $this->conf_toolbar_hide, GeneralUtility::trimExplode(',', $this->thisConfig['hideButtons'], TRUE));
-               // Apply toolbar constraints from registered plugins
-               foreach ($this->registeredPlugins as $pluginId => $plugin) {
-                       if ($this->isPluginEnabled($pluginId) && method_exists($plugin, 'applyToolbarConstraints')) {
-                               $show = $plugin->applyToolbarConstraints($show);
-               &nbs