PageRenderTime 54ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/typo3/sysext/rtehtmlarea/class.tx_rtehtmlarea_base.php

https://github.com/andreaswolf/typo3-tceforms
PHP | 1507 lines | 1030 code | 97 blank | 380 comment | 221 complexity | f189090ad9f6f9fae7ed22b0a4b782c2 MD5 | raw file
Possible License(s): Apache-2.0, BSD-2-Clause, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /***************************************************************
  3. * Copyright notice
  4. *
  5. * (c) 2004-2011 Kasper Skårhøj (kasper@typo3.com)
  6. * (c) 2004-2011 Philipp Borgmann <philipp.borgmann@gmx.de>
  7. * (c) 2004-2011 Stanislas Rolland <typo3(arobas)sjbr.ca>
  8. * All rights reserved
  9. *
  10. * This script is part of the TYPO3 project. The TYPO3 project is
  11. * free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * The GNU General Public License can be found at
  17. * http://www.gnu.org/copyleft/gpl.html.
  18. * A copy is found in the textfile GPL.txt and important notices to the license
  19. * from the author is found in LICENSE.txt distributed with these scripts.
  20. *
  21. *
  22. * This script is distributed in the hope that it will be useful,
  23. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  24. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  25. * GNU General Public License for more details.
  26. *
  27. * This copyright notice MUST APPEAR in all copies of the script!
  28. ***************************************************************/
  29. /**
  30. * A RTE using the htmlArea editor
  31. *
  32. * @author Philipp Borgmann <philipp.borgmann@gmx.de>
  33. * @author Stanislas Rolland <typo3(arobas)sjbr.ca>
  34. *
  35. * $Id$ *
  36. */
  37. class tx_rtehtmlarea_base extends t3lib_rteapi {
  38. // Configuration of supported browsers
  39. var $conf_supported_browser = array (
  40. 'msie' => array (
  41. array (
  42. 'version' => 6.0,
  43. 'system' => array(
  44. 'allowed' => array(
  45. 'winNT',
  46. 'win98',
  47. 'win95',
  48. ),
  49. ),
  50. ),
  51. ),
  52. 'gecko' => array (
  53. array (
  54. 'version' => 1.8,
  55. ),
  56. ),
  57. 'webkit' => array (
  58. array (
  59. 'version' => 523,
  60. 'system' => array(
  61. 'disallowed' => array(
  62. 'iOS',
  63. 'android',
  64. ),
  65. ),
  66. ),
  67. ),
  68. 'opera' => array (
  69. array (
  70. 'version' => 9.62,
  71. 'system' => array(
  72. 'disallowed' => array(
  73. 'iOS',
  74. 'android',
  75. ),
  76. ),
  77. ),
  78. )
  79. );
  80. // Always hide these toolbar buttons (TYPO3 button name)
  81. var $conf_toolbar_hide = array (
  82. 'showhelp', // Has no content yet
  83. );
  84. // The order of the toolbar: the name is the TYPO3-button name
  85. var $defaultToolbarOrder;
  86. // Conversion array: TYPO3 button names to htmlArea button names
  87. var $convertToolbarForHtmlAreaArray = array (
  88. 'showhelp' => 'ShowHelp',
  89. 'space' => 'space',
  90. 'bar' => 'separator',
  91. 'linebreak' => 'linebreak',
  92. );
  93. var $pluginButton = array();
  94. var $pluginLabel = array();
  95. // Alternative style for RTE <div> tag.
  96. public $RTEdivStyle;
  97. // Relative path to this extension. It ends with "/"
  98. public $extHttpPath;
  99. public $backPath = '';
  100. // TYPO3 site url
  101. public $siteURL;
  102. // TYPO3 host url
  103. public $hostURL;
  104. // Typo3 version
  105. public $typoVersion;
  106. // Identifies the RTE as being the one from the "rtehtmlarea" extension if any external code needs to know
  107. var $ID = 'rtehtmlarea';
  108. // If set, the content goes into a regular TEXT area field - for developing testing of transformations.
  109. var $debugMode = FALSE;
  110. // For the editor
  111. var $client;
  112. /**
  113. * Reference to parent object, which is an instance of the TCEforms
  114. *
  115. * @var t3lib_TCEforms
  116. */
  117. var $TCEform;
  118. var $elementId;
  119. var $elementParts;
  120. var $tscPID;
  121. var $typeVal;
  122. var $thePid;
  123. var $RTEsetup;
  124. var $thisConfig;
  125. var $confValues;
  126. public $language;
  127. public $contentTypo3Language;
  128. public $contentISOLanguage;
  129. public $contentCharset;
  130. public $OutputCharset;
  131. var $editorCSS;
  132. var $specConf;
  133. var $toolbar = array(); // Save the buttons for the toolbar
  134. var $toolbarOrderArray = array();
  135. protected $pluginEnabledArray = array(); // Array of plugin id's enabled in the current RTE editing area
  136. protected $pluginEnabledCumulativeArray = array(); // Cumulative array of plugin id's enabled so far in any of the RTE editing areas of the form
  137. protected $cumulativeScripts = array();
  138. public $registeredPlugins = array(); // Array of registered plugins indexed by their plugin Id's
  139. protected $fullScreen = false;
  140. /**
  141. * Returns true if the RTE is available. Here you check if the browser requirements are met.
  142. * If there are reasons why the RTE cannot be displayed you simply enter them as text in ->errorLog
  143. *
  144. * @return boolean TRUE if this RTE object offers an RTE in the current browser environment
  145. */
  146. function isAvailable() {
  147. $this->client = $this->clientInfo();
  148. $this->errorLog = array();
  149. if (!$this->debugMode) { // If debug-mode, let any browser through
  150. $rteIsAvailable = FALSE;
  151. $rteConfBrowser = $this->conf_supported_browser;
  152. if (is_array($rteConfBrowser)) {
  153. foreach ($rteConfBrowser as $browser => $browserConf) {
  154. if ($browser == $this->client['browser']) {
  155. // Config for Browser found, check it:
  156. if (is_array($browserConf)) {
  157. foreach ($browserConf as $browserConfSub) {
  158. if ($browserConfSub['version'] <= $this->client['version'] || empty($browserConfSub['version'])) {
  159. // Version is supported
  160. if (is_array($browserConfSub['system'])) {
  161. // Check against allowed systems
  162. if (is_array($browserConfSub['system']['allowed'])) {
  163. foreach ($browserConfSub['system']['allowed'] as $system) {
  164. if (in_array($system, $this->client['all_systems'])) {
  165. $rteIsAvailable = TRUE;
  166. break;
  167. }
  168. }
  169. } else {
  170. // All allowed
  171. $rteIsAvailable = TRUE;
  172. }
  173. // Check against disallowed systems
  174. if (is_array($browserConfSub['system']['disallowed'])) {
  175. foreach ($browserConfSub['system']['disallowed'] as $system) {
  176. if (in_array($system, $this->client['all_systems'])) {
  177. $rteIsAvailable = FALSE;
  178. break;
  179. }
  180. }
  181. }
  182. } else {
  183. // No system config: system is supported
  184. $rteIsAvailable = TRUE;
  185. break;
  186. }// End of System
  187. }// End of Version
  188. }// End of foreach-BrowserSubpart
  189. } else {
  190. // no config for this browser found, so all versions or system with this browsers are allow
  191. $rteIsAvailable = TRUE;
  192. break;
  193. }
  194. } // End of Browser Check
  195. } // foreach: Browser Check
  196. } else {
  197. // no Browser config for this RTE-Editor, so all Clients are allow
  198. }
  199. if (!$rteIsAvailable) {
  200. $this->errorLog[] = 'RTE: Browser not supported.';
  201. }
  202. if (t3lib_div::int_from_ver(TYPO3_version) < 4000000) {
  203. $rteIsAvailable = FALSE;
  204. $this->errorLog[] = 'rte: This version of htmlArea RTE cannot run under this version of TYPO3.';
  205. }
  206. }
  207. return $rteIsAvailable;
  208. }
  209. /**
  210. * Draws the RTE as an iframe
  211. *
  212. * @param object Reference to parent object, which is an instance of the TCEforms.
  213. * @param string The table name
  214. * @param string The field name
  215. * @param array The current row from which field is being rendered
  216. * @param array 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.
  217. * @param array "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
  218. * @param array Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
  219. * @param string Record "type" field value.
  220. * @param string 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!
  221. * @param integer PID value of record (true parent page id)
  222. * @return string HTML code for RTE!
  223. */
  224. function drawRTE($parentObject, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue) {
  225. global $BE_USER, $LANG, $TYPO3_DB, $TYPO3_CONF_VARS;
  226. $this->TCEform = $parentObject;
  227. $inline = $this->TCEform->inline;
  228. $LANG->includeLLFile('EXT:' . $this->ID . '/locallang.xml');
  229. $this->client = $this->clientInfo();
  230. $this->typoVersion = t3lib_div::int_from_ver(TYPO3_version);
  231. $this->userUid = 'BE_' . $BE_USER->user['uid'];
  232. // Draw form element:
  233. if ($this->debugMode) { // Draws regular text area (debug mode)
  234. $item = parent::drawRTE($this->TCEform, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue);
  235. } else { // Draw real RTE
  236. /* =======================================
  237. * INIT THE EDITOR-SETTINGS
  238. * =======================================
  239. */
  240. // Set backPath
  241. $this->backPath = $this->TCEform->backPath;
  242. // Get the path to this extension:
  243. $this->extHttpPath = $this->backPath . t3lib_extMgm::extRelPath($this->ID);
  244. // Get the site URL
  245. $this->siteURL = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
  246. // Get the host URL
  247. $this->hostURL = $this->siteURL . TYPO3_mainDir;
  248. // Element ID + pid
  249. $this->elementId = $PA['itemFormElName']; // Form element name
  250. $this->elementParts = explode('][',preg_replace('/\]$/','',preg_replace('/^(TSFE_EDIT\[data\]\[|data\[)/','',$this->elementId)));
  251. // Find the page PIDs:
  252. list($this->tscPID,$this->thePid) = t3lib_BEfunc::getTSCpid(trim($this->elementParts[0]),trim($this->elementParts[1]),$thePidValue);
  253. // Record "types" field value:
  254. $this->typeVal = $RTEtypeVal; // TCA "types" value for record
  255. // Find "thisConfig" for record/editor:
  256. unset($this->RTEsetup);
  257. $this->RTEsetup = $BE_USER->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($this->tscPID));
  258. $this->thisConfig = $thisConfig;
  259. // Special configuration and default extras:
  260. $this->specConf = $specConf;
  261. if ($this->thisConfig['forceHTTPS']) {
  262. $this->extHttpPath = preg_replace('/^(http|https)/', 'https', $this->extHttpPath);
  263. $this->siteURL = preg_replace('/^(http|https)/', 'https', $this->siteURL);
  264. $this->hostURL = preg_replace('/^(http|https)/', 'https', $this->hostURL);
  265. }
  266. // Register RTE windows
  267. $this->TCEform->RTEwindows[] = $PA['itemFormElName'];
  268. $textAreaId = preg_replace('/[^a-zA-Z0-9_:.-]/', '_', $PA['itemFormElName']);
  269. $textAreaId = htmlspecialchars(preg_replace('/^[^a-zA-Z]/', 'x', $textAreaId));
  270. /* =======================================
  271. * LANGUAGES & CHARACTER SETS
  272. * =======================================
  273. */
  274. // Languages: interface and content
  275. $this->language = $LANG->lang;
  276. if ($this->language=='default' || !$this->language) {
  277. $this->language='en';
  278. }
  279. $this->contentTypo3Language = $this->language;
  280. $this->contentISOLanguage = 'en';
  281. $this->contentLanguageUid = ($row['sys_language_uid'] > 0) ? $row['sys_language_uid'] : 0;
  282. if (t3lib_extMgm::isLoaded('static_info_tables')) {
  283. if ($this->contentLanguageUid) {
  284. $tableA = 'sys_language';
  285. $tableB = 'static_languages';
  286. $languagesUidsList = $this->contentLanguageUid;
  287. $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2,' . $tableB . '.lg_typo3';
  288. $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
  289. $whereClause = $tableA . '.uid IN (' . $languagesUidsList . ') ';
  290. $whereClause .= t3lib_BEfunc::BEenableFields($tableA);
  291. $whereClause .= t3lib_BEfunc::deleteClause($tableA);
  292. $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
  293. while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
  294. $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']).(trim($languageRow['lg_country_iso_2'])?'_'.trim($languageRow['lg_country_iso_2']):''));
  295. $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
  296. }
  297. } else {
  298. $this->contentISOLanguage = trim($this->thisConfig['defaultContentLanguage']) ? trim($this->thisConfig['defaultContentLanguage']) : 'en';
  299. $selectFields = 'lg_iso_2, lg_typo3';
  300. $tableAB = 'static_languages';
  301. $whereClause = 'lg_iso_2 = ' . $TYPO3_DB->fullQuoteStr(strtoupper($this->contentISOLanguage), $tableAB);
  302. $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
  303. while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
  304. $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
  305. }
  306. }
  307. }
  308. // Character sets: interface and content
  309. $this->charset = $LANG->charSet;
  310. $this->OutputCharset = $this->charset;
  311. $this->contentCharset = $LANG->csConvObj->charSetArray[$this->contentTypo3Language];
  312. $this->contentCharset = $this->contentCharset ? $this->contentCharset : 'iso-8859-1';
  313. $this->origContentCharSet = $this->contentCharset;
  314. $this->contentCharset = (trim($TYPO3_CONF_VARS['BE']['forceCharset']) ? trim($TYPO3_CONF_VARS['BE']['forceCharset']) : $this->contentCharset);
  315. /* =======================================
  316. * TOOLBAR CONFIGURATION
  317. * =======================================
  318. */
  319. $this->initializeToolbarConfiguration();
  320. if ($this->client['BROWSER'] == 'msie') {
  321. $this->thisConfig['keepButtonGroupTogether'] = 0;
  322. }
  323. if ($this->client['BROWSER'] == 'opera') {
  324. $this->thisConfig['keepButtonGroupTogether'] = 0;
  325. }
  326. if ($this->client['BROWSER'] == 'gecko' && $this->client['VERSION'] == '1.3') {
  327. $this->thisConfig['keepButtonGroupTogether'] = 0;
  328. }
  329. // Toolbar
  330. $this->setToolbar();
  331. // Check if some plugins need to be disabled
  332. $this->setPlugins();
  333. // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
  334. $this->pluginEnabledCumulativeArray[$this->TCEform->getRTEcounter()] = $this->pluginEnabledArray;
  335. if ($this->TCEform->getRTEcounter() > 1 && isset($this->pluginEnabledCumulativeArray[$this->TCEform->getRTEcounter()-1]) && is_array($this->pluginEnabledCumulativeArray[$this->TCEform->getRTEcounter()-1])) {
  336. $this->pluginEnabledCumulativeArray[$this->TCEform->getRTEcounter()] = array_unique(array_values(array_merge($this->pluginEnabledArray,$this->pluginEnabledCumulativeArray[$this->TCEform->getRTEcounter()-1])));
  337. }
  338. /* =======================================
  339. * SET STYLES
  340. * =======================================
  341. */
  342. // Check if wizard_rte called this for fullscreen edtition
  343. if (basename(PATH_thisScript) == 'wizard_rte.php') {
  344. $this->fullScreen = TRUE;
  345. $RTEWidth = '100%';
  346. $RTEHeight = '100%';
  347. $RTEPaddingRight = '0';
  348. $editorWrapWidth = '100%';
  349. } else {
  350. $RTEWidth = isset($BE_USER->userTS['options.']['RTESmallWidth']) ? $BE_USER->userTS['options.']['RTESmallWidth'] : '530';
  351. $RTEHeight = isset($BE_USER->userTS['options.']['RTESmallHeight']) ? $BE_USER->userTS['options.']['RTESmallHeight'] : '380';
  352. $RTEWidth = $RTEWidth + ($this->TCEform->docLarge ? (isset($BE_USER->userTS['options.']['RTELargeWidthIncrement']) ? $BE_USER->userTS['options.']['RTELargeWidthIncrement'] : '150') : 0);
  353. $RTEWidth -= ($inline->getStructureDepth() > 0 ? ($inline->getStructureDepth()+1)*$inline->getLevelMargin() : 0);
  354. $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']);
  355. if ($RTEWidthOverride) {
  356. if (strstr($RTEWidthOverride, '%')) {
  357. if ($this->client['browser'] != 'msie') {
  358. $RTEWidth = (intval($RTEWidthOverride) > 0) ? $RTEWidthOverride : '100%';
  359. }
  360. } else {
  361. $RTEWidth = (intval($RTEWidthOverride) > 0) ? intval($RTEWidthOverride) : $RTEWidth;
  362. }
  363. }
  364. $RTEWidth = strstr($RTEWidth, '%') ? $RTEWidth : $RTEWidth . 'px';
  365. $RTEHeight = $RTEHeight + ($this->TCEform->docLarge ? (isset($BE_USER->userTS['options.']['RTELargeHeightIncrement']) ? $BE_USER->userTS['options.']['RTELargeHeightIncrement'] : 0) : 0);
  366. $RTEHeightOverride = (is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteHeight']) && intval($GLOBALS['BE_USER']->uc['rteHeight'])) ? intval($GLOBALS['BE_USER']->uc['rteHeight']) : intval($this->thisConfig['RTEHeightOverride']);
  367. $RTEHeight = ($RTEHeightOverride > 0) ? $RTEHeightOverride : $RTEHeight;
  368. $RTEPaddingRight = '2px';
  369. $editorWrapWidth = '99%';
  370. }
  371. $editorWrapHeight = '100%';
  372. $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:' . $RTEHeight . 'px; width:' . $RTEWidth . '; border: 1px solid black; padding: 2px ' . $RTEPaddingRight . ' 2px 2px;';
  373. /* =======================================
  374. * LOAD CSS AND JAVASCRIPT
  375. * =======================================
  376. */
  377. // Preloading the pageStyle and including RTE skin stylesheets
  378. $this->addPageStyle();
  379. $this->addSkin();
  380. // Re-initialize the scripts array so that only the cumulative set of plugins of the last RTE on the page is used
  381. $this->cumulativeScripts[$this->TCEform->RTEcounter] = array();
  382. $this->includeScriptFiles($this->TCEform->RTEcounter);
  383. $this->buildJSMainLangFile($this->TCEform->RTEcounter);
  384. // Register RTE in JS:
  385. $this->TCEform->additionalJS_post[] = $this->registerRTEinJS($this->TCEform->RTEcounter, $table, $row['uid'], $field, $textAreaId);
  386. // Set the save option for the RTE:
  387. $this->TCEform->additionalJS_submit[] = $this->setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId, $PA['itemFormElName']);
  388. $this->TCEform->additionalJS_delete[] = $this->setDeleteRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
  389. // Loading JavaScript files and code
  390. if ($this->TCEform->RTEcounter == 1) {
  391. $this->TCEform->additionalJS_pre['rtehtmlarea-loadJScode'] = $this->loadJScode($this->TCEform->RTEcounter);
  392. }
  393. $this->TCEform->additionalCode_pre['rtehtmlarea-loadJSfiles'] = $this->loadJSfiles($this->TCEform->RTEcounter);
  394. $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
  395. $pageRenderer->enableExtJSQuickTips();
  396. if (!$GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts']) {
  397. $pageRenderer->enableExtJsDebug();
  398. }
  399. $pageRenderer->addJsFile('../t3lib/js/extjs/notifications.js');
  400. /* =======================================
  401. * DRAW THE EDITOR
  402. * =======================================
  403. */
  404. // Transform value:
  405. $value = $this->transformContent('rte',$PA['itemFormElValue'],$table,$field,$row,$specConf,$thisConfig,$RTErelPath,$thePidValue);
  406. // Further content transformation by registered plugins
  407. foreach ($this->registeredPlugins as $pluginId => $plugin) {
  408. if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "transformContent")) {
  409. $value = $plugin->transformContent($value);
  410. }
  411. }
  412. // Draw the textarea
  413. $visibility = 'hidden';
  414. $item = $this->triggerField($PA['itemFormElName']).'
  415. <div id="pleasewait' . $textAreaId . '" class="pleasewait" style="display: block;" >' . $LANG->getLL('Please wait') . '</div>
  416. <div id="editorWrap' . $textAreaId . '" class="editorWrap" style="visibility: hidden; width:' . $editorWrapWidth . '; height:' . $editorWrapHeight . ';">
  417. <textarea id="RTEarea' . $textAreaId . '" name="'.htmlspecialchars($PA['itemFormElName']).'" rows="0" cols="0" style="'.t3lib_div::deHSCentities(htmlspecialchars($this->RTEdivStyle)).'">'.t3lib_div::formatForTextarea($value).'</textarea>
  418. </div>' . LF;
  419. }
  420. // Return form item:
  421. return $item;
  422. }
  423. /**
  424. * Add link to content style sheet to document header
  425. *
  426. * @return void
  427. */
  428. protected function addPageStyle() {
  429. // Get stylesheet file name from Page TSConfig if any
  430. $filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/res/contentcss/default.css';
  431. $this->addStyleSheet(
  432. 'rtehtmlarea-page-style',
  433. $this->getFullFileName($filename),
  434. 'htmlArea RTE Content CSS',
  435. 'alternate stylesheet'
  436. );
  437. }
  438. /**
  439. * Add links to skin style sheet(s) to document header
  440. *
  441. * @return void
  442. */
  443. protected function addSkin() {
  444. // Get skin file name from Page TSConfig if any
  445. $skinFilename = trim($this->thisConfig['skin']) ? trim($this->thisConfig['skin']) : 'EXT:' . $this->ID . '/htmlarea/skins/default/htmlarea.css';
  446. $this->editorCSS = $this->getFullFileName($skinFilename);
  447. $skinDir = dirname($this->editorCSS);
  448. // Editing area style sheet
  449. $this->editedContentCSS = $skinDir . '/htmlarea-edited-content.css';
  450. $this->addStyleSheet(
  451. 'rtehtmlarea-editing-area-skin',
  452. $this->editedContentCSS
  453. );
  454. // Main skin
  455. $this->addStyleSheet(
  456. 'rtehtmlarea-skin',
  457. $this->editorCSS
  458. );
  459. // Additional icons from registered plugins
  460. foreach ($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] as $pluginId) {
  461. if (is_object($this->registeredPlugins[$pluginId])) {
  462. $pathToSkin = $this->registeredPlugins[$pluginId]->getPathToSkin();
  463. if ($pathToSkin) {
  464. $key = $this->registeredPlugins[$pluginId]->getExtensionKey();
  465. $this->addStyleSheet(
  466. 'rtehtmlarea-plugin-' . $pluginId . '-skin',
  467. ($this->is_FE() ? t3lib_extMgm::siteRelPath($key) : $this->backPath . t3lib_extMgm::extRelPath($key)) . $pathToSkin
  468. );
  469. }
  470. }
  471. }
  472. }
  473. /**
  474. * Add style sheet file to document header
  475. *
  476. * @param string $key: some key identifying the style sheet
  477. * @param string $href: uri to the style sheet file
  478. * @param string $title: value for the title attribute of the link element
  479. * @return string $relation: value for the rel attribute of the link element
  480. * @return void
  481. */
  482. protected function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
  483. // If it was not known that an RTE-enabled would be created when the page was first created, the css would not be added to head
  484. if (is_object($this->TCEform->inline) && $this->TCEform->inline->isAjaxCall) {
  485. $this->TCEform->additionalCode_pre[$key] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '" title="' . $title. '" />';
  486. } else {
  487. $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
  488. $pageRenderer->addCssFile($href, $relation, 'screen', $title);
  489. }
  490. }
  491. /**
  492. * Initialize toolbar configuration and enable registered plugins
  493. *
  494. * @return void
  495. */
  496. protected function initializeToolbarConfiguration() {
  497. // Enable registred plugins
  498. $this->enableRegisteredPlugins();
  499. // Configure toolbar
  500. $this->setToolbar();
  501. // Check if some plugins need to be disabled
  502. $this->setPlugins();
  503. // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
  504. $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = $this->pluginEnabledArray;
  505. if ($this->TCEform->RTEcounter > 1 && isset($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1]) && is_array($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])) {
  506. $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = array_unique(array_values(array_merge($this->pluginEnabledArray,$this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])));
  507. }
  508. }
  509. /**
  510. * Add registered plugins to the array of enabled plugins
  511. *
  512. */
  513. function enableRegisteredPlugins() {
  514. global $TYPO3_CONF_VARS;
  515. // Traverse registered plugins
  516. if (is_array($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'])) {
  517. foreach($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'] as $pluginId => $pluginObjectConfiguration) {
  518. $plugin = false;
  519. if (is_array($pluginObjectConfiguration) && count($pluginObjectConfiguration)) {
  520. $plugin = t3lib_div::getUserObj($pluginObjectConfiguration['objectReference']);
  521. }
  522. if (is_object($plugin)) {
  523. if ($plugin->main($this)) {
  524. $this->registeredPlugins[$pluginId] = $plugin;
  525. // Override buttons from previously registered plugins
  526. $pluginButtons = t3lib_div::trimExplode(',', $plugin->getPluginButtons(), 1);
  527. foreach ($this->pluginButton as $previousPluginId => $buttonList) {
  528. $this->pluginButton[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginButton[$previousPluginId], 1), $pluginButtons));
  529. }
  530. $this->pluginButton[$pluginId] = $plugin->getPluginButtons();
  531. $pluginLabels = t3lib_div::trimExplode(',', $plugin->getPluginLabels(), 1);
  532. foreach ($this->pluginLabel as $previousPluginId => $labelList) {
  533. $this->pluginLabel[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginLabel[$previousPluginId], 1), $pluginLabels));
  534. }
  535. $this->pluginLabel[$pluginId] = $plugin->getPluginLabels();
  536. $this->pluginEnabledArray[] = $pluginId;
  537. }
  538. }
  539. }
  540. }
  541. // Process overrides
  542. $hidePlugins = array();
  543. foreach ($this->registeredPlugins as $pluginId => $plugin) {
  544. if ($plugin->addsButtons() && !$this->pluginButton[$pluginId]) {
  545. $hidePlugins[] = $pluginId;
  546. }
  547. }
  548. $this->pluginEnabledArray = array_unique(array_diff($this->pluginEnabledArray, $hidePlugins));
  549. }
  550. /**
  551. * Set the toolbar config (only in this PHP-Object, not in JS):
  552. *
  553. */
  554. function setToolbar() {
  555. global $BE_USER;
  556. if ($this->client['browser'] == 'msie' || $this->client['browser'] == 'opera') {
  557. $this->thisConfig['keepButtonGroupTogether'] = 0;
  558. }
  559. $this->defaultToolbarOrder = 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
  560. bar, formattext, bold, strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code, definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span,
  561. bar, fontstyle, space, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, line,
  562. bar, left, center, right, justifyfull,
  563. bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, lefttoright, righttoleft, language, showlanguagemarks,
  564. bar, textcolor, bgcolor, textindicator,
  565. bar, editelement, emoticon, insertcharacter, link, unlink, image, table,' . (($this->thisConfig['hideTableOperationsInToolbar'] && is_array($this->thisConfig['buttons.']) && is_array($this->thisConfig['buttons.']['toggleborders.']) && $this->thisConfig['buttons.']['toggleborders.']['keepInToolbar']) ? ' toggleborders,': '') . ' user, acronym, bar, findreplace, spellcheck,
  566. bar, chMode, inserttag, removeformat, bar, copy, cut, paste, pastetoggle, pastebehaviour, bar, undo, redo, bar, showhelp, about, linebreak,
  567. ' . ($this->thisConfig['hideTableOperationsInToolbar'] ? '': 'bar, toggleborders,') . ' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
  568. columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
  569. cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
  570. // Additional buttons from registered plugins
  571. foreach($this->registeredPlugins as $pluginId => $plugin) {
  572. if ($this->isPluginEnabled($pluginId)) {
  573. $this->defaultToolbarOrder = $plugin->addButtonsToToolbar();
  574. }
  575. }
  576. $toolbarOrder = $this->thisConfig['toolbarOrder'] ? $this->thisConfig['toolbarOrder'] : $this->defaultToolbarOrder;
  577. // Getting rid of undefined buttons
  578. $this->toolbarOrderArray = array_intersect(t3lib_div::trimExplode(',', $toolbarOrder, 1), t3lib_div::trimExplode(',', $this->defaultToolbarOrder, 1));
  579. $toolbarOrder = array_unique(array_values($this->toolbarOrderArray));
  580. // Fetching specConf for field from backend
  581. $pList = is_array($this->specConf['richtext']['parameters']) ? implode(',',$this->specConf['richtext']['parameters']) : '';
  582. if ($pList != '*') { // If not all
  583. $show = is_array($this->specConf['richtext']['parameters']) ? $this->specConf['richtext']['parameters'] : array();
  584. if ($this->thisConfig['showButtons']) {
  585. if (!t3lib_div::inList($this->thisConfig['showButtons'],'*')) {
  586. $show = array_unique(array_merge($show,t3lib_div::trimExplode(',',$this->thisConfig['showButtons'],1)));
  587. } else {
  588. $show = array_unique(array_merge($show, $toolbarOrder));
  589. }
  590. }
  591. if (is_array($this->thisConfig['showButtons.'])) {
  592. foreach ($this->thisConfig['showButtons.'] as $buttonId => $value) {
  593. if ($value) $show[] = $buttonId;
  594. }
  595. $show = array_unique($show);
  596. }
  597. } else {
  598. $show = $toolbarOrder;
  599. }
  600. // Resticting to RTEkeyList for backend user
  601. if(is_object($BE_USER)) {
  602. $RTEkeyList = isset($BE_USER->userTS['options.']['RTEkeyList']) ? $BE_USER->userTS['options.']['RTEkeyList'] : '*';
  603. if ($RTEkeyList != '*') { // If not all
  604. $show = array_intersect($show, t3lib_div::trimExplode(',',$RTEkeyList,1));
  605. }
  606. }
  607. // Hiding buttons of disabled plugins
  608. $hideButtons = array('space', 'bar', 'linebreak');
  609. foreach ($this->pluginButton as $pluginId => $buttonList) {
  610. if (!$this->isPluginEnabled($pluginId)) {
  611. $buttonArray = t3lib_div::trimExplode(',',$buttonList,1);
  612. foreach ($buttonArray as $button) {
  613. $hideButtons[] = $button;
  614. }
  615. }
  616. }
  617. // Hiding labels of disabled plugins
  618. foreach ($this->pluginLabel as $pluginId => $label) {
  619. if (!$this->isPluginEnabled($pluginId)) {
  620. $hideButtons[] = $label;
  621. }
  622. }
  623. // Hiding buttons
  624. $show = array_diff($show, $this->conf_toolbar_hide, t3lib_div::trimExplode(',',$this->thisConfig['hideButtons'],1));
  625. // Apply toolbar constraints from registered plugins
  626. foreach ($this->registeredPlugins as $pluginId => $plugin) {
  627. if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "applyToolbarConstraints")) {
  628. $show = $plugin->applyToolbarConstraints($show);
  629. }
  630. }
  631. // Getting rid of the buttons for which we have no position
  632. $show = array_intersect($show, $toolbarOrder);
  633. $this->toolbar = $show;
  634. }
  635. /**
  636. * Disable some plugins
  637. *
  638. */
  639. function setPlugins() {
  640. // Disabling a plugin that adds buttons if none of its buttons is in the toolbar
  641. $hidePlugins = array();
  642. foreach ($this->pluginButton as $pluginId => $buttonList) {
  643. if ($this->registeredPlugins[$pluginId]->addsButtons()) {
  644. $showPlugin = false;
  645. $buttonArray = t3lib_div::trimExplode(',', $buttonList, 1);
  646. foreach ($buttonArray as $button) {
  647. if (in_array($button, $this->toolbar)) {
  648. $showPlugin = true;
  649. }
  650. }
  651. if (!$showPlugin) {
  652. $hidePlugins[] = $pluginId;
  653. }
  654. }
  655. }
  656. $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
  657. // Hiding labels of disabled plugins
  658. $hideLabels = array();
  659. foreach ($this->pluginLabel as $pluginId => $label) {
  660. if (!$this->isPluginEnabled($pluginId)) {
  661. $hideLabels[] = $label;
  662. }
  663. }
  664. $this->toolbar = array_diff($this->toolbar, $hideLabels);
  665. // Adding plugins declared as prerequisites by enabled plugins
  666. $requiredPlugins = array();
  667. foreach ($this->registeredPlugins as $pluginId => $plugin) {
  668. if ($this->isPluginEnabled($pluginId)) {
  669. $requiredPlugins = array_merge($requiredPlugins, t3lib_div::trimExplode(',', $plugin->getRequiredPlugins(), 1));
  670. }
  671. }
  672. $requiredPlugins = array_unique($requiredPlugins);
  673. foreach ($requiredPlugins as $pluginId) {
  674. if (is_object($this->registeredPlugins[$pluginId]) && !$this->isPluginEnabled($pluginId)) {
  675. $this->pluginEnabledArray[] = $pluginId;
  676. }
  677. }
  678. $this->pluginEnabledArray = array_unique($this->pluginEnabledArray);
  679. // Completing the toolbar conversion array for htmlArea
  680. foreach ($this->registeredPlugins as $pluginId => $plugin) {
  681. if ($this->isPluginEnabled($pluginId)) {
  682. $this->convertToolbarForHtmlAreaArray = array_unique(array_merge($this->convertToolbarForHtmlAreaArray, $plugin->getConvertToolbarForHtmlAreaArray()));
  683. }
  684. }
  685. }
  686. /**
  687. * Convert the TYPO3 names of buttons into the names for htmlArea RTE
  688. *
  689. * @param string buttonname (typo3-name)
  690. * @return string buttonname (htmlarea-name)
  691. */
  692. function convertToolbarForHTMLArea($button) {
  693. return $this->convertToolbarForHtmlAreaArray[$button];
  694. }
  695. /**
  696. * Return the HTML code for loading the Javascript files
  697. *
  698. * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
  699. *
  700. * @return void
  701. */
  702. protected function includeScriptFiles($RTEcounter) {
  703. $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea.js', 'htmlarea', 'js', '', TRUE);
  704. if ($this->client['browser'] == 'msie') {
  705. $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-ie.js', 'htmlarea-ie', 'js', '', TRUE);
  706. } else {
  707. $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-gecko.js', 'htmlarea-gecko', 'js', '', TRUE);
  708. }
  709. foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
  710. $extensionKey = is_object($this->registeredPlugins[$pluginId]) ? $this->registeredPlugins[$pluginId]->getExtensionKey() : $this->ID;
  711. $this->writeTemporaryFile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $pluginId . '/' . strtolower(preg_replace('/([a-z])([A-Z])([a-z])/', "$1".'-'."$2"."$3", $pluginId)) . '.js', $pluginId, 'js', '', TRUE);
  712. }
  713. }
  714. /**
  715. * Return the HTML code for loading the Javascript files
  716. *
  717. * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
  718. *
  719. * @return string the html code for loading the Javascript Files
  720. */
  721. protected function loadJSfiles($RTEcounter) {
  722. $loadJavascriptCode = '<script type="text/javascript" src="' . $this->doConcatenate($RTEcounter) . '"></script>' . LF;
  723. $loadJavascriptCode .= t3lib_div::wrapJS('
  724. if (typeof(RTEarea) == "undefined") {
  725. RTEarea = new Object();
  726. RTEarea[0] = new Object();
  727. RTEarea[0].version = "' . $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['version'] . '";
  728. RTEarea[0].editorUrl = "' . $this->extHttpPath . 'htmlarea/";
  729. RTEarea[0].editorCSS = "' . t3lib_div::createVersionNumberedFilename($this->editorCSS) . '";
  730. RTEarea[0].editorSkin = "' . dirname($this->editorCSS) . '/";
  731. RTEarea[0].editedContentCSS = "' . t3lib_div::createVersionNumberedFilename($this->editedContentCSS) . '";
  732. RTEarea[0].hostUrl = "' . $this->hostURL . '";
  733. RTEarea.init = function() {
  734. if (typeof(HTMLArea) == "undefined" || !Ext.isReady) {
  735. window.setTimeout("RTEarea.init();", 40);
  736. } else {
  737. Ext.QuickTips.init();
  738. HTMLArea.init();
  739. }
  740. };
  741. RTEarea.initEditor = function(editorNumber) {
  742. if (typeof(HTMLArea) == "undefined") {
  743. RTEarea.initEditor.defer(40, null, [editorNumber]);
  744. } else {
  745. HTMLArea.initEditor(editorNumber);
  746. }
  747. };
  748. }'
  749. );
  750. return $loadJavascriptCode;
  751. }
  752. /**
  753. * Return the Javascript code for initializing the RTE
  754. *
  755. * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
  756. *
  757. * @return string the Javascript code for initializing the RTE
  758. */
  759. function loadJScode($RTEcounter) {
  760. return TAB . 'RTEarea.init();';
  761. }
  762. /**
  763. * Return the Javascript code for configuring the RTE
  764. *
  765. * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
  766. * @param string $table: The table that includes this RTE (optional, necessary for IRRE).
  767. * @param string $uid: The uid of that table that includes this RTE (optional, necessary for IRRE).
  768. * @param string $field: The field of that record that includes this RTE (optional).
  769. *
  770. * @return string the Javascript code for configuring the RTE
  771. */
  772. function registerRTEinJS($RTEcounter, $table='', $uid='', $field='', $textAreaId = '') {
  773. $configureRTEInJavascriptString = '
  774. if (typeof(configureEditorInstance) == "undefined") {
  775. configureEditorInstance = new Object();
  776. }
  777. configureEditorInstance["' . $textAreaId . '"] = function() {
  778. if (typeof(RTEarea) == "undefined" || typeof(HTMLArea) == "undefined") {
  779. window.setTimeout("configureEditorInstance[\'' . $textAreaId . '\']();", 40);
  780. } else {
  781. editornumber = "' . $textAreaId . '";
  782. RTEarea[editornumber] = new Object();
  783. RTEarea[editornumber].RTEtsConfigParams = "&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams()) . '";
  784. RTEarea[editornumber].number = editornumber;
  785. RTEarea[editornumber].deleted = false;
  786. RTEarea[editornumber].textAreaId = "' . $textAreaId . '";
  787. RTEarea[editornumber].id = "RTEarea" + editornumber;
  788. 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'])) . '";
  789. RTEarea[editornumber].RTEHeightOverride = "' . ((is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteHeight']) && intval($GLOBALS['BE_USER']->uc['rteHeight'])) ? intval($GLOBALS['BE_USER']->uc['rteHeight']) : intval($this->thisConfig['RTEHeightOverride'])) . '";
  790. 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')) . ';
  791. RTEarea[editornumber].maxHeight = "' . ((is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteMaxHeight']) && intval($GLOBALS['BE_USER']->uc['rteMaxHeight'])) ? trim($GLOBALS['BE_USER']->uc['rteMaxHeight']) : (intval($this->thisConfig['rteMaxHeight']) ? intval($this->thisConfig['rteMaxHeight']) : '2000')) . '";
  792. RTEarea[editornumber].fullScreen = ' . ($this->fullScreen ? 'true' : 'false') . ';
  793. RTEarea[editornumber].showStatusBar = ' . (trim($this->thisConfig['showStatusBar'])?'true':'false') . ';
  794. RTEarea[editornumber].enableWordClean = ' . (trim($this->thisConfig['enableWordClean'])?'true':'false') . ';
  795. RTEarea[editornumber].htmlRemoveComments = ' . (trim($this->thisConfig['removeComments'])?'true':'false') . ';
  796. RTEarea[editornumber].disableEnterParagraphs = ' . (trim($this->thisConfig['disableEnterParagraphs'])?'true':'false') . ';
  797. RTEarea[editornumber].disableObjectResizing = ' . (trim($this->thisConfig['disableObjectResizing'])?'true':'false') . ';
  798. RTEarea[editornumber].removeTrailingBR = ' . (trim($this->thisConfig['removeTrailingBR'])?'true':'false') . ';
  799. RTEarea[editornumber].useCSS = ' . (trim($this->thisConfig['useCSS'])?'true':'false') . ';
  800. RTEarea[editornumber].keepButtonGroupTogether = ' . (trim($this->thisConfig['keepButtonGroupTogether'])?'true':'false') . ';
  801. RTEarea[editornumber].disablePCexamples = ' . (trim($this->thisConfig['disablePCexamples'])?'true':'false') . ';
  802. RTEarea[editornumber].showTagFreeClasses = ' . (trim($this->thisConfig['showTagFreeClasses'])?'true':'false') . ';
  803. RTEarea[editornumber].useHTTPS = ' . ((trim(stristr($this->siteURL, 'https')) || $this->thisConfig['forceHTTPS'])?'true':'false') . ';
  804. RTEarea[editornumber].tceformsNested = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(true) : '[]') . ';
  805. RTEarea[editornumber].dialogueWindows = new Object();';
  806. if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromTop'])) {
  807. $configureRTEInJavascriptString .= '
  808. RTEarea[editornumber].dialogueWindows.positionFromTop = ' . intval($this->thisConfig['dialogueWindows.']['defaultPositionFromTop']) . ';';
  809. }
  810. if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'])) {
  811. $configureRTEInJavascriptString .= '
  812. RTEarea[editornumber].dialogueWindows.positionFromLeft = ' . intval($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft']) . ';';
  813. }
  814. // The following properties apply only to the backend
  815. if (!$this->is_FE()) {
  816. $configureRTEInJavascriptString .= '
  817. RTEarea[editornumber].sys_language_content = "' . $this->contentLanguageUid . '";
  818. RTEarea[editornumber].typo3ContentLanguage = "' . $this->contentTypo3Language . '";
  819. RTEarea[editornumber].typo3ContentCharset = "' . $this->contentCharset . '";
  820. RTEarea[editornumber].userUid = "' . $this->userUid . '";';
  821. }
  822. // Setting the plugin flags
  823. $configureRTEInJavascriptString .= '
  824. RTEarea[editornumber].plugin = new Object();
  825. RTEarea[editornumber].pathToPluginDirectory = new Object();';
  826. foreach ($this->pluginEnabledArray as $pluginId) {
  827. $configureRTEInJavascriptString .= '
  828. RTEarea[editornumber].plugin.'.$pluginId.' = true;';
  829. if (is_object($this->registeredPlugins[$pluginId])) {
  830. $pathToPluginDirectory = $this->registeredPlugins[$pluginId]->getPathToPluginDirectory();
  831. if ($pathToPluginDirectory) {
  832. $configureRTEInJavascriptString .= '
  833. RTEarea[editornumber].pathToPluginDirectory.'.$pluginId.' = "' . $pathToPluginDirectory . '";';
  834. }
  835. }
  836. }
  837. // Setting the buttons configuration
  838. $configureRTEInJavascriptString .= '
  839. RTEarea[editornumber].buttons = new Object();';
  840. if (is_array($this->thisConfig['buttons.'])) {
  841. foreach ($this->thisConfig['buttons.'] as $buttonIndex => $conf) {
  842. $button = substr($buttonIndex, 0, -1);
  843. if (is_array($conf)) {
  844. $configureRTEInJavascriptString .= '
  845. RTEarea[editornumber].buttons.'.$button.' = ' . $this->buildNestedJSArray($conf) . ';';
  846. }
  847. }
  848. }
  849. // Setting the list of tags to be removed if specified in the RTE config
  850. if (trim($this->thisConfig['removeTags'])) {
  851. $configureRTEInJavascriptString .= '
  852. RTEarea[editornumber].htmlRemoveTags = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTags'], 1)) . ')$/i;';
  853. }
  854. // Setting the list of tags to be removed with their contents if specified in the RTE config
  855. if (trim($this->thisConfig['removeTagsAndContents'])) {
  856. $configureRTEInJavascriptString .= '
  857. RTEarea[editornumber].htmlRemoveTagsAndContents = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTagsAndContents'], 1)) . ')$/i;';
  858. }
  859. // Process default style configuration
  860. $configureRTEInJavascriptString .= '
  861. RTEarea[editornumber].defaultPageStyle = "' . $this->writeTemporaryFile('', 'defaultPageStyle', 'css', $this->buildStyleSheet()) . '";';
  862. // Setting the pageStyle
  863. $filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/res/contentcss/default.css';
  864. $configureRTEInJavascriptString .= '
  865. RTEarea[editornumber].pageStyle = "' . t3lib_div::createVersionNumberedFilename($this->getFullFileName($filename)) .'";';
  866. // Process classes configuration
  867. $classesConfigurationRequired = false;
  868. foreach ($this->registeredPlugins as $pluginId => $plugin) {
  869. if ($this->isPluginEnabled($pluginId)) {
  870. $classesConfigurationRequired = $classesConfigurationRequired || $plugin->requiresClassesConfiguration();
  871. }
  872. }
  873. if ($classesConfigurationRequired) {
  874. $configureRTEInJavascriptString .= $this->buildJSClassesConfig($RTEcounter);
  875. }
  876. // Add Javascript configuration for registered plugins
  877. foreach ($this->registeredPlugins as $pluginId => $plugin) {
  878. if ($this->isPluginEnabled($pluginId)) {
  879. $configureRTEInJavascriptString .= $plugin->buildJavascriptConfiguration('editornumber');
  880. }
  881. }
  882. // Avoid premature reference to HTMLArea when being initially loaded by IRRE Ajax call
  883. $configureRTEInJavascriptString .= '
  884. RTEarea[editornumber].toolbar = ' . $this->getJSToolbarArray() . ';
  885. RTEarea[editornumber].convertButtonId = ' . json_encode(array_flip($this->convertToolbarForHtmlAreaArray)) . ';
  886. RTEarea.initEditor(editornumber);
  887. }
  888. };
  889. configureEditorInstance["' . $textAreaId . '"]();';
  890. return $configureRTEInJavascriptString;
  891. }
  892. /**
  893. * Return true, if the plugin can be loaded
  894. *
  895. * @param string $pluginId: The identification string of the plugin
  896. *
  897. * @return boolean true if the plugin can be loaded
  898. */
  899. function isPluginEnabled($pluginId) {
  900. return in_array($pluginId, $this->pluginEnabledArray);
  901. }
  902. /**
  903. * Build the default content style sheet
  904. *
  905. * @return string Style sheet
  906. */
  907. function buildStyleSheet() {
  908. if (!trim($this->thisConfig['ignoreMainStyleOverride'])) {
  909. $mainStyle_font = $this->thisConfig['mainStyle_font'] ? $this->thisConfig['mainStyle_font']: 'Verdana,sans-serif';
  910. $mainElements = array();
  911. $mainElements['P'] = $this->thisConfig['mainStyleOverride_add.']['P'];
  912. $elList = explode(',','H1,H2,H3,H4,H5,H6,PRE');
  913. foreach ($elList as $elListName) {
  914. if ($this->thisConfig['mainStyleOverride_add.'][$elListName]) {
  915. $mainElements[$elListName] = $this->thisConfig['mainStyleOverride_add.'][$elListName];
  916. }
  917. }
  918. $addElementCode = '';
  919. foreach ($mainElements as $elListName => $elValue) {
  920. $addElementCode .= strToLower($elListName) . ' {' . $elValue . '}' . LF;
  921. }
  922. $stylesheet = $this->thisConfig['mainStyleOverride'] ? $this->thisConfig['mainStyleOverride'] : LF .
  923. 'body.htmlarea-content-body { font-family: ' . $mainStyle_font .
  924. '; font-size: '.($this->thisConfig['mainStyle_size'] ? $this->thisConfig['mainStyle_size'] : '12px') .
  925. '; color: '.($this->thisConfig['mainStyle_color']?$this->thisConfig['mainStyle_color'] : 'black') .
  926. '; background-color: '.($this->thisConfig['mainStyle_bgcolor'] ? $this->thisConfig['mainStyle_bgcolor'] : 'white') .
  927. ';'.$this->thisConfig['mainStyleOverride_add.']['BODY'].'}' . LF .
  928. 'td { ' . $this->thisConfig['mainStyleOverride_add.']['TD'].'}' . LF .
  929. 'div { ' . $this->thisConfig['mainStyleOverride_add.']['DIV'].'}' . LF .
  930. 'pre { ' . $this->thisConfig['mainStyleOverride_add.']['PRE'].'}' . LF .
  931. 'ol { ' . $this->thisConfig['mainStyleOverride_add.']['OL'].'}' . LF .
  932. 'ul { ' . $this->thisConfig['mainStyleOverride_add.']['UL'].'}' . LF .
  933. 'blockquote { ' . $this->thisConfig['mainStyleOverride_add.']['BLOCKQUOTE'].'}' . LF .
  934. $addElementCode;
  935. if (is_array($this->thisConfig['inlineStyle.'])) {
  936. $stylesheet .= LF . implode(LF, $this->thisConfig['inlineStyle.']) . LF;
  937. }
  938. } else {
  939. $stylesheet = '/* mainStyleOverride and inlineStyle properties ignored. */';
  940. }
  941. return $stylesheet;
  942. }
  943. /**
  944. * Return Javascript configuration of classes
  945. *
  946. * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
  947. *
  948. * @return string Javascript configuration of classes
  949. */
  950. function buildJSClassesConfig($RTEcounter) {
  951. // Build JS array of lists of classes
  952. $classesTagList = 'classesCharacter, classesParagraph, classesImage, classesTable, classesLinks, classesTD';
  953. $classesTagConvert = array( 'classesCharacter' => 'span', 'classesParagraph' => 'div', 'classesImage' => 'img', 'classesTable' => 'table', 'classesLinks' => 'a', 'classesTD' => 'td');
  954. $classesTagArray = t3lib_div::trimExplode(',' , $classesTagList);
  955. $configureRTEInJavascriptString = '
  956. RTEarea[editornumber].classesTag = new Object();';
  957. foreach ($classesTagArray as $classesTagName) {
  958. $HTMLAreaJSClasses = ($this->thisConfig[$classesTagName])?('"' . $this->cleanList($this->thisConfig[$classesTagName]) . '";'):'null;';
  959. $configureRTEInJavascriptString .= '
  960. RTEarea[editornumber].classesTag.'. $classesTagConvert[$classesTagName] .' = '. $HTMLAreaJSClasses;
  961. }
  962. // Include JS arrays of configured classes
  963. $configureRTEInJavascriptString .= '
  964. RTEarea[editornumber].classesUrl = "' . $this->writeTemporaryFile('', 'classes_' . $this->language, 'js', $this->buildJSClassesArray(), TRUE) . '";';
  965. return $configureRTEInJavascriptString;
  966. }
  967. /**
  968. * Return JS arrays of classes configuration
  969. *
  970. * @return string JS classes arrays
  971. */
  972. function buildJSClassesArray() {
  973. if ($this->is_FE()) {
  974. $RTEProperties = $this->RTEsetup;
  975. } else {
  976. $RTEProperties = $this->RTEsetup['properties'];
  977. }
  978. $classesArray = array('labels' => array(), 'values' => array(), 'noShow' => array(), 'alternating' => array(), 'counting' => array(), 'XOR' => array());
  979. $JSClassesArray = '';
  980. // Scanning the list of classes if specified in the RTE config
  981. if (is_array($RTEProperties['classes.'])) {
  982. foreach ($RTEProperties['classes.'] as $className => $conf) {
  983. $className = rtrim($className, '.');
  984. $classesArray['labels'][$className] = $this->getPageConfigLabel($conf['name'], FALSE);
  985. $classesArray['values'][$className] = str_replace('\\\'', '\'', $conf['value']);
  986. if (isset($conf['noShow'])) {
  987. $classesArray['noShow'][$className] = $conf['noShow'];
  988. }
  989. if (is_array($conf['alternating.'])) {
  990. $classesArray['alternating'][$className] = $conf['alternating.'];
  991. }
  992. if (is_array($conf['counting.'])) {
  993. $classesArray['counting'][$className] = $conf['counting.'];
  994. }
  995. }
  996. }
  997. // Scanning the list of sets of mutually exclusives classes if specified in the RTE config
  998. if (is_array($RTEProperties['mutuallyExclusiveClasses.'])) {
  999. foreach ($RTEProperties['mutuallyExclusiveClasses.'] as $listName => $conf) {
  1000. $classSet = t3lib_div::trimExplode(',', $conf, 1);
  1001. $classList = implode(',', $classSet);
  1002. foreach ($classSet as $className) {
  1003. $classesArray['XOR'][$className] = '/^(' . implode('|', t3lib_div::trimExplode(',', t3lib_div::rmFromList($className, $classList), 1)) . ')$/';
  1004. }
  1005. }
  1006. }
  1007. foreach ($classesArray as $key => $subArray) {
  1008. $JSClassesArray .= 'HTMLArea.classes' . ucfirst($key) . ' = ' . $this->buildNestedJSArray($subArray) . ';' . LF;
  1009. }
  1010. return $JSClassesArray;
  1011. }
  1012. /**
  1013. * Translate Page TS Config array in JS nested array definition
  1014. * Replace 0 values with false
  1015. * Unquote regular expression values
  1016. * Replace empty arrays with empty objects
  1017. *
  1018. * @param array $conf: Page TSConfig configuration array
  1019. *
  1020. * @return string nested JS array definition
  1021. */
  1022. function buildNestedJSArray($conf) {
  1023. $convertedConf = t3lib_div::removeDotsFromTS($conf);
  1024. if ($this->is_FE()) {
  1025. $GLOBALS['TSFE']->csConvObj->convArray($convertedConf, ($GLOBALS['TYPO3_…

Large files files are truncated, but you can click here to view the full file