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