910acca280f9c9f18974fdc1211ba4f107040eb2
[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 $filename = ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . t3lib_div::createVersionNumberedFilename($relativeFilename);
1110 } else {
1111 $filename = t3lib_div::createVersionNumberedFilename(($this->isFrontendEditActive() ? '' : ($this->backPath . '../')) . $relativeFilename);
1112 }
1113 return t3lib_div::resolveBackPath($filename);
1114 }
1115 /**
1116 * Concatenates all accumulated scripts in a file in typo3temp/rtehtmlarea directory and returns the file name
1117 *
1118 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1119 *
1120 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1121 */
1122 protected function doConcatenate($RTEcounter) {
1123 $fileExtension = 'js';
1124 $compress = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts'];
1125 $token = implode('|', $this->cumulativeScripts[$RTEcounter]);
1126 $relativeFilename = 'typo3temp/' . $this->ID . '/' . 'htmlarea_cumulative' . '_' . t3lib_div::shortMD5(($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . $token ), 20) . ($compress ? '_compressed' : '') . '.' . $fileExtension;
1127 $destination = PATH_site . $relativeFilename;
1128 if (!file_exists($destination)) {
1129 foreach ($this->cumulativeScripts[$RTEcounter] as $fileName) {
1130 $contents = file_get_contents($fileName);
1131 if (!file_exists($destination)) {
1132 $failure = t3lib_div::writeFileToTypo3tempDir($destination, $contents);
1133 if ($failure) {
1134 die($failure);
1135 }
1136 } else {
1137 $success = file_put_contents($destination, $contents, FILE_APPEND);
1138 if (!$success) {
1139 die('Could not append script' + $fileName);
1140 }
1141 }
1142 }
1143 }
1144 if ($this->is_FE()) {
1145 $filename = ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . t3lib_div::createVersionNumberedFilename($relativeFilename);
1146 } else {
1147 if ($compress) {
1148 $compressor = t3lib_div::makeInstance('t3lib_Compressor');
1149 $filename = $compressor->compressJsFile(($this->isFrontendEditActive() ? '' : $this->backPath) . '../' . $relativeFilename);
1150 if ($this->isFrontendEditActive()) {
1151 $filename = preg_replace('/^..\//', '', $filename);
1152 }
1153 } else {
1154 $filename = t3lib_div::createVersionNumberedFilename(($this->isFrontendEditActive() ? '' : ($this->backPath . '../')) . $relativeFilename);
1155 }
1156 }
1157 return t3lib_div::resolveBackPath($filename);
1158 }
1159
1160 /**
1161 * Return a file name containing the main JS language array for HTMLArea
1162 *
1163 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1164 *
1165 * @return string filename
1166 */
1167 function buildJSMainLangFile($RTEcounter) {
1168 $contents = $this->buildJSMainLangArray() . LF;
1169 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
1170 $contents .= $this->buildJSLangArray($pluginId) . LF;
1171 }
1172 return $this->writeTemporaryFile('', $this->language.'_'.$this->OutputCharset, 'js', $contents, TRUE);
1173 }
1174
1175 /**
1176 * Return a Javascript localization array for the plugin
1177 *
1178 * @param string $plugin: identification string of the plugin
1179 *
1180 * @return string Javascript localization array
1181 */
1182
1183 function buildJSLangArray($plugin) {
1184 $LOCAL_LANG = FALSE;
1185 $extensionKey = is_object($this->registeredPlugins[$plugin]) ? $this->registeredPlugins[$plugin]->getExtensionKey() : $this->ID;
1186 $LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $plugin . '/locallang.xml', $this->language, 'utf-8', 1);
1187 $linebreak = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts'] ? '' : LF;
1188 $JSLanguageArray = 'HTMLArea.I18N["' . $plugin . '"] = new Object();' . $linebreak;
1189 if (is_array($LOCAL_LANG)) {
1190 if (!empty($LOCAL_LANG[$this->language])) {
1191 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'],$LOCAL_LANG[$this->language]);
1192 } else {
1193 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1194 }
1195 $JSLanguageArray .= 'HTMLArea.I18N["' . $plugin . '"] = ' . json_encode($LOCAL_LANG[$this->language]) . ';'. LF;
1196 }
1197 return $JSLanguageArray;
1198 }
1199
1200 /**
1201 * Return the JS code of the toolbar configuration for the HTMLArea editor
1202 *
1203 * @return string the JS code as nested JS arrays
1204 */
1205 protected function getJSToolbarArray() {
1206 // The toolbar array
1207 $toolbar = array();
1208 // The current row; a "linebreak" ends the current row
1209 $row = array();
1210 // The current group; each group is between "bar"s; a "linebreak" ends the current group
1211 $group = array();
1212 // Process each toolbar item in the toolbar order list
1213 foreach ($this->toolbarOrderArray as $item) {
1214 switch ($item) {
1215 case 'linebreak':
1216 // Add row to toolbar if not empty
1217 if (!empty($group)) {
1218 $row[] = $group;
1219 $group = array();
1220 }
1221 if (!empty($row)) {
1222 $toolbar[] = $row;
1223 $row = array();
1224 }
1225 break;
1226 case 'bar':
1227 // Add group to row if not empty
1228 if (!empty($group)) {
1229 $row[] = $group;
1230 $group = array();
1231 }
1232 break;
1233 case 'space':
1234 if (end($group) != $this->convertToolbarForHTMLArea($item)) {
1235 $group[] = $this->convertToolbarForHTMLArea($item);
1236 }
1237 break;
1238 default:
1239 if (in_array($item, $this->toolbar)) {
1240 // Add the item to the group
1241 $convertedItem = $this->convertToolbarForHTMLArea($item);
1242 if ($convertedItem) {
1243 $group[] = $convertedItem;
1244 }
1245 }
1246 break;
1247 }
1248 }
1249 // Add the last group and last line, if not empty
1250 if (!empty($group)) {
1251 $row[] = $group;
1252 }
1253 if (!empty($row)) {
1254 $toolbar[] = $row;
1255 }
1256 return json_encode($toolbar);
1257 }
1258
1259 public function getLLContent($string) {
1260 global $LANG;
1261
1262 $BE_lang = $LANG->lang;
1263 $BE_charSet = $LANG->charSet;
1264 $LANG->lang = $this->contentTypo3Language;
1265 $LANG->charSet = $this->contentCharset;
1266 $LLString = $LANG->JScharCode($LANG->sL($string));
1267 $LANG->lang = $BE_lang;
1268 $LANG->charSet = $BE_charSet;
1269 return $LLString;
1270 }
1271
1272 public function getPageConfigLabel($string,$JScharCode=1) {
1273 global $LANG, $TSFE, $TYPO3_CONF_VARS;
1274
1275 if ($this->is_FE()) {
1276 if (strcmp(substr($string,0,4),'LLL:') && $TYPO3_CONF_VARS['BE']['forceCharset']) {
1277 // A pure string coming from Page TSConfig must be in forceCharset, otherwise we just don't know..
1278 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $TYPO3_CONF_VARS['BE']['forceCharset'], $this->OutputCharset);
1279 } else {
1280 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $this->charset, $this->OutputCharset);
1281 }
1282 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1283 $label = $JScharCode ? $this->feJScharCode($label) : $label;
1284 } else {
1285 if (strcmp(substr($string,0,4),'LLL:')) {
1286 $label = $string;
1287 } else {
1288 $label = $LANG->sL(trim($string));
1289 }
1290 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1291 $label = $JScharCode ? $LANG->JScharCode($label): $label;
1292 }
1293 return $label;
1294 }
1295
1296 function feJScharCode($str) {
1297 global $TSFE;
1298 // Convert string to UTF-8:
1299 if ($this->OutputCharset != 'utf-8') $str = $TSFE->csConvObj->utf8_encode($str,$this->OutputCharset);
1300 // Convert the UTF-8 string into a array of char numbers:
1301 $nArr = $TSFE->csConvObj->utf8_to_numberarray($str);
1302 return 'String.fromCharCode('.implode(',',$nArr).')';
1303 }
1304
1305 public function getFullFileName($filename) {
1306 if (substr($filename,0,4)=='EXT:') { // extension
1307 list($extKey,$local) = explode('/',substr($filename,4),2);
1308 $newFilename = '';
1309 if (strcmp($extKey,'') && t3lib_extMgm::isLoaded($extKey) && strcmp($local,'')) {
1310 $newFilename = (($this->is_FE() || $this->isFrontendEditActive()) ? t3lib_extMgm::siteRelPath($extKey) : $this->backPath . t3lib_extMgm::extRelPath($extKey)) . $local;
1311 }
1312 } elseif (substr($filename,0,1) != '/') {
1313 $newFilename = (($this->is_FE() || $this->isFrontendEditActive()) ? '' : ($this->backPath . '../')) . $filename;
1314 } else {
1315 $newFilename = (($this->is_FE() || $this->isFrontendEditActive()) ? '' : ($this->backPath . '../')) . substr($filename, 1);
1316 }
1317 return t3lib_div::resolveBackPath($newFilename);
1318 }
1319
1320 /**
1321 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1322 * This is for submit function of the form.
1323 *
1324 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1325 * @param string $formName: the name of the form
1326 * @param string $textareaId: the id of the textarea
1327 *
1328 * @return string Javascript code
1329 */
1330 function setSaveRTE($RTEcounter, $formName, $textareaId) {
1331 return 'if (RTEarea["' . $textareaId . '"]) { document.' . $formName . '["' . $textareaId . '"].value = RTEarea["' . $textareaId . '"].editor.getHTML(); } else { OK = 0; };';
1332 }
1333
1334 /**
1335 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1336 * This is for submit function of the form.
1337 *
1338 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1339 * @param string $formName: the name of the form
1340 * @param string $textareaId: the id of the textarea
1341 *
1342 * @return string Javascript code
1343 */
1344 function setDeleteRTE($RTEcounter, $formName, $textareaId) {
1345 return 'if (RTEarea["' . $textareaId . '"]) { RTEarea["' . $textareaId . '"].deleted = true;}';
1346 }
1347
1348 /**
1349 * Return true if we are in the FE, but not in the FE editing feature of BE.
1350 *
1351 * @return boolean
1352 */
1353
1354 function is_FE() {
1355 return is_object($GLOBALS['TSFE']) && !$this->isFrontendEditActive();
1356 }
1357
1358 /**
1359 * Checks whether frontend editing is active.
1360 *
1361 * @return boolean
1362 */
1363 public function isFrontendEditActive() {
1364 return is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->beUserLogin && ($GLOBALS['BE_USER']->frontendEdit instanceof t3lib_frontendedit);
1365 }
1366 /**
1367 * Client Browser Information
1368 *
1369 * @param string $userAgent: The useragent string, t3lib_div::getIndpEnv('HTTP_USER_AGENT')
1370 * @return array Contains keys "useragent", "browser", "version", "system"
1371 * where "browser" is limited to the engines
1372 * and where "version" is a floating number
1373 */
1374 function clientInfo ($userAgent='') {
1375 if (!$userAgent) {
1376 $userAgent = t3lib_div::getIndpEnv('HTTP_USER_AGENT');
1377 }
1378 $browserInfo = t3lib_utility_Client::getBrowserInfo($userAgent);
1379 // Known engines: order is not irrelevant!
1380 $knownEngines = array('opera', 'msie', 'gecko', 'webkit');
1381 if (is_array($browserInfo['all'])) {
1382 foreach ($knownEngines as $engine) {
1383 if ($browserInfo['all'][$engine]) {
1384 $browserInfo['browser'] = $engine;
1385 $browserInfo['version'] = t3lib_utility_Client::getVersion($browserInfo['all'][$engine]);
1386 break;
1387 }
1388 }
1389 }
1390 return $browserInfo;
1391 }
1392 /***************************
1393 *
1394 * OTHER FUNCTIONS: (from Classic RTE)
1395 *
1396 ***************************/
1397 /**
1398 * @return [type] ...
1399 * @desc
1400 */
1401
1402 function RTEtsConfigParams() {
1403 if($this->is_FE()) {
1404 return '';
1405 } else {
1406 $p = t3lib_BEfunc::getSpecConfParametersFromArray($this->specConf['rte_transform']['parameters']);
1407 return $this->elementParts[0].':'.$this->elementParts[1].':'.$this->elementParts[2].':'.$this->thePid.':'.$this->typeVal.':'.$this->tscPID.':'.$p['imgpath'];
1408 }
1409 }
1410
1411 public function cleanList($str) {
1412 if (strstr($str,'*')) {
1413 $str = '*';
1414 } else {
1415 $str = implode(',',array_unique(t3lib_div::trimExplode(',',$str,1)));
1416 }
1417 return $str;
1418 }
1419
1420 function filterStyleEl($elValue,$matchList) {
1421 $matchParts = t3lib_div::trimExplode(',',$matchList,1);
1422 $styleParts = explode(';',$elValue);
1423 $nStyle=array();
1424 foreach ($styleParts as $k => $p) {
1425 $pp = t3lib_div::trimExplode(':',$p);
1426 if ($pp[0]&&$pp[1]) {
1427 foreach ($matchParts as $el) {
1428 $star=substr($el,-1)=='*';
1429 if (!strcmp($pp[0],$el) || ($star && t3lib_div::isFirstPartOfStr($pp[0],substr($el,0,-1)) )) {
1430 $nStyle[]=$pp[0].':'.$pp[1];
1431 } else unset($styleParts[$k]);
1432 }
1433 } else {
1434 unset($styleParts[$k]);
1435 }
1436 }
1437 return implode('; ',$nStyle);
1438 }
1439
1440 // Hook on lorem_ipsum extension to insert text into the RTE in wysiwyg mode
1441 function loremIpsumInsert($params) {
1442 return "
1443 if (typeof(lorem_ipsum) == 'function' && " . $params['element'] . ".tagName.toLowerCase() == 'textarea' ) lorem_ipsum(" . $params['element'] . ", lipsum_temp_strings[lipsum_temp_pointer]);
1444 ";
1445 }
1446 }
1447 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']) {
1448 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']);
1449 }
1450 ?>