Fixed bug #14567: htmlArea RTE: RTE is greyed out and has no "styles" in page module...
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / class.tx_rtehtmlarea_base.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2004-2010 Kasper Skaarhoj (kasper@typo3.com)
6 * (c) 2004-2010 Philipp Borgmann <philipp.borgmann@gmx.de>
7 * (c) 2004-2010 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
38 class tx_rtehtmlarea_base extends t3lib_rteapi {
39 // Configuration of supported browsers
40 var $conf_supported_browser = array (
41 'msie' => array (
42 1 => array (
43 'version' => 6.0,
44 'system' => 'winNT'
45 ),
46 2 => array (
47 'version' => 6.0,
48 'system' => 'win98'
49 ),
50 3 => array (
51 'version' => 6.0,
52 'system' => 'win95'
53 )
54 ),
55 'gecko' => array (
56 1 => array (
57 'version' => 1.8
58 )
59 ),
60 'webkit' => array (
61 1 => array (
62 'version' => 523
63 )
64 ),
65 'opera' => array (
66 1 => array (
67 'version' => 9.62
68 )
69 )
70 );
71
72 // Always hide these toolbar buttons (TYPO3 button name)
73 var $conf_toolbar_hide = array (
74 'showhelp', // Has no content yet
75 );
76
77 // The order of the toolbar: the name is the TYPO3-button name
78 var $defaultToolbarOrder;
79
80 // Conversion array: TYPO3 button names to htmlArea button names
81 var $convertToolbarForHtmlAreaArray = array (
82 'showhelp' => 'ShowHelp',
83 'space' => 'space',
84 'bar' => 'separator',
85 'linebreak' => 'linebreak',
86 );
87
88 var $pluginButton = array();
89 var $pluginLabel = array();
90 // Alternative style for RTE <div> tag.
91 public $RTEdivStyle;
92 // Relative path to this extension. It ends with "/"
93 public $extHttpPath;
94 public $backPath = '';
95 // TYPO3 site url
96 public $siteURL;
97 // TYPO3 host url
98 public $hostURL;
99 // Typo3 version
100 public $typoVersion;
101 // Identifies the RTE as being the one from the "rtehtmlarea" extension if any external code needs to know
102 var $ID = 'rtehtmlarea';
103 // If set, the content goes into a regular TEXT area field - for developing testing of transformations.
104 var $debugMode = FALSE;
105 // For the editor
106 var $client;
107
108 /**
109 * Reference to parent object, which is an instance of the TCEforms
110 *
111 * @var t3lib_TCEforms
112 */
113 var $TCEform;
114 var $elementId;
115 var $elementParts;
116 var $tscPID;
117 var $typeVal;
118 var $thePid;
119 var $RTEsetup;
120 var $thisConfig;
121 var $confValues;
122 public $language;
123 public $contentTypo3Language;
124 public $contentISOLanguage;
125 public $contentCharset;
126 public $OutputCharset;
127 var $editorCSS;
128 var $specConf;
129 var $toolbar = array(); // Save the buttons for the toolbar
130 var $toolbarOrderArray = array();
131 protected $pluginEnabledArray = array(); // Array of plugin id's enabled in the current RTE editing area
132 protected $pluginEnabledCumulativeArray = array(); // Cumulative array of plugin id's enabled so far in any of the RTE editing areas of the form
133 protected $cumulativeScripts = array();
134 public $registeredPlugins = array(); // Array of registered plugins indexed by their plugin Id's
135 protected $fullScreen = false;
136
137 /**
138 * Returns true if the RTE is available. Here you check if the browser requirements are met.
139 * If there are reasons why the RTE cannot be displayed you simply enter them as text in ->errorLog
140 *
141 * @return boolean TRUE if this RTE object offers an RTE in the current browser environment
142 */
143
144 function isAvailable() {
145 global $TYPO3_CONF_VARS;
146
147 $this->client = $this->clientInfo();
148 $this->errorLog = array();
149 if (!$this->debugMode) { // If debug-mode, let any browser through
150 $rteIsAvailable = 0;
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 $browserConfNr => $browserConfSub) {
158 if ($browserConfSub['version'] <= $this->client['version'] || empty($browserConfSub['version'])) {
159 // Version is correct
160 if ($browserConfSub['system'] == $this->client['system'] || empty($browserConfSub['system'])) {
161 // System is correctly
162 $rteIsAvailable = 1;
163 }// End of System
164 }// End of Version
165 }// End of foreach-BrowserSubpart
166 } else {
167 // no config for this browser found, so all versions or system with this browsers are allow
168 $rteIsAvailable = 1;
169 }
170 } // End of Browser Check
171 } // foreach: Browser Check
172 } else {
173 // no Browser config for this RTE-Editor, so all Clients are allow
174 }
175 if (!$rteIsAvailable) {
176 $this->errorLog[] = 'rte: Browser not supported. Only msie Version 5 or higher and Mozilla based client 1. and higher.';
177 }
178 if (t3lib_div::int_from_ver(TYPO3_version) < 4000000) {
179 $rteIsAvailable = 0;
180 $this->errorLog[] = 'rte: This version of htmlArea RTE cannot run under this version of TYPO3.';
181 }
182 }
183 if ($rteIsAvailable) return true;
184 }
185
186 /**
187 * Draws the RTE as an iframe
188 *
189 * @param object Reference to parent object, which is an instance of the TCEforms.
190 * @param string The table name
191 * @param string The field name
192 * @param array The current row from which field is being rendered
193 * @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.
194 * @param array "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
195 * @param array Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
196 * @param string Record "type" field value.
197 * @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!
198 * @param integer PID value of record (true parent page id)
199 * @return string HTML code for RTE!
200 */
201
202 function drawRTE($parentObject, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue) {
203 global $BE_USER, $LANG, $TYPO3_DB, $TYPO3_CONF_VARS;
204
205 $this->TCEform = $parentObject;
206 $inline = $this->TCEform->inline;
207 $LANG->includeLLFile('EXT:' . $this->ID . '/locallang.xml');
208 $this->client = $this->clientInfo();
209 $this->typoVersion = t3lib_div::int_from_ver(TYPO3_version);
210 $this->userUid = 'BE_' . $BE_USER->user['uid'];
211
212 // Draw form element:
213 if ($this->debugMode) { // Draws regular text area (debug mode)
214 $item = parent::drawRTE($this->TCEform, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue);
215 } else { // Draw real RTE
216
217 /* =======================================
218 * INIT THE EDITOR-SETTINGS
219 * =======================================
220 */
221 // Set backPath
222 $this->backPath = $this->TCEform->backPath;
223 // Get the path to this extension:
224 $this->extHttpPath = $this->backPath . t3lib_extMgm::extRelPath($this->ID);
225 // Get the site URL
226 $this->siteURL = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
227 // Get the host URL
228 $this->hostURL = $this->siteURL . TYPO3_mainDir;
229 // Element ID + pid
230 $this->elementId = $PA['itemFormElName']; // Form element name
231 $this->elementParts = explode('][',preg_replace('/\]$/','',preg_replace('/^(TSFE_EDIT\[data\]\[|data\[)/','',$this->elementId)));
232 // Find the page PIDs:
233 list($this->tscPID,$this->thePid) = t3lib_BEfunc::getTSCpid(trim($this->elementParts[0]),trim($this->elementParts[1]),$thePidValue);
234
235 // Record "types" field value:
236 $this->typeVal = $RTEtypeVal; // TCA "types" value for record
237
238 // Find "thisConfig" for record/editor:
239 unset($this->RTEsetup);
240 $this->RTEsetup = $BE_USER->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($this->tscPID));
241 $this->thisConfig = $thisConfig;
242
243 // Special configuration and default extras:
244 $this->specConf = $specConf;
245
246 if ($this->thisConfig['forceHTTPS']) {
247 $this->extHttpPath = preg_replace('/^(http|https)/', 'https', $this->extHttpPath);
248 $this->siteURL = preg_replace('/^(http|https)/', 'https', $this->siteURL);
249 $this->hostURL = preg_replace('/^(http|https)/', 'https', $this->hostURL);
250 }
251
252 /* =======================================
253 * LANGUAGES & CHARACTER SETS
254 * =======================================
255 */
256
257 // Languages: interface and content
258 $this->language = $LANG->lang;
259 if ($this->language=='default' || !$this->language) {
260 $this->language='en';
261 }
262 $this->contentTypo3Language = $this->language;
263 $this->contentISOLanguage = 'en';
264 $this->contentLanguageUid = ($row['sys_language_uid'] > 0) ? $row['sys_language_uid'] : 0;
265 if (t3lib_extMgm::isLoaded('static_info_tables')) {
266 if ($this->contentLanguageUid) {
267 $tableA = 'sys_language';
268 $tableB = 'static_languages';
269 $languagesUidsList = $this->contentLanguageUid;
270 $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2,' . $tableB . '.lg_typo3';
271 $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
272 $whereClause = $tableA . '.uid IN (' . $languagesUidsList . ') ';
273 $whereClause .= t3lib_BEfunc::BEenableFields($tableA);
274 $whereClause .= t3lib_BEfunc::deleteClause($tableA);
275 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
276 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
277 $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']).(trim($languageRow['lg_country_iso_2'])?'_'.trim($languageRow['lg_country_iso_2']):''));
278 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
279 }
280 } else {
281 $this->contentISOLanguage = trim($this->thisConfig['defaultContentLanguage']) ? trim($this->thisConfig['defaultContentLanguage']) : 'en';
282 $selectFields = 'lg_iso_2, lg_typo3';
283 $tableAB = 'static_languages';
284 $whereClause = 'lg_iso_2 = ' . $TYPO3_DB->fullQuoteStr(strtoupper($this->contentISOLanguage), $tableAB);
285 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
286 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
287 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
288 }
289 }
290 }
291
292 // Character sets: interface and content
293 $this->charset = $LANG->charSet;
294 $this->OutputCharset = $this->charset;
295
296 $this->contentCharset = $LANG->csConvObj->charSetArray[$this->contentTypo3Language];
297 $this->contentCharset = $this->contentCharset ? $this->contentCharset : 'iso-8859-1';
298 $this->origContentCharSet = $this->contentCharset;
299 $this->contentCharset = (trim($TYPO3_CONF_VARS['BE']['forceCharset']) ? trim($TYPO3_CONF_VARS['BE']['forceCharset']) : $this->contentCharset);
300
301 /* =======================================
302 * TOOLBAR CONFIGURATION
303 * =======================================
304 */
305 $this->initializeToolbarConfiguration();
306
307 /* =======================================
308 * SET STYLES
309 * =======================================
310 */
311
312 $RTEWidth = isset($BE_USER->userTS['options.']['RTESmallWidth']) ? $BE_USER->userTS['options.']['RTESmallWidth'] : '530';
313 $RTEHeight = isset($BE_USER->userTS['options.']['RTESmallHeight']) ? $BE_USER->userTS['options.']['RTESmallHeight'] : '380';
314 $RTEWidth = $RTEWidth + ($this->TCEform->docLarge ? (isset($BE_USER->userTS['options.']['RTELargeWidthIncrement']) ? $BE_USER->userTS['options.']['RTELargeWidthIncrement'] : '150') : 0);
315 $RTEWidth -= ($inline->getStructureDepth() > 0 ? ($inline->getStructureDepth()+1)*$inline->getLevelMargin() : 0);
316 if (isset($this->thisConfig['RTEWidthOverride'])) {
317 if (strstr($this->thisConfig['RTEWidthOverride'], '%')) {
318 if ($this->client['browser'] != 'msie') {
319 $RTEWidth = (intval($this->thisConfig['RTEWidthOverride']) > 0) ? $this->thisConfig['RTEWidthOverride'] : '100%';
320 }
321 } else {
322 $RTEWidth = (intval($this->thisConfig['RTEWidthOverride']) > 0) ? intval($this->thisConfig['RTEWidthOverride']) : $RTEWidth;
323 }
324 }
325 $RTEWidth = strstr($RTEWidth, '%') ? $RTEWidth : $RTEWidth . 'px';
326 $RTEHeight = $RTEHeight + ($this->TCEform->docLarge ? (isset($BE_USER->userTS['options.']['RTELargeHeightIncrement']) ? $BE_USER->userTS['options.']['RTELargeHeightIncrement'] : 0) : 0);
327 $RTEHeightOverride = intval($this->thisConfig['RTEHeightOverride']);
328 $RTEHeight = ($RTEHeightOverride > 0) ? $RTEHeightOverride : $RTEHeight;
329 $editorWrapWidth = '99%';
330 $editorWrapHeight = '100%';
331 $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:' . $RTEHeight . 'px; width:'.$RTEWidth.'; border: 1px solid black; padding: 2px 2px 2px 2px;';
332
333 /* =======================================
334 * LOAD CSS AND JAVASCRIPT
335 * =======================================
336 */
337 // Preloading the pageStyle and including RTE skin stylesheets
338 $this->addPageStyle();
339 $this->addSkin();
340 // Loading JavaScript files and code
341 if ($this->TCEform->RTEcounter == 1) {
342 $this->TCEform->additionalJS_pre['rtehtmlarea-loadJScode'] = $this->loadJScode($this->TCEform->RTEcounter);
343 }
344 $this->TCEform->additionalCode_pre['rtehtmlarea-loadJSfiles'] = $this->loadJSfiles($this->TCEform->RTEcounter);
345 $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
346 $pageRenderer->enableExtJSQuickTips();
347 if (!$GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts']) {
348 $pageRenderer->enableExtJsDebug();
349 }
350 /* =======================================
351 * DRAW THE EDITOR
352 * =======================================
353 */
354
355 // Transform value:
356 $value = $this->transformContent('rte',$PA['itemFormElValue'],$table,$field,$row,$specConf,$thisConfig,$RTErelPath,$thePidValue);
357
358 // Further content transformation by registered plugins
359 foreach ($this->registeredPlugins as $pluginId => $plugin) {
360 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "transformContent")) {
361 $value = $plugin->transformContent($value);
362 }
363 }
364 // Register RTE windows
365 $this->TCEform->RTEwindows[] = $PA['itemFormElName'];
366 $textAreaId = htmlspecialchars($PA['itemFormElName']);
367
368 // Check if wizard_rte called this for fullscreen edtition; if so, change the size of the RTE to fullscreen using JS
369 if (basename(PATH_thisScript) == 'wizard_rte.php') {
370 $this->fullScreen = true;
371 $editorWrapWidth = '100%';
372 $editorWrapHeight = '100%';
373 $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:100%; width:100%; border: 1px solid black; padding: 2px 0px 2px 2px;';
374 }
375
376 // Register RTE in JS:
377 $this->TCEform->additionalJS_post[] = $this->registerRTEinJS($this->TCEform->RTEcounter, $table, $row['uid'], $field, $textAreaId);
378
379 // Set the save option for the RTE:
380 $this->TCEform->additionalJS_submit[] = $this->setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
381 $this->TCEform->additionalJS_delete[] = $this->setDeleteRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
382
383 // Draw the textarea
384 $visibility = 'hidden';
385 $item = $this->triggerField($PA['itemFormElName']).'
386 <div id="pleasewait' . $textAreaId . '" class="pleasewait" style="display: block;" >' . $LANG->getLL('Please wait') . '</div>
387 <div id="editorWrap' . $textAreaId . '" class="editorWrap" style="visibility: hidden; width:' . $editorWrapWidth . '; height:' . $editorWrapHeight . ';">
388 <textarea id="RTEarea' . $textAreaId . '" name="'.htmlspecialchars($PA['itemFormElName']).'" style="'.t3lib_div::deHSCentities(htmlspecialchars($this->RTEdivStyle)).'">'.t3lib_div::formatForTextarea($value).'</textarea>
389 </div>' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableDebugMode'] ? '<div id="HTMLAreaLog"></div>' : '') . '
390 ';
391 }
392
393 // Return form item:
394 return $item;
395 }
396
397 /**
398 * Add link to content style sheet to document header
399 *
400 * @return void
401 */
402 protected function addPageStyle() {
403 // Get stylesheet file name from Page TSConfig if any
404 $filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/res/contentcss/default.css';
405 $this->addStyleSheet(
406 'rtehtmlarea-page-style',
407 $this->getFullFileName($filename),
408 'htmlArea RTE Content CSS',
409 'alternate stylesheet'
410 );
411 }
412
413 /**
414 * Add links to skin style sheet(s) to document header
415 *
416 * @return void
417 */
418 protected function addSkin() {
419 // Get skin file name from Page TSConfig if any
420 $skinFilename = trim($this->thisConfig['skin']) ? trim($this->thisConfig['skin']) : 'EXT:' . $this->ID . '/htmlarea/skins/default/htmlarea.css';
421 $this->editorCSS = $this->getFullFileName($skinFilename);
422 $skinDir = dirname($this->editorCSS);
423 // Editing area style sheet
424 $this->editedContentCSS = $skinDir . '/htmlarea-edited-content.css';
425 $this->addStyleSheet(
426 'rtehtmlarea-editing-area-skin',
427 $this->editedContentCSS
428 );
429 // Main skin
430 $this->addStyleSheet(
431 'rtehtmlarea-skin',
432 $this->editorCSS
433 );
434 // Additional icons from registered plugins
435 foreach ($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] as $pluginId) {
436 if (is_object($this->registeredPlugins[$pluginId])) {
437 $pathToSkin = $this->registeredPlugins[$pluginId]->getPathToSkin();
438 if ($pathToSkin) {
439 $key = $this->registeredPlugins[$pluginId]->getExtensionKey();
440 $this->addStyleSheet(
441 'rtehtmlarea-plugin-' . $pluginId . '-skin',
442 ($this->is_FE() ? t3lib_extMgm::siteRelPath($key) : $this->backPath . t3lib_extMgm::extRelPath($key)) . $pathToSkin
443 );
444 }
445 }
446 }
447 }
448
449 /**
450 * Add style sheet file to document header
451 *
452 * @param string $key: some key identifying the style sheet
453 * @param string $href: uri to the style sheet file
454 * @param string $title: value for the title attribute of the link element
455 * @return string $relation: value for the rel attribute of the link element
456 * @return void
457 */
458 protected function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
459 // 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
460 if (is_object($this->TCEform->inline) && $this->TCEform->inline->isAjaxCall) {
461 $this->TCEform->additionalCode_pre[$key] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '" title="' . $title. '" />';
462 } else {
463 $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
464 $pageRenderer->addCssFile($href, $relation, 'screen', $title);
465 }
466 }
467
468 /**
469 * Initialize toolbar configuration and enable registered plugins
470 *
471 * @return void
472 */
473 protected function initializeToolbarConfiguration() {
474
475 // Enable registred plugins
476 $this->enableRegisteredPlugins();
477
478 // Configure toolbar
479 $this->setToolbar();
480
481 // Check if some plugins need to be disabled
482 $this->setPlugins();
483
484 // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
485 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = $this->pluginEnabledArray;
486 if ($this->TCEform->RTEcounter > 1 && isset($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1]) && is_array($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])) {
487 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = array_unique(array_values(array_merge($this->pluginEnabledArray,$this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])));
488 }
489 }
490
491 /**
492 * Add registered plugins to the array of enabled plugins
493 *
494 */
495 function enableRegisteredPlugins() {
496 global $TYPO3_CONF_VARS;
497 // Traverse registered plugins
498 if (is_array($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'])) {
499 foreach($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'] as $pluginId => $pluginObjectConfiguration) {
500 $plugin = false;
501 if (is_array($pluginObjectConfiguration) && count($pluginObjectConfiguration)) {
502 $plugin = t3lib_div::getUserObj($pluginObjectConfiguration['objectReference']);
503 }
504 if (is_object($plugin)) {
505 if ($plugin->main($this)) {
506 $this->registeredPlugins[$pluginId] = $plugin;
507 // Override buttons from previously registered plugins
508 $pluginButtons = t3lib_div::trimExplode(',', $plugin->getPluginButtons(), 1);
509 foreach ($this->pluginButton as $previousPluginId => $buttonList) {
510 $this->pluginButton[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginButton[$previousPluginId], 1), $pluginButtons));
511 }
512 $this->pluginButton[$pluginId] = $plugin->getPluginButtons();
513 $pluginLabels = t3lib_div::trimExplode(',', $plugin->getPluginLabels(), 1);
514 foreach ($this->pluginLabel as $previousPluginId => $labelList) {
515 $this->pluginLabel[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginLabel[$previousPluginId], 1), $pluginLabels));
516 }
517 $this->pluginLabel[$pluginId] = $plugin->getPluginLabels();
518 $this->pluginEnabledArray[] = $pluginId;
519 }
520 }
521 }
522 }
523 // Process overrides
524 $hidePlugins = array();
525 foreach ($this->registeredPlugins as $pluginId => $plugin) {
526 if ($plugin->addsButtons() && !$this->pluginButton[$pluginId]) {
527 $hidePlugins[] = $pluginId;
528 }
529 }
530 $this->pluginEnabledArray = array_unique(array_diff($this->pluginEnabledArray, $hidePlugins));
531 }
532
533 /**
534 * Set the toolbar config (only in this PHP-Object, not in JS):
535 *
536 */
537
538 function setToolbar() {
539 global $BE_USER;
540
541 if ($this->client['browser'] == 'msie' || $this->client['browser'] == 'opera') {
542 $this->thisConfig['keepButtonGroupTogether'] = 0;
543 }
544
545 $this->defaultToolbarOrder = 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
546 bar, formattext, bold, strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code, definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span,
547 bar, fontstyle, space, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, line,
548 bar, left, center, right, justifyfull,
549 bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, lefttoright, righttoleft, language, showlanguagemarks,
550 bar, textcolor, bgcolor, textindicator,
551 bar, 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,
552 bar, chMode, inserttag, removeformat, bar, copy, cut, paste, bar, undo, redo, bar, showhelp, about, linebreak,
553 ' . ($this->thisConfig['hideTableOperationsInToolbar'] ? '': 'bar, toggleborders,') . ' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
554 columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
555 cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
556
557 // Additional buttons from registered plugins
558 foreach($this->registeredPlugins as $pluginId => $plugin) {
559 if ($this->isPluginEnabled($pluginId)) {
560 $this->defaultToolbarOrder = $plugin->addButtonsToToolbar();
561 }
562 }
563 $toolbarOrder = $this->thisConfig['toolbarOrder'] ? $this->thisConfig['toolbarOrder'] : $this->defaultToolbarOrder;
564
565 // Getting rid of undefined buttons
566 $this->toolbarOrderArray = array_intersect(t3lib_div::trimExplode(',', $toolbarOrder, 1), t3lib_div::trimExplode(',', $this->defaultToolbarOrder, 1));
567 $toolbarOrder = array_unique(array_values($this->toolbarOrderArray));
568
569 // Fetching specConf for field from backend
570 $pList = is_array($this->specConf['richtext']['parameters']) ? implode(',',$this->specConf['richtext']['parameters']) : '';
571 if ($pList != '*') { // If not all
572 $show = is_array($this->specConf['richtext']['parameters']) ? $this->specConf['richtext']['parameters'] : array();
573 if ($this->thisConfig['showButtons']) {
574 if (!t3lib_div::inList($this->thisConfig['showButtons'],'*')) {
575 $show = array_unique(array_merge($show,t3lib_div::trimExplode(',',$this->thisConfig['showButtons'],1)));
576 } else {
577 $show = array_unique(array_merge($show, $toolbarOrder));
578 }
579 }
580 if (is_array($this->thisConfig['showButtons.'])) {
581 foreach ($this->thisConfig['showButtons.'] as $buttonId => $value) {
582 if ($value) $show[] = $buttonId;
583 }
584 $show = array_unique($show);
585 }
586 } else {
587 $show = $toolbarOrder;
588 }
589
590 // Resticting to RTEkeyList for backend user
591 if(is_object($BE_USER)) {
592 $RTEkeyList = isset($BE_USER->userTS['options.']['RTEkeyList']) ? $BE_USER->userTS['options.']['RTEkeyList'] : '*';
593 if ($RTEkeyList != '*') { // If not all
594 $show = array_intersect($show, t3lib_div::trimExplode(',',$RTEkeyList,1));
595 }
596 }
597
598 // Hiding buttons of disabled plugins
599 $hideButtons = array('space', 'bar', 'linebreak');
600 foreach ($this->pluginButton as $pluginId => $buttonList) {
601 if (!$this->isPluginEnabled($pluginId)) {
602 $buttonArray = t3lib_div::trimExplode(',',$buttonList,1);
603 foreach ($buttonArray as $button) {
604 $hideButtons[] = $button;
605 }
606 }
607 }
608
609 // Hiding labels of disabled plugins
610 foreach ($this->pluginLabel as $pluginId => $label) {
611 if (!$this->isPluginEnabled($pluginId)) {
612 $hideButtons[] = $label;
613 }
614 }
615
616 // Hiding buttons
617 $show = array_diff($show, $this->conf_toolbar_hide, t3lib_div::trimExplode(',',$this->thisConfig['hideButtons'],1));
618
619 // Apply toolbar constraints from registered plugins
620 foreach ($this->registeredPlugins as $pluginId => $plugin) {
621 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "applyToolbarConstraints")) {
622 $show = $plugin->applyToolbarConstraints($show);
623 }
624 }
625 // Getting rid of the buttons for which we have no position
626 $show = array_intersect($show, $toolbarOrder);
627 $this->toolbar = $show;
628 }
629
630 /**
631 * Disable some plugins
632 *
633 */
634 function setPlugins() {
635
636 // Disabling a plugin that adds buttons if none of its buttons is in the toolbar
637 $hidePlugins = array();
638 foreach ($this->pluginButton as $pluginId => $buttonList) {
639 if ($this->registeredPlugins[$pluginId]->addsButtons()) {
640 $showPlugin = false;
641 $buttonArray = t3lib_div::trimExplode(',', $buttonList, 1);
642 foreach ($buttonArray as $button) {
643 if (in_array($button, $this->toolbar)) {
644 $showPlugin = true;
645 }
646 }
647 if (!$showPlugin) {
648 $hidePlugins[] = $pluginId;
649 }
650 }
651 }
652 $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
653
654 // Hiding labels of disabled plugins
655 $hideLabels = array();
656 foreach ($this->pluginLabel as $pluginId => $label) {
657 if (!$this->isPluginEnabled($pluginId)) {
658 $hideLabels[] = $label;
659 }
660 }
661 $this->toolbar = array_diff($this->toolbar, $hideLabels);
662
663 // Adding plugins declared as prerequisites by enabled plugins
664 $requiredPlugins = array();
665 foreach ($this->registeredPlugins as $pluginId => $plugin) {
666 if ($this->isPluginEnabled($pluginId)) {
667 $requiredPlugins = array_merge($requiredPlugins, t3lib_div::trimExplode(',', $plugin->getRequiredPlugins(), 1));
668 }
669 }
670 $requiredPlugins = array_unique($requiredPlugins);
671 foreach ($requiredPlugins as $pluginId) {
672 if (is_object($this->registeredPlugins[$pluginId]) && !$this->isPluginEnabled($pluginId)) {
673 $this->pluginEnabledArray[] = $pluginId;
674 }
675 }
676 $this->pluginEnabledArray = array_unique($this->pluginEnabledArray);
677
678 // Completing the toolbar conversion array for htmlArea
679 foreach ($this->registeredPlugins as $pluginId => $plugin) {
680 if ($this->isPluginEnabled($pluginId)) {
681 $this->convertToolbarForHtmlAreaArray = array_unique(array_merge($this->convertToolbarForHtmlAreaArray, $plugin->getConvertToolbarForHtmlAreaArray()));
682 }
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
693 function convertToolbarForHTMLArea($button) {
694 return $this->convertToolbarForHtmlAreaArray[$button];
695 }
696 /**
697 * Return the HTML code for loading the Javascript files
698 *
699 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
700 *
701 * @return string the html code for loading the Javascript Files
702 */
703 function loadJSfiles($RTEcounter) {
704 // Re-initialize the scripts array so that only the cumulative set of plugins of the last RTE on the page is used
705 $this->cumulativeScripts[$RTEcounter] = array();
706 $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea.js', 'htmlarea', 'js', '', TRUE);
707 if ($this->client['browser'] == 'msie') {
708 $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-ie.js', 'htmlarea-ie', 'js', '', TRUE);
709 } else {
710 $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-gecko.js', 'htmlarea-gecko', 'js', '', TRUE);
711 }
712 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
713 $extensionKey = is_object($this->registeredPlugins[$pluginId]) ? $this->registeredPlugins[$pluginId]->getExtensionKey() : $this->ID;
714 $this->writeTemporaryFile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $pluginId . '/' . strtolower(preg_replace('/([a-z])([A-Z])([a-z])/', "$1".'-'."$2"."$3", $pluginId)) . '.js', $pluginId, 'js', '', TRUE);
715 }
716 $this->buildJSMainLangFile($RTEcounter);
717 // Avoid re-initialization on AJax call when RTEarea object was already initialized
718 $loadJavascriptCode = '
719 <script type="text/javascript" src="' . $this->doConcatenate($RTEcounter) . '"></script>
720 <script type="text/javascript">
721 /*<![CDATA[*/
722 if (typeof(RTEarea) == "undefined") {
723 RTEarea = new Object();
724 RTEarea[0] = new Object();
725 RTEarea[0].version = "' . $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['version'] . '";
726 RTEarea[0].editorUrl = "' . $this->extHttpPath . 'htmlarea/";
727 RTEarea[0].editorCSS = "' . t3lib_div::createVersionNumberedFilename($this->editorCSS) . '";
728 RTEarea[0].editorSkin = "' . dirname($this->editorCSS) . '/";
729 RTEarea[0].editedContentCSS = "' . t3lib_div::createVersionNumberedFilename($this->editedContentCSS) . '";
730 RTEarea[0].hostUrl = "' . $this->hostURL . '";
731 RTEarea[0].enableDebugMode = ' . ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableDebugMode'] ? 'true' : 'false') . ';
732 RTEarea.init = function() {
733 if (typeof(HTMLArea) == "undefined" || !Ext.isReady) {
734 window.setTimeout("RTEarea.init();", 40);
735 } else {
736 Ext.QuickTips.init();
737 HTMLArea.init();
738 }
739 };
740 RTEarea.initEditor = function(editorNumber) {
741 if (typeof(HTMLArea) == "undefined") {
742 RTEarea.initEditor.defer(40, null, [editorNumber]);
743 } else {
744 HTMLArea.initEditor(editorNumber);
745 }
746 };
747 }
748 /*]]>*/
749 </script>';
750 return $loadJavascriptCode;
751 }
752
753 /**
754 * Return the Javascript code for initializing the RTE
755 *
756 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
757 *
758 * @return string the Javascript code for initializing the RTE
759 */
760 function loadJScode($RTEcounter) {
761 return (!$this->is_FE() ? '' : '
762 ' . '/*<![CDATA[*/') . '
763 RTEarea.init();' . (!$this->is_FE() ? '' : '
764 /*]]>*/
765 ');
766 }
767
768 /**
769 * Return the Javascript code for configuring the RTE
770 *
771 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
772 * @param string $table: The table that includes this RTE (optional, necessary for IRRE).
773 * @param string $uid: The uid of that table that includes this RTE (optional, necessary for IRRE).
774 * @param string $field: The field of that record that includes this RTE (optional).
775 *
776 * @return string the Javascript code for configuring the RTE
777 */
778 function registerRTEinJS($RTEcounter, $table='', $uid='', $field='', $textAreaId = '') {
779
780 $configureRTEInJavascriptString = (!$this->is_FE() ? '' : '
781 ' . '/*<![CDATA[*/') . '
782 if (typeof(configureEditorInstance) == "undefined") {
783 configureEditorInstance = new Object();
784 }
785 configureEditorInstance["' . $textAreaId . '"] = function() {
786 if (typeof(RTEarea) == "undefined" || typeof(HTMLArea) == "undefined") {
787 window.setTimeout("configureEditorInstance[\'' . $textAreaId . '\']();", 40);
788 } else {
789 editornumber = "' . $textAreaId . '";
790 RTEarea[editornumber] = new Object();
791 RTEarea[editornumber].RTEtsConfigParams = "&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams()) . '";
792 RTEarea[editornumber].number = editornumber;
793 RTEarea[editornumber].deleted = false;
794 RTEarea[editornumber].textAreaId = "' . $textAreaId . '";
795 RTEarea[editornumber].id = "RTEarea" + editornumber;
796 RTEarea[editornumber].RTEWidthOverride = "' . trim($this->thisConfig['RTEWidthOverride']) . '";
797 RTEarea[editornumber].RTEHeightOverride = "' . trim($this->thisConfig['RTEHeightOverride']) . '";
798 RTEarea[editornumber].fullScreen = ' . ($this->fullScreen ? 'true' : 'false') . ';
799 RTEarea[editornumber].showStatusBar = ' . (trim($this->thisConfig['showStatusBar'])?'true':'false') . ';
800 RTEarea[editornumber].enableWordClean = ' . (trim($this->thisConfig['enableWordClean'])?'true':'false') . ';
801 RTEarea[editornumber].htmlRemoveComments = ' . (trim($this->thisConfig['removeComments'])?'true':'false') . ';
802 RTEarea[editornumber].disableEnterParagraphs = ' . (trim($this->thisConfig['disableEnterParagraphs'])?'true':'false') . ';
803 RTEarea[editornumber].disableObjectResizing = ' . (trim($this->thisConfig['disableObjectResizing'])?'true':'false') . ';
804 RTEarea[editornumber].removeTrailingBR = ' . (trim($this->thisConfig['removeTrailingBR'])?'true':'false') . ';
805 RTEarea[editornumber].useCSS = ' . (trim($this->thisConfig['useCSS'])?'true':'false') . ';
806 RTEarea[editornumber].keepButtonGroupTogether = ' . (trim($this->thisConfig['keepButtonGroupTogether'])?'true':'false') . ';
807 RTEarea[editornumber].disablePCexamples = ' . (trim($this->thisConfig['disablePCexamples'])?'true':'false') . ';
808 RTEarea[editornumber].showTagFreeClasses = ' . (trim($this->thisConfig['showTagFreeClasses'])?'true':'false') . ';
809 RTEarea[editornumber].useHTTPS = ' . ((trim(stristr($this->siteURL, 'https')) || $this->thisConfig['forceHTTPS'])?'true':'false') . ';
810 RTEarea[editornumber].tceformsNested = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(true) : '[]') . ';
811 RTEarea[editornumber].dialogueWindows = new Object();
812 RTEarea[editornumber].dialogueWindows.defaultPositionFromTop = ' . (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromTop'])? intval($this->thisConfig['dialogueWindows.']['defaultPositionFromTop']) : '100') . ';
813 RTEarea[editornumber].dialogueWindows.defaultPositionFromLeft = ' . (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'])? intval($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft']) : '100') . ';
814 RTEarea[editornumber].dialogueWindows.doNotResize = ' . (trim($this->thisConfig['dialogueWindows.']['doNotResize'])?'true':'false') . ';
815 RTEarea[editornumber].dialogueWindows.doNotCenter = ' . (trim($this->thisConfig['dialogueWindows.']['doNotCenter'])?'true':'false') . ';';
816
817 // The following properties apply only to the backend
818 if (!$this->is_FE()) {
819 $configureRTEInJavascriptString .= '
820 RTEarea[editornumber].sys_language_content = "' . $this->contentLanguageUid . '";
821 RTEarea[editornumber].typo3ContentLanguage = "' . $this->contentTypo3Language . '";
822 RTEarea[editornumber].typo3ContentCharset = "' . $this->contentCharset . '";
823 RTEarea[editornumber].userUid = "' . $this->userUid . '";';
824 }
825
826 // Setting the plugin flags
827 $configureRTEInJavascriptString .= '
828 RTEarea[editornumber].plugin = new Object();
829 RTEarea[editornumber].pathToPluginDirectory = new Object();';
830 foreach ($this->pluginEnabledArray as $pluginId) {
831 $configureRTEInJavascriptString .= '
832 RTEarea[editornumber].plugin.'.$pluginId.' = true;';
833 if (is_object($this->registeredPlugins[$pluginId])) {
834 $pathToPluginDirectory = $this->registeredPlugins[$pluginId]->getPathToPluginDirectory();
835 if ($pathToPluginDirectory) {
836 $configureRTEInJavascriptString .= '
837 RTEarea[editornumber].pathToPluginDirectory.'.$pluginId.' = "' . $pathToPluginDirectory . '";';
838 }
839 }
840 }
841
842 // Setting the buttons configuration
843 $configureRTEInJavascriptString .= '
844 RTEarea[editornumber].buttons = new Object();';
845 if (is_array($this->thisConfig['buttons.'])) {
846 foreach ($this->thisConfig['buttons.'] as $buttonIndex => $conf) {
847 $button = substr($buttonIndex, 0, -1);
848 if (in_array($button,$this->toolbar)) {
849 $configureRTEInJavascriptString .= '
850 RTEarea[editornumber].buttons.'.$button.' = ' . $this->buildNestedJSArray($conf) . ';';
851 }
852 }
853 }
854
855 // Setting the list of tags to be removed if specified in the RTE config
856 if (trim($this->thisConfig['removeTags'])) {
857 $configureRTEInJavascriptString .= '
858 RTEarea[editornumber].htmlRemoveTags = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTags'], 1)) . ')$/i;';
859 }
860
861 // Setting the list of tags to be removed with their contents if specified in the RTE config
862 if (trim($this->thisConfig['removeTagsAndContents'])) {
863 $configureRTEInJavascriptString .= '
864 RTEarea[editornumber].htmlRemoveTagsAndContents = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTagsAndContents'], 1)) . ')$/i;';
865 }
866 // Process default style configuration
867 $configureRTEInJavascriptString .= '
868 RTEarea[editornumber].defaultPageStyle = "' . $this->writeTemporaryFile('', 'defaultPageStyle', 'css', $this->buildStyleSheet()) . '";';
869 // Setting the pageStyle
870 $filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/res/contentcss/default.css';
871 $configureRTEInJavascriptString .= '
872 RTEarea[editornumber].pageStyle = "' . t3lib_div::createVersionNumberedFilename($this->getFullFileName($filename)) .'";';
873 // Process classes configuration
874 $classesConfigurationRequired = false;
875 foreach ($this->registeredPlugins as $pluginId => $plugin) {
876 if ($this->isPluginEnabled($pluginId)) {
877 $classesConfigurationRequired = $classesConfigurationRequired || $plugin->requiresClassesConfiguration();
878 }
879 }
880 if ($classesConfigurationRequired) {
881 $configureRTEInJavascriptString .= $this->buildJSClassesConfig($RTEcounter);
882 }
883 // Add Javascript configuration for registered plugins
884 foreach ($this->registeredPlugins as $pluginId => $plugin) {
885 if ($this->isPluginEnabled($pluginId)) {
886 $configureRTEInJavascriptString .= $plugin->buildJavascriptConfiguration('editornumber');
887 }
888 }
889 // Avoid premature reference to HTMLArea when being initially loaded by IRRE Ajax call
890 $configureRTEInJavascriptString .= '
891 RTEarea[editornumber].toolbar = ' . $this->getJSToolbarArray() . ';
892 RTEarea[editornumber].convertButtonId = ' . json_encode(array_flip($this->convertToolbarForHtmlAreaArray)) . ';
893 RTEarea.initEditor(editornumber);
894 }
895 };
896 configureEditorInstance["' . $textAreaId . '"]();'. (!$this->is_FE() ? '' : '
897 /*]]>*/');
898 return $configureRTEInJavascriptString;
899 }
900
901 /**
902 * Return true, if the plugin can be loaded
903 *
904 * @param string $pluginId: The identification string of the plugin
905 *
906 * @return boolean true if the plugin can be loaded
907 */
908
909 function isPluginEnabled($pluginId) {
910 return in_array($pluginId, $this->pluginEnabledArray);
911 }
912
913 /**
914 * Build the default content style sheet
915 *
916 * @return string Style sheet
917 */
918 function buildStyleSheet() {
919
920 if (!trim($this->thisConfig['ignoreMainStyleOverride'])) {
921 $mainStyle_font = $this->thisConfig['mainStyle_font'] ? $this->thisConfig['mainStyle_font']: 'Verdana,sans-serif';
922
923 $mainElements = array();
924 $mainElements['P'] = $this->thisConfig['mainStyleOverride_add.']['P'];
925 $elList = explode(',','H1,H2,H3,H4,H5,H6,PRE');
926 foreach ($elList as $elListName) {
927 if ($this->thisConfig['mainStyleOverride_add.'][$elListName]) {
928 $mainElements[$elListName] = $this->thisConfig['mainStyleOverride_add.'][$elListName];
929 }
930 }
931
932 $addElementCode = '';
933 foreach ($mainElements as $elListName => $elValue) {
934 $addElementCode .= strToLower($elListName) . ' {' . $elValue . '}' . LF;
935 }
936
937 $stylesheet = $this->thisConfig['mainStyleOverride'] ? $this->thisConfig['mainStyleOverride'] : LF .
938 'body.htmlarea-content-body { font-family: ' . $mainStyle_font .
939 '; font-size: '.($this->thisConfig['mainStyle_size'] ? $this->thisConfig['mainStyle_size'] : '12px') .
940 '; color: '.($this->thisConfig['mainStyle_color']?$this->thisConfig['mainStyle_color'] : 'black') .
941 '; background-color: '.($this->thisConfig['mainStyle_bgcolor'] ? $this->thisConfig['mainStyle_bgcolor'] : 'white') .
942 ';'.$this->thisConfig['mainStyleOverride_add.']['BODY'].'}' . LF .
943 'td { ' . $this->thisConfig['mainStyleOverride_add.']['TD'].'}' . LF .
944 'div { ' . $this->thisConfig['mainStyleOverride_add.']['DIV'].'}' . LF .
945 'pre { ' . $this->thisConfig['mainStyleOverride_add.']['PRE'].'}' . LF .
946 'ol { ' . $this->thisConfig['mainStyleOverride_add.']['OL'].'}' . LF .
947 'ul { ' . $this->thisConfig['mainStyleOverride_add.']['UL'].'}' . LF .
948 'blockquote { ' . $this->thisConfig['mainStyleOverride_add.']['BLOCKQUOTE'].'}' . LF .
949 $addElementCode;
950
951 if (is_array($this->thisConfig['inlineStyle.'])) {
952 $stylesheet .= LF . implode(LF, $this->thisConfig['inlineStyle.']) . LF;
953 }
954 } else {
955 $stylesheet = '/* mainStyleOverride and inlineStyle properties ignored. */';
956 }
957 return $stylesheet;
958 }
959
960 /**
961 * Return Javascript configuration of classes
962 *
963 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
964 *
965 * @return string Javascript configuration of classes
966 */
967 function buildJSClassesConfig($RTEcounter) {
968 // Build JS array of lists of classes
969 $classesTagList = 'classesCharacter, classesParagraph, classesImage, classesTable, classesLinks, classesTD';
970 $classesTagConvert = array( 'classesCharacter' => 'span', 'classesParagraph' => 'div', 'classesImage' => 'img', 'classesTable' => 'table', 'classesLinks' => 'a', 'classesTD' => 'td');
971 $classesTagArray = t3lib_div::trimExplode(',' , $classesTagList);
972 $configureRTEInJavascriptString = '
973 RTEarea[editornumber].classesTag = new Object();';
974 foreach ($classesTagArray as $classesTagName) {
975 $HTMLAreaJSClasses = ($this->thisConfig[$classesTagName])?('"' . $this->cleanList($this->thisConfig[$classesTagName]) . '";'):'null;';
976 $configureRTEInJavascriptString .= '
977 RTEarea[editornumber].classesTag.'. $classesTagConvert[$classesTagName] .' = '. $HTMLAreaJSClasses;
978 }
979 // Include JS arrays of configured classes
980 $configureRTEInJavascriptString .= '
981 RTEarea[editornumber].classesUrl = "' . $this->writeTemporaryFile('', 'classes_'.$LANG->lang, 'js', $this->buildJSClassesArray()) . '";';
982 return $configureRTEInJavascriptString;
983 }
984
985 /**
986 * Return JS arrays of classes configuration
987 *
988 * @return string JS classes arrays
989 */
990 function buildJSClassesArray() {
991 if ($this->is_FE()) {
992 $RTEProperties = $this->RTEsetup;
993 } else {
994 $RTEProperties = $this->RTEsetup['properties'];
995 }
996 $classesArray = array('labels' => array(), 'values' => array(), 'noShow' => array(), 'alternating' => array(), 'counting' => array(), 'XOR' => array());
997 $JSClassesArray = '';
998 // Scanning the list of classes if specified in the RTE config
999 if (is_array($RTEProperties['classes.'])) {
1000 foreach ($RTEProperties['classes.'] as $className => $conf) {
1001 $className = rtrim($className, '.');
1002 $classesArray['labels'][$className] = $this->getPageConfigLabel($conf['name'], FALSE);
1003 $classesArray['values'][$className] = str_replace('\\\'', '\'', $conf['value']);
1004 if (isset($conf['noShow'])) {
1005 $classesArray['noShow'][$className] = $conf['noShow'];
1006 }
1007 if (is_array($conf['alternating.'])) {
1008 $classesArray['alternating'][$className] = $conf['alternating.'];
1009 }
1010 if (is_array($conf['counting.'])) {
1011 $classesArray['counting'][$className] = $conf['counting.'];
1012 }
1013 }
1014 }
1015 // Scanning the list of sets of mutually exclusives classes if specified in the RTE config
1016 if (is_array($RTEProperties['mutuallyExclusiveClasses.'])) {
1017 foreach ($RTEProperties['mutuallyExclusiveClasses.'] as $listName => $conf) {
1018 $classSet = t3lib_div::trimExplode(',', $conf, 1);
1019 $classList = implode(',', $classSet);
1020 foreach ($classSet as $className) {
1021 $classesArray['XOR'][$className] = '/^(' . implode('|', t3lib_div::trimExplode(',', t3lib_div::rmFromList($className, $classList), 1)) . ')$/';
1022 }
1023 }
1024 }
1025 foreach ($classesArray as $key => $subArray) {
1026 $JSClassesArray .= 'HTMLArea.classes' . ucfirst($key) . ' = ' . $this->buildNestedJSArray($subArray) . ';' . LF;
1027 }
1028 return $JSClassesArray;
1029 }
1030
1031 /**
1032 * Translate Page TS Config array in JS nested array definition
1033 * Replace 0 values with false
1034 * Unquote regular expression values
1035 * Replace empty arrays with empty objects
1036 *
1037 * @param array $conf: Page TSConfig configuration array
1038 *
1039 * @return string nested JS array definition
1040 */
1041 function buildNestedJSArray($conf) {
1042 $convertedConf = t3lib_div::removeDotsFromTS($conf);
1043 if ($this->is_FE()) {
1044 $GLOBALS['TSFE']->csConvObj->convArray($convertedConf, ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'iso-8859-1'), 'utf-8');
1045 } else {
1046 $GLOBALS['LANG']->csConvObj->convArray($convertedConf, $GLOBALS['LANG']->charSet, 'utf-8');
1047 }
1048 return str_replace(array(':"0"', ':"\/^(', ')$\/i"', ':"\/^(', ')$\/"', '[]'), array(':false', ':/^(', ')$/i', ':/^(', ')$/', '{}'), json_encode($convertedConf));
1049 }
1050
1051 /**
1052 * Return a Javascript localization array for htmlArea RTE
1053 *
1054 * @return string Javascript localization array
1055 */
1056 function buildJSMainLangArray() {
1057 $JSLanguageArray = 'HTMLArea.I18N = new Object();' . LF;
1058 $labelsArray = array('tooltips' => array(), 'msg' => array(), 'dialogs' => array());
1059 foreach ($labelsArray as $labels => $subArray) {
1060 $LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $this->ID . '/htmlarea/locallang_' . $labels . '.xml', $this->language, 'utf-8');
1061 if (!empty($LOCAL_LANG[$this->language])) {
1062 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'], $LOCAL_LANG[$this->language]);
1063 } else {
1064 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1065 }
1066 $labelsArray[$labels] = $LOCAL_LANG[$this->language];
1067 }
1068 $JSLanguageArray .= 'HTMLArea.I18N = ' . json_encode($labelsArray) . ';' . LF;
1069 return $JSLanguageArray;
1070 }
1071
1072 /**
1073 * Writes contents in a file in typo3temp/rtehtmlarea directory and returns the file name
1074 *
1075 * @param string $sourceFileName: The name of the file from which the contents should be extracted
1076 * @param string $label: A label to insert at the beginning of the name of the file
1077 * @param string $fileExtension: The file extension of the file, defaulting to 'js'
1078 * @param string $contents: The contents to write into the file if no $sourceFileName is provided
1079 *
1080 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1081 */
1082 public function writeTemporaryFile($sourceFileName='', $label, $fileExtension='js', $contents='', $concatenate = FALSE) {
1083 global $TYPO3_CONF_VARS;
1084
1085 if ($sourceFileName) {
1086 $output = '';
1087 $source = t3lib_div::getFileAbsFileName($sourceFileName);
1088 $output = file_get_contents($source);
1089 } else {
1090 $output = $contents;
1091 }
1092 $compress = $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] && ($fileExtension == 'js') && ($output != '');
1093 $relativeFilename = 'typo3temp/' . $this->ID . '/' . str_replace('-','_',$label) . '_' . t3lib_div::shortMD5(($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . ($sourceFileName ? $sourceFileName : $output)), 20) . ($compress ? '_compressed' : '') . '.' . $fileExtension;
1094 $destination = PATH_site . $relativeFilename;
1095 if(!file_exists($destination)) {
1096 $compressedJavaScript = '';
1097 if ($compress && $fileExtension == 'js') {
1098 $compressedJavaScript = t3lib_div::minifyJavaScript($output);
1099 }
1100 $failure = t3lib_div::writeFileToTypo3tempDir($destination, $compressedJavaScript ? $compressedJavaScript : $output);
1101 if ($failure) {
1102 die($failure);
1103 }
1104 }
1105 if ($concatenate && $fileExtension == 'js') {
1106 $this->cumulativeScripts[$this->TCEform->RTEcounter][] = $destination;
1107 }
1108 if ($this->is_FE()) {
1109 return ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . t3lib_div::createVersionNumberedFilename($relativeFilename);
1110 } else {
1111 $filename = t3lib_div::createVersionNumberedFilename(($this->isFrontendEditActive() ? '' : ('../' . $this->backPath)) . $relativeFilename);
1112 if ($this->isFrontendEditActive()) {
1113 $filename = preg_replace('/^..\//', '', $filename);
1114 }
1115 return $filename;
1116 }
1117 }
1118 /**
1119 * Concatenates all accumulated scripts in a file in typo3temp/rtehtmlarea directory and returns the file name
1120 *
1121 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1122 *
1123 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1124 */
1125 protected function doConcatenate($RTEcounter) {
1126 $fileExtension = 'js';
1127 $compress = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts'];
1128 $token = implode('|', $this->cumulativeScripts[$RTEcounter]);
1129 $relativeFilename = 'typo3temp/' . $this->ID . '/' . 'htmlarea_cumulative' . '_' . t3lib_div::shortMD5(($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . $token ), 20) . ($compress ? '_compressed' : '') . '.' . $fileExtension;
1130 $destination = PATH_site . $relativeFilename;
1131 if (!file_exists($destination)) {
1132 foreach ($this->cumulativeScripts[$RTEcounter] as $fileName) {
1133 $contents = file_get_contents($fileName);
1134 if (!file_exists($destination)) {
1135 $failure = t3lib_div::writeFileToTypo3tempDir($destination, $contents);
1136 if ($failure) {
1137 die($failure);
1138 }
1139 } else {
1140 $success = file_put_contents($destination, $contents, FILE_APPEND);
1141 if (!$success) {
1142 die('Could not append script' + $fileName);
1143 }
1144 }
1145 }
1146 }
1147 if ($this->is_FE()) {
1148 $filename = ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . t3lib_div::createVersionNumberedFilename($relativeFilename);
1149 } else {
1150 if ($compress) {
1151 $compressor = t3lib_div::makeInstance('t3lib_Compressor');
1152 $filename = $compressor->compressJsFile('../' . ($this->isFrontendEditActive() ? '' : $this->backPath) . $relativeFilename);
1153 } else {
1154 $filename = t3lib_div::createVersionNumberedFilename(($this->isFrontendEditActive() ? '' : ('../' . $this->backPath)) . $relativeFilename);
1155 }
1156 if ($this->isFrontendEditActive()) {
1157 $filename = preg_replace('/^..\//', '', $filename);
1158 }
1159 }
1160 return $filename;
1161 }
1162
1163 /**
1164 * Return a file name containing the main JS language array for HTMLArea
1165 *
1166 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1167 *
1168 * @return string filename
1169 */
1170 function buildJSMainLangFile($RTEcounter) {
1171 $contents = $this->buildJSMainLangArray() . LF;
1172 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
1173 $contents .= $this->buildJSLangArray($pluginId) . LF;
1174 }
1175 return $this->writeTemporaryFile('', $this->language.'_'.$this->OutputCharset, 'js', $contents, TRUE);
1176 }
1177
1178 /**
1179 * Return a Javascript localization array for the plugin
1180 *
1181 * @param string $plugin: identification string of the plugin
1182 *
1183 * @return string Javascript localization array
1184 */
1185
1186 function buildJSLangArray($plugin) {
1187 $LOCAL_LANG = FALSE;
1188 $extensionKey = is_object($this->registeredPlugins[$plugin]) ? $this->registeredPlugins[$plugin]->getExtensionKey() : $this->ID;
1189 $LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $plugin . '/locallang.xml', $this->language, 'utf-8', 1);
1190 $linebreak = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts'] ? '' : LF;
1191 $JSLanguageArray = 'HTMLArea.I18N["' . $plugin . '"] = new Object();' . $linebreak;
1192 if (is_array($LOCAL_LANG)) {
1193 if (!empty($LOCAL_LANG[$this->language])) {
1194 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'],$LOCAL_LANG[$this->language]);
1195 } else {
1196 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1197 }
1198 $JSLanguageArray .= 'HTMLArea.I18N["' . $plugin . '"] = ' . json_encode($LOCAL_LANG[$this->language]) . ';'. LF;
1199 }
1200 return $JSLanguageArray;
1201 }
1202
1203 /**
1204 * Return the JS code of the toolbar configuration for the HTMLArea editor
1205 *
1206 * @return string the JS code as nested JS arrays
1207 */
1208 protected function getJSToolbarArray() {
1209 // The toolbar array
1210 $toolbar = array();
1211 // The current row; a "linebreak" ends the current row
1212 $row = array();
1213 // The current group; each group is between "bar"s; a "linebreak" ends the current group
1214 $group = array();
1215 // Process each toolbar item in the toolbar order list
1216 foreach ($this->toolbarOrderArray as $item) {
1217 switch ($item) {
1218 case 'linebreak':
1219 // Add row to toolbar if not empty
1220 if (!empty($group)) {
1221 $row[] = $group;
1222 $group = array();
1223 }
1224 if (!empty($row)) {
1225 $toolbar[] = $row;
1226 $row = array();
1227 }
1228 break;
1229 case 'bar':
1230 // Add group to row if not empty
1231 if (!empty($group)) {
1232 $row[] = $group;
1233 $group = array();
1234 }
1235 break;
1236 case 'space':
1237 if (end($group) != $this->convertToolbarForHTMLArea($item)) {
1238 $group[] = $this->convertToolbarForHTMLArea($item);
1239 }
1240 break;
1241 default:
1242 if (in_array($item, $this->toolbar)) {
1243 // Add the item to the group
1244 $convertedItem = $this->convertToolbarForHTMLArea($item);
1245 if ($convertedItem) {
1246 $group[] = $convertedItem;
1247 }
1248 }
1249 break;
1250 }
1251 }
1252 // Add the last group and last line, if not empty
1253 if (!empty($group)) {
1254 $row[] = $group;
1255 }
1256 if (!empty($row)) {
1257 $toolbar[] = $row;
1258 }
1259 return json_encode($toolbar);
1260 }
1261
1262 public function getLLContent($string) {
1263 global $LANG;
1264
1265 $BE_lang = $LANG->lang;
1266 $BE_charSet = $LANG->charSet;
1267 $LANG->lang = $this->contentTypo3Language;
1268 $LANG->charSet = $this->contentCharset;
1269 $LLString = $LANG->JScharCode($LANG->sL($string));
1270 $LANG->lang = $BE_lang;
1271 $LANG->charSet = $BE_charSet;
1272 return $LLString;
1273 }
1274
1275 public function getPageConfigLabel($string,$JScharCode=1) {
1276 global $LANG, $TSFE, $TYPO3_CONF_VARS;
1277
1278 if ($this->is_FE()) {
1279 if (strcmp(substr($string,0,4),'LLL:') && $TYPO3_CONF_VARS['BE']['forceCharset']) {
1280 // A pure string coming from Page TSConfig must be in forceCharset, otherwise we just don't know..
1281 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $TYPO3_CONF_VARS['BE']['forceCharset'], $this->OutputCharset);
1282 } else {
1283 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $this->charset, $this->OutputCharset);
1284 }
1285 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1286 $label = $JScharCode ? $this->feJScharCode($label) : $label;
1287 } else {
1288 if (strcmp(substr($string,0,4),'LLL:')) {
1289 $label = $string;
1290 } else {
1291 $label = $LANG->sL(trim($string));
1292 }
1293 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1294 $label = $JScharCode ? $LANG->JScharCode($label): $label;
1295 }
1296 return $label;
1297 }
1298
1299 function feJScharCode($str) {
1300 global $TSFE;
1301 // Convert string to UTF-8:
1302 if ($this->OutputCharset != 'utf-8') $str = $TSFE->csConvObj->utf8_encode($str,$this->OutputCharset);
1303 // Convert the UTF-8 string into a array of char numbers:
1304 $nArr = $TSFE->csConvObj->utf8_to_numberarray($str);
1305 return 'String.fromCharCode('.implode(',',$nArr).')';
1306 }
1307
1308 public function getFullFileName($filename) {
1309 if (substr($filename,0,4)=='EXT:') { // extension
1310 list($extKey,$local) = explode('/',substr($filename,4),2);
1311 $newFilename = '';
1312 if (strcmp($extKey,'') && t3lib_extMgm::isLoaded($extKey) && strcmp($local,'')) {
1313 $newFilename = ($this->is_FE() ? t3lib_extMgm::siteRelPath($extKey) : $this->backPath . t3lib_extMgm::extRelPath($extKey)) . $local;
1314 }
1315 } elseif (substr($filename,0,1) != '/') {
1316 $newFilename = (($this->is_FE() || $this->isFrontendEditActive()) ? '' : ('../' . $this->backPath)) . $filename;
1317 } else {
1318 $newFilename = (($this->is_FE() || $this->isFrontendEditActive()) ? '' : ('../' . $this->backPath)) . substr($filename, 1);
1319 }
1320 return $newFilename;
1321 }
1322
1323 /**
1324 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1325 * This is for submit function of the form.
1326 *
1327 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1328 * @param string $formName: the name of the form
1329 * @param string $textareaId: the id of the textarea
1330 *
1331 * @return string Javascript code
1332 */
1333 function setSaveRTE($RTEcounter, $formName, $textareaId) {
1334 return 'if (RTEarea["' . $textareaId . '"]) { document.' . $formName . '["' . $textareaId . '"].value = RTEarea["' . $textareaId . '"].editor.getHTML(); } else { OK = 0; };';
1335 }
1336
1337 /**
1338 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1339 * This is for submit function of the form.
1340 *
1341 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1342 * @param string $formName: the name of the form
1343 * @param string $textareaId: the id of the textarea
1344 *
1345 * @return string Javascript code
1346 */
1347 function setDeleteRTE($RTEcounter, $formName, $textareaId) {
1348 return 'if (RTEarea["' . $textareaId . '"]) { RTEarea["' . $textareaId . '"].deleted = true;}';
1349 }
1350
1351 /**
1352 * Return true if we are in the FE, but not in the FE editing feature of BE.
1353 *
1354 * @return boolean
1355 */
1356
1357 function is_FE() {
1358 return is_object($GLOBALS['TSFE']) && !$this->isFrontendEditActive();
1359 }
1360
1361 /**
1362 * Checks whether frontend editing is active.
1363 *
1364 * @return boolean
1365 */
1366 public function isFrontendEditActive() {
1367 return is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->beUserLogin && ($GLOBALS['BE_USER']->frontendEdit instanceof t3lib_frontendedit);
1368 }
1369 /**
1370 * Client Browser Information
1371 *
1372 * @param string $userAgent: The useragent string, t3lib_div::getIndpEnv('HTTP_USER_AGENT')
1373 * @return array Contains keys "useragent", "browser", "version", "system"
1374 * where "browser" is limited to the engines
1375 * and where "version" is a floating number
1376 */
1377 function clientInfo ($userAgent='') {
1378 if (!$userAgent) {
1379 $userAgent = t3lib_div::getIndpEnv('HTTP_USER_AGENT');
1380 }
1381 $browserInfo = t3lib_utility_Client::getBrowserInfo($userAgent);
1382 // Known engines: order is not irrelevant!
1383 $knownEngines = array('opera', 'msie', 'gecko', 'webkit');
1384 if (is_array($browserInfo['all'])) {
1385 foreach ($knownEngines as $engine) {
1386 if ($browserInfo['all'][$engine]) {
1387 $browserInfo['browser'] = $engine;
1388 $browserInfo['version'] = t3lib_utility_Client::getVersion($browserInfo['all'][$engine]);
1389 break;
1390 }
1391 }
1392 }
1393 return $browserInfo;
1394 }
1395 /***************************
1396 *
1397 * OTHER FUNCTIONS: (from Classic RTE)
1398 *
1399 ***************************/
1400 /**
1401 * @return [type] ...
1402 * @desc
1403 */
1404
1405 function RTEtsConfigParams() {
1406 if($this->is_FE()) {
1407 return '';
1408 } else {
1409 $p = t3lib_BEfunc::getSpecConfParametersFromArray($this->specConf['rte_transform']['parameters']);
1410 return $this->elementParts[0].':'.$this->elementParts[1].':'.$this->elementParts[2].':'.$this->thePid.':'.$this->typeVal.':'.$this->tscPID.':'.$p['imgpath'];
1411 }
1412 }
1413
1414 public function cleanList($str) {
1415 if (strstr($str,'*')) {
1416 $str = '*';
1417 } else {
1418 $str = implode(',',array_unique(t3lib_div::trimExplode(',',$str,1)));
1419 }
1420 return $str;
1421 }
1422
1423 function filterStyleEl($elValue,$matchList) {
1424 $matchParts = t3lib_div::trimExplode(',',$matchList,1);
1425 $styleParts = explode(';',$elValue);
1426 $nStyle=array();
1427 foreach ($styleParts as $k => $p) {
1428 $pp = t3lib_div::trimExplode(':',$p);
1429 if ($pp[0]&&$pp[1]) {
1430 foreach ($matchParts as $el) {
1431 $star=substr($el,-1)=='*';
1432 if (!strcmp($pp[0],$el) || ($star && t3lib_div::isFirstPartOfStr($pp[0],substr($el,0,-1)) )) {
1433 $nStyle[]=$pp[0].':'.$pp[1];
1434 } else unset($styleParts[$k]);
1435 }
1436 } else {
1437 unset($styleParts[$k]);
1438 }
1439 }
1440 return implode('; ',$nStyle);
1441 }
1442
1443 // Hook on lorem_ipsum extension to insert text into the RTE in wysiwyg mode
1444 function loremIpsumInsert($params) {
1445 return "
1446 if (typeof(lorem_ipsum) == 'function' && " . $params['element'] . ".tagName.toLowerCase() == 'textarea' ) lorem_ipsum(" . $params['element'] . ", lipsum_temp_strings[lipsum_temp_pointer]);
1447 ";
1448 }
1449 }
1450 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']) {
1451 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']);
1452 }
1453 ?>