diff --git a/typo3/sysext/backend/Classes/Controller/Wizard/RteController.php b/typo3/sysext/backend/Classes/Controller/Wizard/RteController.php index 949b32c327f99a3bcffe27833639eefa2a49b869..d263126bf28caa47504f6a32c2d018f5a5f9030e 100644 --- a/typo3/sysext/backend/Classes/Controller/Wizard/RteController.php +++ b/typo3/sysext/backend/Classes/Controller/Wizard/RteController.php @@ -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); diff --git a/typo3/sysext/backend/Classes/Form/Container/SingleFieldContainer.php b/typo3/sysext/backend/Classes/Form/Container/SingleFieldContainer.php index ea6f338a5b036bc402b386a57e8400d649be7c85..0ae814c7361789939534c21445b15680f36224ce 100644 --- a/typo3/sysext/backend/Classes/Form/Container/SingleFieldContainer.php +++ b/typo3/sysext/backend/Classes/Form/Container/SingleFieldContainer.php @@ -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'] diff --git a/typo3/sysext/backend/Classes/Form/FormEngine.php b/typo3/sysext/backend/Classes/Form/FormEngine.php index ccd706f6de8bf1fb71a034a544c61e103f0e24af..d5952a826d3942abd99e58930793b974b7363d1f 100644 --- a/typo3/sysext/backend/Classes/Form/FormEngine.php +++ b/typo3/sysext/backend/Classes/Form/FormEngine.php @@ -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 index bf34fa41ae7bb6a10da8fdb8c78132d90e928e7a..0000000000000000000000000000000000000000 --- a/typo3/sysext/backend/Classes/Rte/AbstractRte.php +++ /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" />'; - } - -} diff --git a/typo3/sysext/backend/Classes/Utility/BackendUtility.php b/typo3/sysext/backend/Classes/Utility/BackendUtility.php index 0598087a78c5b5ddae636a9e6c7b7baa49f0ac8d..48ca1af0ed4ac9360cfe0e9770f3850806d54762 100644 --- a/typo3/sysext/backend/Classes/Utility/BackendUtility.php +++ b/typo3/sysext/backend/Classes/Utility/BackendUtility.php @@ -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: diff --git a/typo3/sysext/backend/Classes/View/PageLayoutView.php b/typo3/sysext/backend/Classes/View/PageLayoutView.php index 42d746d8d4471799b14449bc90d7f57a0f425e66..5b5b84a44c52f535b4641345dc21dda22e80c3ca 100644 --- a/typo3/sysext/backend/Classes/View/PageLayoutView.php +++ b/typo3/sysext/backend/Classes/View/PageLayoutView.php @@ -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) diff --git a/typo3/sysext/backend/Resources/Private/Templates/helper_javascript_css.html b/typo3/sysext/backend/Resources/Private/Templates/helper_javascript_css.html index c74305141271e292511274f2ea25f54b45a9e68d..1e1f2e25d5c11325a6623632dfd85c537184a57d 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/helper_javascript_css.html +++ b/typo3/sysext/backend/Resources/Private/Templates/helper_javascript_css.html @@ -1,7 +1,3 @@ -###CSS_LIBS### -###CSS_INCLUDE### -###CSS_INLINE### - ###JS_LIBS### ###JS_INCLUDE### ###JS_INLINE### diff --git a/typo3/sysext/compatibility6/Migrations/Code/ClassAliasMap.php b/typo3/sysext/compatibility6/Migrations/Code/ClassAliasMap.php index 043dd0e498bfaafed79d1166765bfefab22aa38d..5024800defa2c9a2bb59c1316ecd29a2bd674c3c 100644 --- a/typo3/sysext/compatibility6/Migrations/Code/ClassAliasMap.php +++ b/typo3/sysext/compatibility6/Migrations/Code/ClassAliasMap.php @@ -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, diff --git a/typo3/sysext/compatibility6/Migrations/Code/LegacyClassesForIde.php b/typo3/sysext/compatibility6/Migrations/Code/LegacyClassesForIde.php index efa74476ab2518fb46bd430b7b17dc7d6d3952eb..b9123592dbb1c331212207e3ebdb7a1dd81f5bdf 100644 --- a/typo3/sysext/compatibility6/Migrations/Code/LegacyClassesForIde.php +++ b/typo3/sysext/compatibility6/Migrations/Code/LegacyClassesForIde.php @@ -366,11 +366,6 @@ class TBE_browser_recordList extends \TYPO3\CMS\Backend\RecordList\ElementBrowse */ interface t3lib_localRecordListGetTableHook extends \TYPO3\CMS\Backend\RecordList\RecordListGetTableHookInterface {} -/** - * @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 */ @@ -5776,11 +5771,6 @@ class tx_rtehtmlarea_pageTree extends \TYPO3\CMS\Rtehtmlarea\PageTree {} */ 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 */ diff --git a/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php b/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php index 7090b0d9ca99539afa5df2da463b6041c0172bc2..a335d580986d9f82e38caf67f7e3d5779905c3ed 100644 --- a/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php +++ b/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php @@ -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 { @@ -157,12 +156,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']; } /** diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index aab244643827fd7b39380d8b00c12a53966d07e2..786084fe03191fe1c9edb6c2597f9c37a6ae707b 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -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 + ); } } } diff --git a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php index 3dc2f0ab8caf1989457b8273eadabb2c983e1330..71e5e08c01d040b04382ed825dd7908529973fe1 100644 --- a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php +++ b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php @@ -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; diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php index 23d5c3c5bc287b412a0ac9e0d2f2e1648a447257..936c37edcda22a26ed760c3b2bab67fb37db1495 100644 --- a/typo3/sysext/core/Configuration/DefaultConfiguration.php +++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php @@ -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! diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-67811-RteApi.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-67811-RteApi.rst index 071e6d4d7924d0fb21e624d199f74bb7ddbab104..2cda7cb85069336b0515f0ebe7bfe4e3d0302e56 100644 --- a/typo3/sysext/core/Documentation/Changelog/master/Breaking-67811-RteApi.rst +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-67811-RteApi.rst @@ -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 diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/Abbreviation.php b/typo3/sysext/rtehtmlarea/Classes/Extension/Abbreviation.php index 70f3fcddcf04d97698fcf7aff1247307692f71ce..e1d3993a7b016cd2008f7938332e8f06f7343f27 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/Abbreviation.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/Abbreviation.php @@ -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']; + } + } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/AboutEditor.php b/typo3/sysext/rtehtmlarea/Classes/Extension/AboutEditor.php index d62fbb9c26dc5e2b25b1fda66573880a56ef0f8d..3da15014650eda59cfba1b36e138350c397bcf91 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/AboutEditor.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/AboutEditor.php @@ -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 ''; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/BlockElements.php b/typo3/sysext/rtehtmlarea/Classes/Extension/BlockElements.php index bc6bf1e0d59d9a5fa17a8ab7513560ab48e6911c..84b0f1d74e626483233994f5a1e0a7cf76e783de 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/BlockElements.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/BlockElements.php @@ -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); } } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/CharacterMap.php b/typo3/sysext/rtehtmlarea/Classes/Extension/CharacterMap.php index a706fabccc7b878f85fb673c88bcb35e3c898b7a..76ebe415f2f9f909117199b29823aebcd9a70a8a 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/CharacterMap.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/CharacterMap.php @@ -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 ''; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/ContextMenu.php b/typo3/sysext/rtehtmlarea/Classes/Extension/ContextMenu.php index 786c49a6a4af063e6b7e4dde6f30ba9384691173..0968c9923677b40de9fe75c8c887c7966ea95ccc 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/ContextMenu.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/ContextMenu.php @@ -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)); } } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/CopyPaste.php b/typo3/sysext/rtehtmlarea/Classes/Extension/CopyPaste.php index a181ae6bf5d7d204b9c30c291a14f5f1ac8a3b6d..3af78aed6c420c08c764c8297e7eda9f1fe558ac 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/CopyPaste.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/CopyPaste.php @@ -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; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultClean.php b/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultClean.php index b5eb9d30c780ec522e10899b06bc1d2eeda12074..e37cc4ca92f885b3c935b219cd0071fe037f2d19 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultClean.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultClean.php @@ -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); } /** diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultImage.php b/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultImage.php index 755ff0c55f3fd099de9595eb98a5443be72c5dac..9762dcb910b21b3e6cf8af4ac21489e9ea01a912 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultImage.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultImage.php @@ -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 ''; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultInline.php b/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultInline.php index 66d61160576e1b0942eea1abc15f41e24fec3e9a..18428e713de9820522d656f58cee06b080504824 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultInline.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultInline.php @@ -30,13 +30,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 * @@ -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; - } - } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultLink.php b/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultLink.php index 50ff787c1a4ed6154229aefbceec39da9c5941f5..9fb205c32f98013ef174e0e8014f0d596948296e 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultLink.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/DefaultLink.php @@ -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 ''; } } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/DefinitionList.php b/typo3/sysext/rtehtmlarea/Classes/Extension/DefinitionList.php index fabdb17c0d2585fdff023dcd2d68cc1a72541053..70fe5ca6fa8f694a130989d4a3585fb05b044ddc 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/DefinitionList.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/DefinitionList.php @@ -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 ''; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/EditElement.php b/typo3/sysext/rtehtmlarea/Classes/Extension/EditElement.php index aac0086571e6cc44b1245e24816e456714fb6a7e..420fdbbd4e87d4dcc63906555ced5001c2fcedd7 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/EditElement.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/EditElement.php @@ -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 ''; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/EditorMode.php b/typo3/sysext/rtehtmlarea/Classes/Extension/EditorMode.php index 40541627fd7e42cf3ad30f8afee32304bd7e8b42..d36e9b105b2ccd37a9298e7c01f6969a61e6d153 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/EditorMode.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/EditorMode.php @@ -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; diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/FindReplace.php b/typo3/sysext/rtehtmlarea/Classes/Extension/FindReplace.php index 04e901d09195fbcb733d7bcb72527d2a00324358..7ad7eb36dcc01645b731dc74fec33967b541cc61 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/FindReplace.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/FindReplace.php @@ -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 ''; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/InlineElements.php b/typo3/sysext/rtehtmlarea/Classes/Extension/InlineElements.php index 16ccb1ee98815a202b9a72fde413e4f6ddf8cf20..dacdd52e88c919899ce18f60ac1a203f8757cfe9 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/InlineElements.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/InlineElements.php @@ -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); } } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/InsertSmiley.php b/typo3/sysext/rtehtmlarea/Classes/Extension/InsertSmiley.php index 45964f5c4e6eceaaef81fdc62096b355affa0874..7f218d0ea500fe3c2b1f4872276722570229ec7f 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/InsertSmiley.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/InsertSmiley.php @@ -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 ''; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/Language.php b/typo3/sysext/rtehtmlarea/Classes/Extension/Language.php index 242ec1dc0ea93cefed5f915e3458c64b484db6bf..fd6b8c50814958911b77cd6cf368ffc8b14d1b2c 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/Language.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/Language.php @@ -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']; + } + } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/MicroDataSchema.php b/typo3/sysext/rtehtmlarea/Classes/Extension/MicroDataSchema.php index a3a8d70ae98233dff04a83e81f2978dae2805758..f3097384d11055afe56783941ba4cd7d48ebbd92 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/MicroDataSchema.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/MicroDataSchema.php @@ -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'); diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/Plaintext.php b/typo3/sysext/rtehtmlarea/Classes/Extension/Plaintext.php index 76026ca76de9de8b256494463f7a3bc98cc92d5b..54613a724fe4e6a16c0fd6d3832a9dbd2a3c3f0c 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/Plaintext.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/Plaintext.php @@ -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); } /** diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/QuickTag.php b/typo3/sysext/rtehtmlarea/Classes/Extension/QuickTag.php index f2d40186364ec75637d9e42f8df20d7b3c42a604..bef37b9f58a661568c759205461cd8bfa07bb937 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/QuickTag.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/QuickTag.php @@ -15,7 +15,6 @@ namespace TYPO3\CMS\Rtehtmlarea\Extension; */ use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaApi; -use TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase; /** * CharacterMap plugin for htmlArea RTE diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/RemoveFormat.php b/typo3/sysext/rtehtmlarea/Classes/Extension/RemoveFormat.php index 9fbc32cb3afbc6df3a71781aa1285d017d40b4fa..532f89d82aa98f80465796f0490d2054d6ab9818 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/RemoveFormat.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/RemoveFormat.php @@ -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 ''; } } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/SelectFont.php b/typo3/sysext/rtehtmlarea/Classes/Extension/SelectFont.php index 3e3261809abe1b3960074d02a4f0c19d36ec20a2..cca676d7fa981cae295dacb209811f6056fbb501 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/SelectFont.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/SelectFont.php @@ -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); } } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/Spellchecker.php b/typo3/sysext/rtehtmlarea/Classes/Extension/Spellchecker.php index 88e92507c52d1534b36491fbc39d7c7a853121fe..d32add12a84fc458b57a1098353d83ed683deced 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/Spellchecker.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/Spellchecker.php @@ -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); } + + } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/TableOperations.php b/typo3/sysext/rtehtmlarea/Classes/Extension/TableOperations.php index 14b74e80ff08165391de19a6cc854e5b48dc0678..57ffd414f5dfdd634078a4fe1f6a4a0017e4aa49 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/TableOperations.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/TableOperations.php @@ -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); } /** diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/TextIndicator.php b/typo3/sysext/rtehtmlarea/Classes/Extension/TextIndicator.php index cb22b99bdc8751d073f95fa713070cdd0c50bfc5..0655048743186ebde2f54bb31007902bd27b0f2e 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/TextIndicator.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/TextIndicator.php @@ -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 ''; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Color.php b/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Color.php index d2e5863e98627838a93c9ed6c5262f22a1c70b65..984ba6acb433670495866a4a29c5df932a4ac7ca 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Color.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Color.php @@ -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); } } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3HtmlParser.php b/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3HtmlParser.php index fcb376eb8e0a2eb96819c15dd3c12ca175e74543..fdb07c8de78eb727618161f7d22a711a43246e36 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3HtmlParser.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3HtmlParser.php @@ -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); } /** diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Image.php b/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Image.php index 76f6016be3a4729fbd2b189d15c4afff52d6b505..d5ee2ffcd27c7c56ca71986bd6c076af9147d77c 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Image.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Image.php @@ -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); } } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Link.php b/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Link.php index 68ecd839a8f80bd73f16efb0cdcab368baed336c..438f4115d41da0c22e82721dcee0344b22dd3a1a 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Link.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/Typo3Link.php @@ -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'])) { diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/UndoRedo.php b/typo3/sysext/rtehtmlarea/Classes/Extension/UndoRedo.php index 4e0be09154ce10fa702da337132e6d2604288353..2274851427d1c13a787ab28fbd0c8d361505f621 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/UndoRedo.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/UndoRedo.php @@ -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 ''; } diff --git a/typo3/sysext/rtehtmlarea/Classes/Extension/UserElements.php b/typo3/sysext/rtehtmlarea/Classes/Extension/UserElements.php index 0824ed0e59719d9f2d806be147e53ebb1652610b..75ebe4c283239e8d2fadb33630442a032aeec341 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Extension/UserElements.php +++ b/typo3/sysext/rtehtmlarea/Classes/Extension/UserElements.php @@ -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); } } diff --git a/typo3/sysext/rtehtmlarea/Classes/Form/Element/RichTextElement.php b/typo3/sysext/rtehtmlarea/Classes/Form/Element/RichTextElement.php index e0fd308aca8536892b5b29abef54a8957f270bb6..e4a36cf517a15b5657ff826be1189b6a0882be4c 100644 --- a/typo3/sysext/rtehtmlarea/Classes/Form/Element/RichTextElement.php +++ b/typo3/sysext/rtehtmlarea/Classes/Form/Element/RichTextElement.php @@ -17,16 +17,193 @@ 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 */ 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(); + } + } diff --git a/typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaApi.php b/typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaApi.php index f5cf9a0f3a6e39fdac9873bdc293ea34aa5c9e8d..cf59aa7af8d1dc260049198bf817881a0f35a371 100644 --- a/typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaApi.php +++ b/typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaApi.php @@ -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 */ @@ -115,71 +96,46 @@ 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 index 70064aaf7bede74c470f4fce13d6c270b9919e87..0000000000000000000000000000000000000000 --- a/typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaBase.php +++ /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); - } - } - // Getting rid of the buttons for which we have no position - $show = array_intersect($show, $toolbarOrder); - $this->toolbar = $show; - } - - /** - * Disable some plugins - */ - public 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) { - if ($this->registeredPlugins[$pluginId]->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) { - 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) { - if ($this->isPluginEnabled($pluginId)) { - $this->convertToolbarForHtmlAreaArray = array_unique(array_merge($this->convertToolbarForHtmlAreaArray, $plugin->getConvertToolbarForHtmlAreaArray())); - } - } - } - - /** - * Convert the TYPO3 names of buttons into the names for htmlArea RTE - * - * @param string buttonname (typo3-name) - * @return string buttonname (htmlarea-name) - */ - public function convertToolbarForHTMLArea($button) { - return $this->convertToolbarForHtmlAreaArray[$button]; - } - - /** - * Add RTE main scripts and plugin scripts - * - * @param int $RTEcounter: The index number of the current RTE editing area within the form. @deprecated since TYPO3 CMS 7, will be removed with TYPO3 CMS 8 - * @return void - */ - protected function addRteJsFiles($RTEcounter = NULL) { - if ($RTEcounter !== NULL) { - GeneralUtility::deprecationLog('$RTEcounter parameter is deprecated and ignored'); - } - - // 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' - ); - foreach ($components as $component) { - $this->pageRenderer->addJsFile($this->getFullFileName('EXT:' . $this->ID . '/Resources/Public/JavaScript/HTMLArea/' . $component . '.js')); - } - foreach ($this->pluginEnabledCumulativeArray as $pluginId) { - $extensionKey = is_object($this->registeredPlugins[$pluginId]) ? $this->registeredPlugins[$pluginId]->getExtensionKey() : $this->ID; - $fileName = 'EXT:' . $extensionKey . '/Resources/Public/JavaScript/Plugins/' . $pluginId . '.js'; - $absolutePath = GeneralUtility::getFileAbsFileName($fileName); - if (file_exists($absolutePath)) { - $this->pageRenderer->addJsFile($this->getFullFileName($fileName)); - } else { - // Backward compatibility - $pluginName = strtolower(preg_replace('/([a-z])([A-Z])([a-z])/', '$1-$2$3', $pluginId)); - $fileName = 'EXT:' . $extensionKey . '/htmlarea/plugins/' . $pluginId . '/' . $pluginName . '.js'; - $absolutePath = GeneralUtility::getFileAbsFileName($fileName); - if (file_exists($absolutePath)) { - $this->pageRenderer->addJsFile($this->getFullFileName($fileName)); - } - } - } - foreach ($components2 as $component) { - $this->pageRenderer->addJsFile($this->getFullFileName('EXT:' . $this->ID . '/Resources/Public/JavaScript/HTMLArea/' . $component . '.js')); - } - $this->pageRenderer->addJsFile($this->getFullFileName('EXT:' . $this->ID . '/Resources/Public/JavaScript/HTMLArea/Util/Wrap.close.js')); - } - - /** - * Return RTE initialization inline JavaScript code - * - * @return string RTE initialization inline JavaScript code - */ - protected function getRteInitJsCode() { - 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'][$this->ID]['version'] . '"; - RTEarea[0].editorUrl = "' . $this->extHttpPath . '"; - RTEarea[0].editorSkin = "' . dirname($this->editorCSS) . '/"; - RTEarea[0].editedContentCSS = "' . GeneralUtility::createVersionNumberedFilename($this->editedContentCSS) . '"; - RTEarea[0].hostUrl = "' . $this->hostURL . '"; - 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 - * - * @param int $RTEcounter: The index number of the current RTE editing area within the form. @deprecated since TYPO3 CMS 7, will be removed with TYPO3 CMS 8 - * @param string $table: The table that includes this RTE (optional, necessary for IRRE). - * @param string $uid: The uid of that table that includes this RTE (optional, necessary for IRRE). - * @param string $field: The field of that record that includes this RTE (optional). - * @param string $textAreaId ID of the textarea, to have a unigue number for the editor - * @return string the Javascript code for configuring the RTE - */ - public function registerRTEinJS($RTEcounter = NULL, $table = '', $uid = '', $field = '', $textAreaId = '') { - if ($RTEcounter !== NULL) { - GeneralUtility::deprecationLog('$RTEcounter parameter is deprecated and ignored'); - } - $configureRTEInJavascriptString = ' - if (typeof configureEditorInstance === "undefined") { - configureEditorInstance = new Object(); - } - configureEditorInstance["' . $textAreaId . '"] = function() { - if (typeof RTEarea === "undefined" || typeof HTMLArea === "undefined") { - window.setTimeout("configureEditorInstance[\'' . $textAreaId . '\']();", 40); - } else { - editornumber = "' . $textAreaId . '"; - RTEarea[editornumber] = new Object(); - RTEarea[editornumber].RTEtsConfigParams = "&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams()) . '"; - RTEarea[editornumber].number = editornumber; - RTEarea[editornumber].deleted = false; - RTEarea[editornumber].textAreaId = "' . $textAreaId . '"; - RTEarea[editornumber].id = "RTEarea" + editornumber; - RTEarea[editornumber].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'])) . '"; - RTEarea[editornumber].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']) . '"; - RTEarea[editornumber].resizable = ' . (is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteResize']) && $GLOBALS['BE_USER']->uc['rteResize'] ? 'true' : (trim($this->thisConfig['rteResize']) ? 'true' : 'false')) . '; - RTEarea[editornumber].maxHeight = "' . (is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteMaxHeight']) && (int)$GLOBALS['BE_USER']->uc['rteMaxHeight'] ? trim($GLOBALS['BE_USER']->uc['rteMaxHeight']) : ((int)$this->thisConfig['rteMaxHeight'] ?: '2000')) . '"; - RTEarea[editornumber].fullScreen = ' . ($this->fullScreen ? 'true' : 'false') . '; - RTEarea[editornumber].showStatusBar = ' . (trim($this->thisConfig['showStatusBar']) ? 'true' : 'false') . '; - RTEarea[editornumber].enableWordClean = ' . (trim($this->thisConfig['enableWordClean']) ? 'true' : 'false') . '; - RTEarea[editornumber].htmlRemoveComments = ' . (trim($this->thisConfig['removeComments']) ? 'true' : 'false') . '; - RTEarea[editornumber].disableEnterParagraphs = ' . (trim($this->thisConfig['disableEnterParagraphs']) ? 'true' : 'false') . '; - RTEarea[editornumber].disableObjectResizing = ' . (trim($this->thisConfig['disableObjectResizing']) ? 'true' : 'false') . '; - RTEarea[editornumber].removeTrailingBR = ' . (trim($this->thisConfig['removeTrailingBR']) ? 'true' : 'false') . '; - RTEarea[editornumber].useCSS = ' . (trim($this->thisConfig['useCSS']) ? 'true' : 'false') . '; - RTEarea[editornumber].keepButtonGroupTogether = ' . (trim($this->thisConfig['keepButtonGroupTogether']) ? 'true' : 'false') . '; - RTEarea[editornumber].disablePCexamples = ' . (trim($this->thisConfig['disablePCexamples']) ? 'true' : 'false') . '; - RTEarea[editornumber].showTagFreeClasses = ' . (trim($this->thisConfig['showTagFreeClasses']) ? 'true' : 'false') . '; - RTEarea[editornumber].useHTTPS = ' . (trim(stristr($this->siteURL, 'https')) || $this->thisConfig['forceHTTPS'] ? 'true' : 'false') . '; - RTEarea[editornumber].tceformsNested = ' . (count($this->globalOptions) ? json_encode($this->globalOptions['tabAndInlineStack']) : '[]') . '; - RTEarea[editornumber].dialogueWindows = new Object();'; - if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromTop'])) { - $configureRTEInJavascriptString .= ' - RTEarea[editornumber].dialogueWindows.positionFromTop = ' . (int)$this->thisConfig['dialogueWindows.']['defaultPositionFromTop'] . ';'; - } - if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'])) { - $configureRTEInJavascriptString .= ' - RTEarea[editornumber].dialogueWindows.positionFromLeft = ' . (int)$this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'] . ';'; - } - // The following properties apply only to the backend - if (!$this->is_FE()) { - $configureRTEInJavascriptString .= ' - RTEarea[editornumber].sys_language_content = "' . $this->contentLanguageUid . '"; - RTEarea[editornumber].typo3ContentLanguage = "' . $this->contentTypo3Language . '"; - RTEarea[editornumber].typo3ContentCharset = "' . $this->contentCharset . '"; - RTEarea[editornumber].userUid = "' . $this->userUid . '";'; - } - // Setting the plugin flags - $configureRTEInJavascriptString .= LF . 'RTEarea[editornumber].plugin = new Object();'; - foreach ($this->pluginEnabledArray as $pluginId) { - $configureRTEInJavascriptString .= LF . 'RTEarea[editornumber].plugin.' . $pluginId . ' = true;'; - } - // Setting the buttons configuration - $configureRTEInJavascriptString .= ' - RTEarea[editornumber].buttons = new Object();'; - if (is_array($this->thisConfig['buttons.'])) { - foreach ($this->thisConfig['buttons.'] as $buttonIndex => $conf) { - $button = substr($buttonIndex, 0, -1); - if (is_array($conf)) { - $configureRTEInJavascriptString .= ' - RTEarea[editornumber].buttons.' . $button . ' = ' . $this->buildNestedJSArray($conf) . ';'; - } - } - } - // Setting the list of tags to be removed if specified in the RTE config - if (trim($this->thisConfig['removeTags'])) { - $configureRTEInJavascriptString .= ' - RTEarea[editornumber].htmlRemoveTags = /^(' . implode('|', GeneralUtility::trimExplode(',', $this->thisConfig['removeTags'], TRUE)) . ')$/i;'; - } - // Setting the list of tags to be removed with their contents if specified in the RTE config - if (trim($this->thisConfig['removeTagsAndContents'])) { - $configureRTEInJavascriptString .= ' - RTEarea[editornumber].htmlRemoveTagsAndContents = /^(' . implode('|', GeneralUtility::trimExplode(',', $this->thisConfig['removeTagsAndContents'], TRUE)) . ')$/i;'; - } - // Setting array of custom tags if specified in the RTE config - if (!empty($this->thisConfig['customTags'])) { - $customTags = GeneralUtility::trimExplode(',', $this->thisConfig['customTags'], TRUE); - if (!empty($customTags)) { - $configureRTEInJavascriptString .= ' - 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); - } - $configureRTEInJavascriptString .= ' - RTEarea[editornumber].pageStyle = ["' . implode('","', $versionNumberedFileNames) . '"];'; - $configureRTEInJavascriptString .= $this->buildJSClassesConfig(); - // Add Javascript configuration for registered plugins - foreach ($this->registeredPlugins as $pluginId => $plugin) { - if ($this->isPluginEnabled($pluginId)) { - $configureRTEInJavascriptString .= $plugin->buildJavascriptConfiguration('editornumber'); - } - } - // Avoid premature reference to HTMLArea when being initially loaded by IRRE Ajax call - $configureRTEInJavascriptString .= ' - RTEarea[editornumber].toolbar = ' . $this->getJSToolbarArray() . '; - RTEarea[editornumber].convertButtonId = ' . json_encode(array_flip($this->convertToolbarForHtmlAreaArray)) . '; - RTEarea.initEditor(editornumber); - } - }; - configureEditorInstance["' . $textAreaId . '"]();'; - return $configureRTEInJavascriptString; - } - - /** - * 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 - */ - public function isPluginEnabled($pluginId) { - return in_array($pluginId, $this->pluginEnabledArray); - } - - /** - * Return Javascript configuration of classes - * - * @param int $RTEcounter: The index number of the current RTE editing area within the form. @deprecated since TYPO3 CMS 7, will be removed with TYPO3 CMS 8 - * @return string Javascript configuration of classes - */ - public function buildJSClassesConfig($RTEcounter = NULL) { - if ($RTEcounter !== NULL) { - GeneralUtility::deprecationLog('$RTEcounter parameter is deprecated and ignored'); - } - // Include JS arrays of configured classes - $configureRTEInJavascriptString = ' - RTEarea[editornumber].classesUrl = "' . ($this->is_FE() && $GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . $this->writeTemporaryFile(('classes_' . $this->language), 'js', $this->buildJSClassesArray()) . '";'; - return $configureRTEInJavascriptString; - } - - /** - * Return JS arrays of classes configuration - * - * @return string JS classes arrays - */ - public function buildJSClassesArray() { - if ($this->is_FE()) { - $RTEProperties = $this->RTEsetup; - } else { - $RTEProperties = $this->RTEsetup['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, '.'); - $classesArray['labels'][$className] = trim($conf['name']) ? $this->getPageConfigLabel($conf['name'], FALSE) : ''; - $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 - */ - public 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/rtehtmlarea directory 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 writtten to typo3temp/rtehtmlarea - */ - public function writeTemporaryFile($label, $fileExtension = 'js', $contents = '') { - $relativeFilename = 'typo3temp/' . $this->ID . '_' . 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) { - $extensionKey = is_object($this->registeredPlugins[$pluginId]) ? $this->registeredPlugins[$pluginId]->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 . '_' . $this->OutputCharset, 'js', $javaScriptString); - } - - /** - * Get all labels from a specific label file, merge default - * labels and target language labels. - * - * @param $fileName - * @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->convertToolbarForHTMLArea($item)) { - $group[] = $this->convertToolbarForHTMLArea($item); - } - break; - default: - if (in_array($item, $this->toolbar)) { - // Add the item to the group - $convertedItem = $this->convertToolbarForHTMLArea($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); - } - - /** - * Localize a string using the language of the content element rather than the language of the BE interface - * - * @param string string: the label to be localized - * @return string Localized string. - */ - public function getLLContent($string) { - return GeneralUtility::quoteJSvalue($this->contentLanguageService->sL($string)); - } - - public function getPageConfigLabel($string, $JScharCode = 1) { - if ($this->is_FE()) { - if (substr($string, 0, 4) !== 'LLL:') { - // A pure string coming from Page TSConfig must be in utf-8 - $label = $GLOBALS['TSFE']->csConvObj->conv($GLOBALS['TSFE']->sL(trim($string)), 'utf-8', $this->OutputCharset); - } else { - $label = $GLOBALS['TSFE']->csConvObj->conv($GLOBALS['TSFE']->sL(trim($string)), $this->charset, $this->OutputCharset); - } - $label = str_replace('"', '\\"', str_replace('\\\'', '\'', $label)); - $label = $JScharCode ? $this->feJScharCode($label) : $label; - } else { - if (substr($string, 0, 4) !== 'LLL:') { - $label = $string; - } else { - $label = $GLOBALS['LANG']->sL(trim($string)); - } - $label = str_replace('"', '\\"', str_replace('\\\'', '\'', $label)); - $label = $JScharCode ? GeneralUtility::quoteJSvalue($label) : $label; - } - return $label; - } - - /** - * JavaScript char code - * - * @param string $str - * @return string - */ - public function feJScharCode($str) { - // Convert string to UTF-8: - if ($this->OutputCharset != 'utf-8') { - $str = $GLOBALS['TSFE']->csConvObj->utf8_encode($str, $this->OutputCharset); - } - // Convert the UTF-8 string into a 'JavaScript-safe' encoded string: - return GeneralUtility::quoteJSvalue($str); - } - - /** - * 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 - */ - public 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->is_FE() || $this->isFrontendEditActive() - ? ExtensionManagementUtility::siteRelPath($extKey) - : ExtensionManagementUtility::extRelPath($extKey)) - . $local; - } - } else { - $path = ($this->is_FE() || $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. - * This is for submit function of the form. - * - * @param int $RTEcounter: The index number of the current RTE editing area within the form. @deprecated since TYPO3 CMS 7, will be removed with TYPO3 CMS 8 - * @param string $formName: the name of the form - * @param string $textareaId: the id of the textarea - * @param string $textareaName: the name of the textarea - * @return string Javascript code - */ - public function setSaveRTE($RTEcounter, $formName, $textareaId, $textareaName) { - if ($RTEcounter !== NULL) { - GeneralUtility::deprecationLog('$RTEcounter parameter is deprecated and ignored'); - } - return 'if (RTEarea["' . $textareaId . '"]) { document.' . $formName . '["' . $textareaName . '"].value = RTEarea["' . $textareaId . '"].editor.getHTML(); } else { OK = 0; };'; - } - - /** - * Return the Javascript code for copying the HTML code from the editor into the hidden input field. - * This is for submit function of the form. - * - * @param int $RTEcounter: The index number of the current RTE editing area within the form. - * @param string $formName: the name of the form - * @param string $textareaId: the id of the textarea - * @return string Javascript code - * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8 - */ - public function setDeleteRTE($RTEcounter, $formName, $textareaId) { - GeneralUtility::logDeprecatedFunction(); - return 'if (RTEarea["' . $textareaId . '"]) { RTEarea["' . $textareaId . '"].deleted = true;}'; - } - - /** - * Return TRUE if we are in the FE, but not in the FE editing feature of BE. - * - * @return bool - */ - public function is_FE() { - return is_object($GLOBALS['TSFE']) && !$this->isFrontendEditActive() && TYPO3_MODE == 'FE'; - } - - /** - * Checks whether frontend editing is active. - * - * @return boolean - */ - public function isFrontendEditActive() { - return is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->beUserLogin && $GLOBALS['BE_USER']->frontendEdit instanceof \TYPO3\CMS\Core\FrontendEditing\FrontendEditingController; - } - - /** - * Client Browser Information - * - * @param string $userAgent: The useragent string, \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('HTTP_USER_AGENT') - * @return array Contains keys "useragent", "browser", "version", "system - */ - public function clientInfo($userAgent = '') { - if (!$userAgent) { - $userAgent = GeneralUtility::getIndpEnv('HTTP_USER_AGENT'); - } - $browserInfo = \TYPO3\CMS\Core\Utility\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'] = \TYPO3\CMS\Core\Utility\ClientUtility::getVersion($browserInfo['all'][$engine]); - break; - } - } - } - return $browserInfo; - } - - /** - * 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 - */ - public function logDeprecatedProperty($deprecatedProperty, $useProperty, $version) { - $backendUser = $this->getBackendUserAuthentication(); - $languageServire = $this->getLanguageService(); - if (!$this->thisConfig['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->thePid); - GeneralUtility::deprecationLog($message); - if (is_object($GLOBALS['BE_USER']) && $this->thisConfig['logDeprecatedProperties.']['logAlsoToBELog']) { - $message = sprintf($languageServire->getLL('deprecatedPropertyMessage'), $deprecatedProperty, $useProperty, $version, $this->thePid); - $backendUser->simplelog($message, $this->ID); - } - } - } - - /*************************** - * - * OTHER FUNCTIONS: (from Classic RTE) - * - ***************************/ - /** - * @return string - */ - public function RTEtsConfigParams() { - if ($this->is_FE()) { - return ''; - } else { - $p = BackendUtility::getSpecConfParametersFromArray($this->specConf['rte_transform']['parameters']); - return $this->elementParts[0] . ':' . $this->elementParts[1] . ':' . $this->elementParts[2] . ':' . $this->thePid . ':' . $this->typeVal . ':' . $this->tscPID . ':' . $p['imgpath']; - } - } - - /** - * Clean list - * - * @param string $str - * @return string - */ - public function cleanList($str) { - if (strstr($str, '*')) { - $str = '*'; - } else { - $str = implode(',', array_unique(GeneralUtility::trimExplode(',', $str, TRUE))); - } - return $str; - } - - /** - * Filter style element - * - * @param string $elValue - * @param string $matchList - * @return string - */ - public function filterStyleEl($elValue, $matchList) { - $matchParts = GeneralUtility::trimExplode(',', $matchList, TRUE); - $styleParts = explode(';', $elValue); - $nStyle = array(); - foreach ($styleParts as $k => $p) { - $pp = GeneralUtility::trimExplode(':', $p); - if ($pp[0] && $pp[1]) { - foreach ($matchParts as $el) { - $star = substr($el, -1) == '*'; - if ($pp[0] === (string)$el || $star && GeneralUtility::isFirstPartOfStr($pp[0], substr($el, 0, -1))) { - $nStyle[] = $pp[0] . ':' . $pp[1]; - } else { - unset($styleParts[$k]); - } - } - } else { - unset($styleParts[$k]); - } - } - return implode('; ', $nStyle); - } - - /** - * @return LanguageService - */ - protected function getLanguageService() { - return $GLOBALS['LANG']; - } - - /** - * @return BackendUserAuthentication - */ - protected function getBackendUserAuthentication() { - return $GLOBALS['BE_USER']; - } - - /** - * @return DatabaseConnection - */ - protected function getDatabaseConnection() { - return $GLOBALS['TYPO3_DB']; - } -} diff --git a/typo3/sysext/rtehtmlarea/Resources/Private/Language/locallang_tooltips.xlf b/typo3/sysext/rtehtmlarea/Resources/Private/Language/locallang_tooltips.xlf index 893842e22c2f056f64672ba0ba72b3d7f50af0ba..3d8893fd55e5a39b574d7a9e0059983f7a0903c4 100644 --- a/typo3/sysext/rtehtmlarea/Resources/Private/Language/locallang_tooltips.xlf +++ b/typo3/sysext/rtehtmlarea/Resources/Private/Language/locallang_tooltips.xlf @@ -75,9 +75,6 @@ <trans-unit id="about"> <source>About this editor</source> </trans-unit> - <trans-unit id="showhelp"> - <source>Help using editor</source> - </trans-unit> <trans-unit id="textindicator"> <source>Current style</source> </trans-unit> diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/Css/Skin/Plugins/default-inline.css b/typo3/sysext/rtehtmlarea/Resources/Public/Css/Skin/Plugins/default-inline.css deleted file mode 100644 index 9aeb9e762156f173888f621eabc542498daf87eb..0000000000000000000000000000000000000000 --- a/typo3/sysext/rtehtmlarea/Resources/Public/Css/Skin/Plugins/default-inline.css +++ /dev/null @@ -1,27 +0,0 @@ -/* Selectors for the DefaultInline plugin of htmlArea RTE */ -.htmlarea-action-bold { - background-image: url('../../../Images/Plugins/DefaultInline/bold.gif') !important; -} -.htmlarea-action-italic { - background-image: url('../../../Images/Plugins/DefaultInline/italic.gif') !important; -} -.htmlarea-action-strike-through { - background-image: url('../../../Images/Plugins/DefaultInline/strikethrough.gif') !important; -} -.htmlarea-action-subscript { - background-image: url('../../../Images/Plugins/DefaultInline/subscript.gif') !important; -} -.htmlarea-action-superscript { - background-image: url('../../../Images/Plugins/DefaultInline/superscript.gif') !important; -} -.htmlarea-action-underline { - background-image: url('../../../Images/Plugins/DefaultInline/underline.gif') !important; -} -.htmlarea-action-bold, -.htmlarea-action-italic, -.htmlarea-action-strike-through, -.htmlarea-action-subscript, -.htmlarea-action-superscript, -.htmlarea-action-underline { - background-position: 0 0 !important; -} diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Ajax/Ajax.js b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Ajax/Ajax.js index d1a119be3204d5176401d1372518ba73e19f5c88..0325ab23446bebfb0fb9a44fa6e91aff51317da4 100644 --- a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Ajax/Ajax.js +++ b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Ajax/Ajax.js @@ -78,7 +78,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Ajax/Ajax', postData: function (url, data, callback, scope) { var success = false, self = this; - data.charset = this.editor.config.typo3ContentCharset ? this.editor.config.typo3ContentCharset : 'utf-8'; + data.charset = 'utf-8'; var params = ''; for (var parameter in data) { params += (params.length ? '&' : '') + parameter + '=' + encodeURIComponent(data[parameter]); diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Configuration/Config.js b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Configuration/Config.js index 7f532a181c26cd114061c641c3d1577f25663fbd..1e33d4da116529021ec23cd93ef23b400345cc9c 100644 --- a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Configuration/Config.js +++ b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Configuration/Config.js @@ -24,8 +24,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Configuration/Config', */ var Config = function (editorId) { this.editorId = editorId; - // if the site is secure, create a secure iframe - this.useHTTPS = false; // for Mozilla this.useCSS = false; this.enableMozillaExtension = true; diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Framework.js b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Framework.js index 7cf60d0173654d8a055e200428288c7258cbe0ca..941b800ef300079e01ffae71e8d91022247d1487 100644 --- a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Framework.js +++ b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Framework.js @@ -303,7 +303,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework', * Resize the framework to its initial size */ resizeFramework: function () { - var frameworkHeight = this.fullScreen ? Typo3.getWindowSize().height - 25 : parseInt(this.textAreaInitialSize.height) + this.toolbar.getHeight() - this.statusBar.getHeight(); + var frameworkHeight = this.fullScreen ? Typo3.getWindowSize().height - 50 : parseInt(this.textAreaInitialSize.height) + this.toolbar.getHeight() - this.statusBar.getHeight(); if (this.textAreaInitialSize.width.indexOf('%') === -1) { // Width is specified in pixels // Initial framework sizing @@ -378,7 +378,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework', } else { var self = this; window.setTimeout(function () { - self.onIframeReady(); + self.onIframeReady(); }, 50); } }, diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/HTMLArea.js b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/HTMLArea.js index 79bfcaa5eff629f58400c2e847d3db704200e657..e652600914145c162dc64cfccf89bffd6b5fe2ec 100644 --- a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/HTMLArea.js +++ b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/HTMLArea.js @@ -42,12 +42,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/HTMLArea', if (!HTMLArea.isReady) { // Apply global configuration settings Util.apply(HtmlArea, RTEarea[0]); - if (!HtmlArea.editorSkin) { - HtmlArea.editorSkin = HtmlArea.editorUrl + 'Resources/Public/Css/Skin/'; - } - if (typeof HtmlArea.editedContentCSS !== 'string' || HtmlArea.editedContentCSS === '') { - HtmlArea.editedContentCSS = HtmlArea.editorSkin + 'htmlarea-edited-content.css'; - } HTMLArea.isReady = true; HtmlArea.appendToLog('', 'HTMLArea', 'init', 'Editor url set to: ' + HtmlArea.editorUrl, 'info'); HtmlArea.appendToLog('', 'HTMLArea', 'init', 'Editor content skin CSS set to: ' + HtmlArea.editedContentCSS, 'info'); diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/DefaultLink.js b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/DefaultLink.js index 58471f65719edab530096f59a29a7dad2eb1a145..6ca956626119cecc51259c872580279d8c6df766 100644 --- a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/DefaultLink.js +++ b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/DefaultLink.js @@ -33,7 +33,6 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/DefaultLink', configurePlugin: function (editor) { this.baseURL = this.editorConfiguration.baseURL; this.pageTSConfiguration = this.editorConfiguration.buttons.link; - this.stripBaseUrl = this.pageTSConfiguration && this.pageTSConfiguration.stripBaseUrl && this.pageTSConfiguration.stripBaseUrl; this.showTarget = !(this.pageTSConfiguration && this.pageTSConfiguration.targetSelector && this.pageTSConfiguration.targetSelector.disabled); /** @@ -101,9 +100,6 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/DefaultLink', * This function gets called when the editor is generated */ onGenerate: function () { - if (UserAgent.isIE) { - this.editor.iframe.getHtmlRenderer().stripBaseUrl = this.stripBaseUrl; - } }, /* * This function gets called when the button was pressed. @@ -139,7 +135,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/DefaultLink', }; } else { this.parameters = { - href: (UserAgent.isIE && this.stripBaseUrl) ? this.stripBaseURL(this.link.href) : this.link.getAttribute('href'), + href: this.link.getAttribute('href'), title: this.link.title, target: this.link.target }; @@ -357,24 +353,6 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/DefaultLink', } this.editor.getSelection().execCommand('Unlink', false, ''); }, - /* - * IE makes relative links absolute. This function reverts this conversion. - * - * @param string url: the url - * - * @return string the url stripped out of the baseurl - */ - stripBaseURL: function (url) { - var baseurl = this.baseURL; - // strip to last directory in case baseurl points to a file - baseurl = baseurl.replace(/[^\/]+$/, ''); - var basere = new RegExp(baseurl); - url = url.replace(basere, ''); - // strip host-part of URL which is added by MSIE to links relative to server root - baseurl = baseurl.replace(/^(https?:\/\/[^\/]+)(.*)$/, "$1"); - basere = new RegExp(baseurl); - return url.replace(basere, ''); - }, /* * This function gets called when the toolbar is updated */ diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/SpellChecker.js b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/SpellChecker.js index 916066f106614501bec8f7d9dbed0e3dda361aa1..69d16be070c607ce9736f505bae65980fc1f59c1 100644 --- a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/SpellChecker.js +++ b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/SpellChecker.js @@ -33,7 +33,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/SpellChecker', configurePlugin: function(editor) { this.pageTSconfiguration = this.editorConfiguration.buttons.spellcheck; this.contentISOLanguage = this.pageTSconfiguration.contentISOLanguage; - this.contentCharset = this.pageTSconfiguration.contentCharset; + this.contentCharset = 'utf-8'; this.spellCheckerMode = this.pageTSconfiguration.spellCheckerMode; this.enablePersonalDicts = this.pageTSconfiguration.enablePersonalDicts; this.userUid = this.editorConfiguration.userUid; diff --git a/typo3/sysext/rtehtmlarea/ext_localconf.php b/typo3/sysext/rtehtmlarea/ext_localconf.php index a549d6d545608048f3ae5d998198b588ba5a2614..6e7ef8191b5a1256871b4e9349f14f2527693198 100644 --- a/typo3/sysext/rtehtmlarea/ext_localconf.php +++ b/typo3/sysext/rtehtmlarea/ext_localconf.php @@ -1,9 +1,6 @@ <?php defined('TYPO3_MODE') or die(); -// Registering the RTE object -$GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_reg']['rtehtmlarea'] = array('objRef' => \TYPO3\CMS\Rtehtmlarea\RteHtmlAreaBase::class); - // Register FormEngine node type resolver hook to render RTE in FormEngine if enabled $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeResolver'][1433167475] = array( 'nodeName' => 'text', @@ -69,7 +66,6 @@ $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['MicrodataSchem // Inline Elements configuration $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['DefaultInline'] = array(); $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['DefaultInline']['objectReference'] = \TYPO3\CMS\Rtehtmlarea\Extension\DefaultInline::class; -$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['DefaultInline']['addIconsToSkin'] = 1; if ($_EXTCONF['enableInlineElements']) { $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['InlineElements'] = array(); $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['rtehtmlarea']['plugins']['InlineElements']['objectReference'] = \TYPO3\CMS\Rtehtmlarea\Extension\InlineElements::class; diff --git a/typo3/sysext/t3skin/rtehtmlarea/htmlarea.css b/typo3/sysext/t3skin/rtehtmlarea/htmlarea.css index ffec793972dcec89c7d73486f09c07831df74738..551909c241db76996b40269b408855f128ae3d64 100644 --- a/typo3/sysext/t3skin/rtehtmlarea/htmlarea.css +++ b/typo3/sysext/t3skin/rtehtmlarea/htmlarea.css @@ -527,7 +527,7 @@ .htmlarea-action-unordered-list { background-position: 0 -4756px !important; } .htmlarea-action-user-element-edit { background-position: 0 -4814px !important; } .htmlarea-action-variable { background-position: 0 -4872px !important; } - + /* ExtJs combo boxes */ .x-combo-list { border-color:#bcbcbc;