Fixed bug #14662: htmlArea RTE: Should use t3lib_utility_Client::getBrowserInfo
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / class.tx_rtehtmlarea_base.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2004-2009 Kasper Skaarhoj (kasper@typo3.com)
6 * (c) 2004-2009 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->isFrontendEditActive() ? '' : $this->TCEform->backPath;
223 // Get the path to this extension:
224 $this->extHttpPath = $this->backPath . ($this->isFrontendEditActive() ? t3lib_extMgm::siteRelPath($this->ID) : 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 // Skin provided by some extension
422 if (substr($skinFilename,0,4) == 'EXT:') {
423 list($extKey,$local) = explode('/',substr($skinFilename,4),2);
424 $skinFilename='';
425 if (strcmp($extKey,'') && t3lib_extMgm::isLoaded($extKey) && strcmp($local,'')) {
426 $skinFilename = ($this->is_FE() ? t3lib_extMgm::siteRelPath($extKey) : t3lib_extMgm::extRelPath($extKey)) . $local;
427 $skinDir = ($this->is_FE() ? t3lib_extMgm::siteRelPath($extKey) : t3lib_extMgm::extRelPath($extKey)) . dirname($local);
428 }
429 } elseif (substr($skinFilename,0,1) != '/') {
430 $skinDir = dirname($skinFilename);
431 $skinFilename = $skinFilename;
432 } else {
433 $skinDir = substr($this->siteURL,0,-1) . dirname($skinFilename);
434 }
435 $this->editorCSS = $skinFilename;
436 // Editing area style sheet
437 $this->editedContentCSS = $skinDir . '/htmlarea-edited-content.css';
438 $this->addStyleSheet(
439 'rtehtmlarea-editing-area-skin',
440 $this->editedContentCSS
441 );
442 // Main skin
443 $this->addStyleSheet(
444 'rtehtmlarea-skin',
445 $this->editorCSS
446 );
447 // Additional icons from registered plugins
448 foreach ($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] as $pluginId) {
449 if (is_object($this->registeredPlugins[$pluginId])) {
450 $pathToSkin = $this->registeredPlugins[$pluginId]->getPathToSkin();
451 if ($pathToSkin) {
452 $key = $this->registeredPlugins[$pluginId]->getExtensionKey();
453 $this->addStyleSheet(
454 'rtehtmlarea-plugin-' . $pluginId . '-skin',
455 ($this->is_FE() ? t3lib_extMgm::siteRelPath($key) : $this->TCEform->backPath . t3lib_extMgm::extRelPath($key)) . $pathToSkin
456 );
457 }
458 }
459 }
460 }
461
462 /**
463 * Add style sheet file to document header
464 *
465 * @param string $key: some key identifying the style sheet
466 * @param string $href: uri to the style sheet file
467 * @param string $title: value for the title attribute of the link element
468 * @return string $relation: value for the rel attribute of the link element
469 * @return void
470 */
471 protected function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
472 // 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
473 if (is_object($this->TCEform->inline) && $this->TCEform->inline->isAjaxCall) {
474 $this->TCEform->additionalCode_pre[$key] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '" title="' . $title. '" />';
475 } else {
476 $this->TCEform->addStyleSheet($key, $href, $title, $relation);
477 }
478
479 }
480
481 /**
482 * Initialize toolbar configuration and enable registered plugins
483 *
484 * @return void
485 */
486 protected function initializeToolbarConfiguration() {
487
488 // Enable registred plugins
489 $this->enableRegisteredPlugins();
490
491 // Configure toolbar
492 $this->setToolbar();
493
494 // Check if some plugins need to be disabled
495 $this->setPlugins();
496
497 // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
498 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = $this->pluginEnabledArray;
499 if ($this->TCEform->RTEcounter > 1 && isset($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1]) && is_array($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])) {
500 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = array_unique(array_values(array_merge($this->pluginEnabledArray,$this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])));
501 }
502 }
503
504 /**
505 * Add registered plugins to the array of enabled plugins
506 *
507 */
508 function enableRegisteredPlugins() {
509 global $TYPO3_CONF_VARS;
510 // Traverse registered plugins
511 if (is_array($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'])) {
512 foreach($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'] as $pluginId => $pluginObjectConfiguration) {
513 $plugin = false;
514 if (is_array($pluginObjectConfiguration) && count($pluginObjectConfiguration)) {
515 $plugin = t3lib_div::getUserObj($pluginObjectConfiguration['objectReference']);
516 }
517 if (is_object($plugin)) {
518 if ($plugin->main($this)) {
519 $this->registeredPlugins[$pluginId] = $plugin;
520 // Override buttons from previously registered plugins
521 $pluginButtons = t3lib_div::trimExplode(',', $plugin->getPluginButtons(), 1);
522 foreach ($this->pluginButton as $previousPluginId => $buttonList) {
523 $this->pluginButton[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginButton[$previousPluginId], 1), $pluginButtons));
524 }
525 $this->pluginButton[$pluginId] = $plugin->getPluginButtons();
526 $pluginLabels = t3lib_div::trimExplode(',', $plugin->getPluginLabels(), 1);
527 foreach ($this->pluginLabel as $previousPluginId => $labelList) {
528 $this->pluginLabel[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginLabel[$previousPluginId], 1), $pluginLabels));
529 }
530 $this->pluginLabel[$pluginId] = $plugin->getPluginLabels();
531 $this->pluginEnabledArray[] = $pluginId;
532 }
533 }
534 }
535 }
536 // Process overrides
537 $hidePlugins = array();
538 foreach ($this->registeredPlugins as $pluginId => $plugin) {
539 if ($plugin->addsButtons() && !$this->pluginButton[$pluginId]) {
540 $hidePlugins[] = $pluginId;
541 }
542 }
543 $this->pluginEnabledArray = array_unique(array_diff($this->pluginEnabledArray, $hidePlugins));
544 }
545
546 /**
547 * Set the toolbar config (only in this PHP-Object, not in JS):
548 *
549 */
550
551 function setToolbar() {
552 global $BE_USER;
553
554 if ($this->client['browser'] == 'msie' || $this->client['browser'] == 'opera') {
555 $this->thisConfig['keepButtonGroupTogether'] = 0;
556 }
557
558 $this->defaultToolbarOrder = 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
559 bar, formattext, bold, strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code, definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span,
560 bar, fontstyle, space, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, line,
561 bar, left, center, right, justifyfull,
562 bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, lefttoright, righttoleft, language, showlanguagemarks,
563 bar, textcolor, bgcolor, textindicator,
564 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,
565 bar, chMode, inserttag, removeformat, bar, copy, cut, paste, bar, undo, redo, bar, showhelp, about, linebreak,
566 ' . ($this->thisConfig['hideTableOperationsInToolbar'] ? '': 'bar, toggleborders,') . ' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
567 columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
568 cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
569
570 // Additional buttons from registered plugins
571 foreach($this->registeredPlugins as $pluginId => $plugin) {
572 if ($this->isPluginEnabled($pluginId)) {
573 $this->defaultToolbarOrder = $plugin->addButtonsToToolbar();
574 }
575 }
576 $toolbarOrder = $this->thisConfig['toolbarOrder'] ? $this->thisConfig['toolbarOrder'] : $this->defaultToolbarOrder;
577
578 // Getting rid of undefined buttons
579 $this->toolbarOrderArray = array_intersect(t3lib_div::trimExplode(',', $toolbarOrder, 1), t3lib_div::trimExplode(',', $this->defaultToolbarOrder, 1));
580 $toolbarOrder = array_unique(array_values($this->toolbarOrderArray));
581
582 // Fetching specConf for field from backend
583 $pList = is_array($this->specConf['richtext']['parameters']) ? implode(',',$this->specConf['richtext']['parameters']) : '';
584 if ($pList != '*') { // If not all
585 $show = is_array($this->specConf['richtext']['parameters']) ? $this->specConf['richtext']['parameters'] : array();
586 if ($this->thisConfig['showButtons']) {
587 if (!t3lib_div::inList($this->thisConfig['showButtons'],'*')) {
588 $show = array_unique(array_merge($show,t3lib_div::trimExplode(',',$this->thisConfig['showButtons'],1)));
589 } else {
590 $show = array_unique(array_merge($show, $toolbarOrder));
591 }
592 }
593 if (is_array($this->thisConfig['showButtons.'])) {
594 foreach ($this->thisConfig['showButtons.'] as $buttonId => $value) {
595 if ($value) $show[] = $buttonId;
596 }
597 $show = array_unique($show);
598 }
599 } else {
600 $show = $toolbarOrder;
601 }
602
603 // Resticting to RTEkeyList for backend user
604 if(is_object($BE_USER)) {
605 $RTEkeyList = isset($BE_USER->userTS['options.']['RTEkeyList']) ? $BE_USER->userTS['options.']['RTEkeyList'] : '*';
606 if ($RTEkeyList != '*') { // If not all
607 $show = array_intersect($show, t3lib_div::trimExplode(',',$RTEkeyList,1));
608 }
609 }
610
611 // Hiding buttons of disabled plugins
612 $hideButtons = array('space', 'bar', 'linebreak');
613 foreach ($this->pluginButton as $pluginId => $buttonList) {
614 if (!$this->isPluginEnabled($pluginId)) {
615 $buttonArray = t3lib_div::trimExplode(',',$buttonList,1);
616 foreach ($buttonArray as $button) {
617 $hideButtons[] = $button;
618 }
619 }
620 }
621
622 // Hiding labels of disabled plugins
623 foreach ($this->pluginLabel as $pluginId => $label) {
624 if (!$this->isPluginEnabled($pluginId)) {
625 $hideButtons[] = $label;
626 }
627 }
628
629 // Hiding buttons
630 $show = array_diff($show, $this->conf_toolbar_hide, t3lib_div::trimExplode(',',$this->thisConfig['hideButtons'],1));
631
632 // Apply toolbar constraints from registered plugins
633 foreach ($this->registeredPlugins as $pluginId => $plugin) {
634 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "applyToolbarConstraints")) {
635 $show = $plugin->applyToolbarConstraints($show);
636 }
637 }
638 // Getting rid of the buttons for which we have no position
639 $show = array_intersect($show, $toolbarOrder);
640 $this->toolbar = $show;
641 }
642
643 /**
644 * Disable some plugins
645 *
646 */
647 function setPlugins() {
648
649 // Disabling a plugin that adds buttons if none of its buttons is in the toolbar
650 $hidePlugins = array();
651 foreach ($this->pluginButton as $pluginId => $buttonList) {
652 if ($this->registeredPlugins[$pluginId]->addsButtons()) {
653 $showPlugin = false;
654 $buttonArray = t3lib_div::trimExplode(',', $buttonList, 1);
655 foreach ($buttonArray as $button) {
656 if (in_array($button, $this->toolbar)) {
657 $showPlugin = true;
658 }
659 }
660 if (!$showPlugin) {
661 $hidePlugins[] = $pluginId;
662 }
663 }
664 }
665 $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
666
667 // Hiding labels of disabled plugins
668 $hideLabels = array();
669 foreach ($this->pluginLabel as $pluginId => $label) {
670 if (!$this->isPluginEnabled($pluginId)) {
671 $hideLabels[] = $label;
672 }
673 }
674 $this->toolbar = array_diff($this->toolbar, $hideLabels);
675
676 // Adding plugins declared as prerequisites by enabled plugins
677 $requiredPlugins = array();
678 foreach ($this->registeredPlugins as $pluginId => $plugin) {
679 if ($this->isPluginEnabled($pluginId)) {
680 $requiredPlugins = array_merge($requiredPlugins, t3lib_div::trimExplode(',', $plugin->getRequiredPlugins(), 1));
681 }
682 }
683 $requiredPlugins = array_unique($requiredPlugins);
684 foreach ($requiredPlugins as $pluginId) {
685 if (is_object($this->registeredPlugins[$pluginId]) && !$this->isPluginEnabled($pluginId)) {
686 $this->pluginEnabledArray[] = $pluginId;
687 }
688 }
689 $this->pluginEnabledArray = array_unique($this->pluginEnabledArray);
690
691 // Completing the toolbar conversion array for htmlArea
692 foreach ($this->registeredPlugins as $pluginId => $plugin) {
693 if ($this->isPluginEnabled($pluginId)) {
694 $this->convertToolbarForHtmlAreaArray = array_unique(array_merge($this->convertToolbarForHtmlAreaArray, $plugin->getConvertToolbarForHtmlAreaArray()));
695 }
696 }
697 }
698
699 /**
700 * Convert the TYPO3 names of buttons into the names for htmlArea RTE
701 *
702 * @param string buttonname (typo3-name)
703 * @return string buttonname (htmlarea-name)
704 */
705
706 function convertToolbarForHTMLArea($button) {
707 return $this->convertToolbarForHtmlAreaArray[$button];
708 }
709 /**
710 * Return the HTML code for loading the Javascript files
711 *
712 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
713 *
714 * @return string the html code for loading the Javascript Files
715 */
716 function loadJSfiles($RTEcounter) {
717 // Re-initialize the scripts array so that only the cumulative set of plugins of the last RTE on the page is used
718 $this->cumulativeScripts[$RTEcounter] = array();
719 $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea.js', 'htmlarea', 'js', '', TRUE);
720 if ($this->client['browser'] == 'msie') {
721 $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-ie.js', 'htmlarea-ie', 'js', '', TRUE);
722 } else {
723 $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-gecko.js', 'htmlarea-gecko', 'js', '', TRUE);
724 }
725 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
726 $extensionKey = is_object($this->registeredPlugins[$pluginId]) ? $this->registeredPlugins[$pluginId]->getExtensionKey() : $this->ID;
727 $this->writeTemporaryFile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $pluginId . '/' . strtolower(preg_replace('/([a-z])([A-Z])([a-z])/', "$1".'-'."$2"."$3", $pluginId)) . '.js', $pluginId, 'js', '', TRUE);
728 }
729 $this->buildJSMainLangFile($RTEcounter);
730 // Avoid re-initialization on AJax call when RTEarea object was already initialized
731 $loadJavascriptCode = '
732 <script type="text/javascript" src="' . $this->doConcatenate($RTEcounter) . '"></script>
733 <script type="text/javascript">
734 /*<![CDATA[*/
735 if (typeof(RTEarea) == "undefined") {
736 RTEarea = new Object();
737 RTEarea[0] = new Object();
738 RTEarea[0].version = "' . $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['version'] . '";
739 RTEarea[0].editorUrl = "' . $this->extHttpPath . 'htmlarea/";
740 RTEarea[0].editorCSS = "' . t3lib_div::createVersionNumberedFilename($this->editorCSS) . '";
741 RTEarea[0].editorSkin = "' . dirname($this->editorCSS) . '/";
742 RTEarea[0].editedContentCSS = "' . t3lib_div::createVersionNumberedFilename($this->editedContentCSS) . '";
743 RTEarea[0].hostUrl = "' . $this->hostURL . '";
744 RTEarea[0].enableDebugMode = ' . ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableDebugMode'] ? 'true' : 'false') . ';
745 RTEarea.init = function() {
746 if (typeof(HTMLArea) == "undefined" || !Ext.isReady) {
747 window.setTimeout("RTEarea.init();", 40);
748 } else {
749 Ext.QuickTips.init();
750 HTMLArea.init();
751 }
752 };
753 RTEarea.initEditor = function(editorNumber) {
754 if (typeof(HTMLArea) == "undefined") {
755 RTEarea.initEditor.defer(40, null, [editorNumber]);
756 } else {
757 HTMLArea.initEditor(editorNumber);
758 }
759 };
760 }
761 /*]]>*/
762 </script>';
763 return $loadJavascriptCode;
764 }
765
766 /**
767 * Return the Javascript code for initializing the RTE
768 *
769 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
770 *
771 * @return string the Javascript code for initializing the RTE
772 */
773 function loadJScode($RTEcounter) {
774 return (!$this->is_FE() ? '' : '
775 ' . '/*<![CDATA[*/') . '
776 RTEarea.init();' . (!$this->is_FE() ? '' : '
777 /*]]>*/
778 ');
779 }
780
781 /**
782 * Return the Javascript code for configuring the RTE
783 *
784 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
785 * @param string $table: The table that includes this RTE (optional, necessary for IRRE).
786 * @param string $uid: The uid of that table that includes this RTE (optional, necessary for IRRE).
787 * @param string $field: The field of that record that includes this RTE (optional).
788 *
789 * @return string the Javascript code for configuring the RTE
790 */
791 function registerRTEinJS($RTEcounter, $table='', $uid='', $field='', $textAreaId = '') {
792
793 $configureRTEInJavascriptString = (!$this->is_FE() ? '' : '
794 ' . '/*<![CDATA[*/') . '
795 if (typeof(configureEditorInstance) == "undefined") {
796 configureEditorInstance = new Object();
797 }
798 configureEditorInstance["' . $textAreaId . '"] = function() {
799 if (typeof(RTEarea) == "undefined" || typeof(HTMLArea) == "undefined") {
800 window.setTimeout("configureEditorInstance[\'' . $textAreaId . '\']();", 40);
801 } else {
802 editornumber = "' . $textAreaId . '";
803 RTEarea[editornumber] = new Object();
804 RTEarea[editornumber].RTEtsConfigParams = "&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams()) . '";
805 RTEarea[editornumber].number = editornumber;
806 RTEarea[editornumber].deleted = false;
807 RTEarea[editornumber].textAreaId = "' . $textAreaId . '";
808 RTEarea[editornumber].id = "RTEarea" + editornumber;
809 RTEarea[editornumber].RTEWidthOverride = "' . trim($this->thisConfig['RTEWidthOverride']) . '";
810 RTEarea[editornumber].RTEHeightOverride = "' . trim($this->thisConfig['RTEHeightOverride']) . '";
811 RTEarea[editornumber].fullScreen = ' . ($this->fullScreen ? 'true' : 'false') . ';
812 RTEarea[editornumber].showStatusBar = ' . (trim($this->thisConfig['showStatusBar'])?'true':'false') . ';
813 RTEarea[editornumber].enableWordClean = ' . (trim($this->thisConfig['enableWordClean'])?'true':'false') . ';
814 RTEarea[editornumber].htmlRemoveComments = ' . (trim($this->thisConfig['removeComments'])?'true':'false') . ';
815 RTEarea[editornumber].disableEnterParagraphs = ' . (trim($this->thisConfig['disableEnterParagraphs'])?'true':'false') . ';
816 RTEarea[editornumber].disableObjectResizing = ' . (trim($this->thisConfig['disableObjectResizing'])?'true':'false') . ';
817 RTEarea[editornumber].removeTrailingBR = ' . (trim($this->thisConfig['removeTrailingBR'])?'true':'false') . ';
818 RTEarea[editornumber].useCSS = ' . (trim($this->thisConfig['useCSS'])?'true':'false') . ';
819 RTEarea[editornumber].keepButtonGroupTogether = ' . (trim($this->thisConfig['keepButtonGroupTogether'])?'true':'false') . ';
820 RTEarea[editornumber].disablePCexamples = ' . (trim($this->thisConfig['disablePCexamples'])?'true':'false') . ';
821 RTEarea[editornumber].showTagFreeClasses = ' . (trim($this->thisConfig['showTagFreeClasses'])?'true':'false') . ';
822 RTEarea[editornumber].useHTTPS = ' . ((trim(stristr($this->siteURL, 'https')) || $this->thisConfig['forceHTTPS'])?'true':'false') . ';
823 RTEarea[editornumber].tceformsNested = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(true) : '[]') . ';
824 RTEarea[editornumber].dialogueWindows = new Object();
825 RTEarea[editornumber].dialogueWindows.defaultPositionFromTop = ' . (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromTop'])? intval($this->thisConfig['dialogueWindows.']['defaultPositionFromTop']) : '100') . ';
826 RTEarea[editornumber].dialogueWindows.defaultPositionFromLeft = ' . (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'])? intval($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft']) : '100') . ';
827 RTEarea[editornumber].dialogueWindows.doNotResize = ' . (trim($this->thisConfig['dialogueWindows.']['doNotResize'])?'true':'false') . ';
828 RTEarea[editornumber].dialogueWindows.doNotCenter = ' . (trim($this->thisConfig['dialogueWindows.']['doNotCenter'])?'true':'false') . ';';
829
830 // The following properties apply only to the backend
831 if (!$this->is_FE()) {
832 $configureRTEInJavascriptString .= '
833 RTEarea[editornumber].sys_language_content = "' . $this->contentLanguageUid . '";
834 RTEarea[editornumber].typo3ContentLanguage = "' . $this->contentTypo3Language . '";
835 RTEarea[editornumber].typo3ContentCharset = "' . $this->contentCharset . '";
836 RTEarea[editornumber].userUid = "' . $this->userUid . '";';
837 }
838
839 // Setting the plugin flags
840 $configureRTEInJavascriptString .= '
841 RTEarea[editornumber].plugin = new Object();
842 RTEarea[editornumber].pathToPluginDirectory = new Object();';
843 foreach ($this->pluginEnabledArray as $pluginId) {
844 $configureRTEInJavascriptString .= '
845 RTEarea[editornumber].plugin.'.$pluginId.' = true;';
846 if (is_object($this->registeredPlugins[$pluginId])) {
847 $pathToPluginDirectory = $this->registeredPlugins[$pluginId]->getPathToPluginDirectory();
848 if ($pathToPluginDirectory) {
849 $configureRTEInJavascriptString .= '
850 RTEarea[editornumber].pathToPluginDirectory.'.$pluginId.' = "' . $pathToPluginDirectory . '";';
851 }
852 }
853 }
854
855 // Setting the buttons configuration
856 $configureRTEInJavascriptString .= '
857 RTEarea[editornumber].buttons = new Object();';
858 if (is_array($this->thisConfig['buttons.'])) {
859 foreach ($this->thisConfig['buttons.'] as $buttonIndex => $conf) {
860 $button = substr($buttonIndex, 0, -1);
861 if (in_array($button,$this->toolbar)) {
862 $configureRTEInJavascriptString .= '
863 RTEarea[editornumber].buttons.'.$button.' = ' . $this->buildNestedJSArray($conf) . ';';
864 }
865 }
866 }
867
868 // Setting the list of tags to be removed if specified in the RTE config
869 if (trim($this->thisConfig['removeTags'])) {
870 $configureRTEInJavascriptString .= '
871 RTEarea[editornumber].htmlRemoveTags = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTags'], 1)) . ')$/i;';
872 }
873
874 // Setting the list of tags to be removed with their contents if specified in the RTE config
875 if (trim($this->thisConfig['removeTagsAndContents'])) {
876 $configureRTEInJavascriptString .= '
877 RTEarea[editornumber].htmlRemoveTagsAndContents = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTagsAndContents'], 1)) . ')$/i;';
878 }
879 // Process default style configuration
880 $configureRTEInJavascriptString .= '
881 RTEarea[editornumber].defaultPageStyle = "' . $this->writeTemporaryFile('', 'defaultPageStyle', 'css', $this->buildStyleSheet()) . '";';
882 // Setting the pageStyle
883 $filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/res/contentcss/default.css';
884 $configureRTEInJavascriptString .= '
885 RTEarea[editornumber].pageStyle = "' . t3lib_div::createVersionNumberedFilename($this->getFullFileName($filename)) .'";';
886 // Process classes configuration
887 $classesConfigurationRequired = false;
888 foreach ($this->registeredPlugins as $pluginId => $plugin) {
889 if ($this->isPluginEnabled($pluginId)) {
890 $classesConfigurationRequired = $classesConfigurationRequired || $plugin->requiresClassesConfiguration();
891 }
892 }
893 if ($classesConfigurationRequired) {
894 $configureRTEInJavascriptString .= $this->buildJSClassesConfig($RTEcounter);
895 }
896 // Add Javascript configuration for registered plugins
897 foreach ($this->registeredPlugins as $pluginId => $plugin) {
898 if ($this->isPluginEnabled($pluginId)) {
899 $configureRTEInJavascriptString .= $plugin->buildJavascriptConfiguration('editornumber');
900 }
901 }
902 // Avoid premature reference to HTMLArea when being initially loaded by IRRE Ajax call
903 $configureRTEInJavascriptString .= '
904 RTEarea[editornumber].toolbar = ' . $this->getJSToolbarArray() . ';
905 RTEarea[editornumber].convertButtonId = ' . json_encode(array_flip($this->convertToolbarForHtmlAreaArray)) . ';
906 RTEarea.initEditor(editornumber);
907 }
908 };
909 configureEditorInstance["' . $textAreaId . '"]();'. (!$this->is_FE() ? '' : '
910 /*]]>*/');
911 return $configureRTEInJavascriptString;
912 }
913
914 /**
915 * Return true, if the plugin can be loaded
916 *
917 * @param string $pluginId: The identification string of the plugin
918 *
919 * @return boolean true if the plugin can be loaded
920 */
921
922 function isPluginEnabled($pluginId) {
923 return in_array($pluginId, $this->pluginEnabledArray);
924 }
925
926 /**
927 * Build the default content style sheet
928 *
929 * @return string Style sheet
930 */
931 function buildStyleSheet() {
932
933 if (!trim($this->thisConfig['ignoreMainStyleOverride'])) {
934 $mainStyle_font = $this->thisConfig['mainStyle_font'] ? $this->thisConfig['mainStyle_font']: 'Verdana,sans-serif';
935
936 $mainElements = array();
937 $mainElements['P'] = $this->thisConfig['mainStyleOverride_add.']['P'];
938 $elList = explode(',','H1,H2,H3,H4,H5,H6,PRE');
939 foreach ($elList as $elListName) {
940 if ($this->thisConfig['mainStyleOverride_add.'][$elListName]) {
941 $mainElements[$elListName] = $this->thisConfig['mainStyleOverride_add.'][$elListName];
942 }
943 }
944
945 $addElementCode = '';
946 foreach ($mainElements as $elListName => $elValue) {
947 $addElementCode .= strToLower($elListName) . ' {' . $elValue . '}' . LF;
948 }
949
950 $stylesheet = $this->thisConfig['mainStyleOverride'] ? $this->thisConfig['mainStyleOverride'] : LF .
951 'body.htmlarea-content-body { font-family: ' . $mainStyle_font .
952 '; font-size: '.($this->thisConfig['mainStyle_size'] ? $this->thisConfig['mainStyle_size'] : '12px') .
953 '; color: '.($this->thisConfig['mainStyle_color']?$this->thisConfig['mainStyle_color'] : 'black') .
954 '; background-color: '.($this->thisConfig['mainStyle_bgcolor'] ? $this->thisConfig['mainStyle_bgcolor'] : 'white') .
955 ';'.$this->thisConfig['mainStyleOverride_add.']['BODY'].'}' . LF .
956 'td { ' . $this->thisConfig['mainStyleOverride_add.']['TD'].'}' . LF .
957 'div { ' . $this->thisConfig['mainStyleOverride_add.']['DIV'].'}' . LF .
958 'pre { ' . $this->thisConfig['mainStyleOverride_add.']['PRE'].'}' . LF .
959 'ol { ' . $this->thisConfig['mainStyleOverride_add.']['OL'].'}' . LF .
960 'ul { ' . $this->thisConfig['mainStyleOverride_add.']['UL'].'}' . LF .
961 'blockquote { ' . $this->thisConfig['mainStyleOverride_add.']['BLOCKQUOTE'].'}' . LF .
962 $addElementCode;
963
964 if (is_array($this->thisConfig['inlineStyle.'])) {
965 $stylesheet .= LF . implode(LF, $this->thisConfig['inlineStyle.']) . LF;
966 }
967 } else {
968 $stylesheet = '/* mainStyleOverride and inlineStyle properties ignored. */';
969 }
970 return $stylesheet;
971 }
972
973 /**
974 * Return Javascript configuration of classes
975 *
976 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
977 *
978 * @return string Javascript configuration of classes
979 */
980 function buildJSClassesConfig($RTEcounter) {
981 // Build JS array of lists of classes
982 $classesTagList = 'classesCharacter, classesParagraph, classesImage, classesTable, classesLinks, classesTD';
983 $classesTagConvert = array( 'classesCharacter' => 'span', 'classesParagraph' => 'div', 'classesImage' => 'img', 'classesTable' => 'table', 'classesLinks' => 'a', 'classesTD' => 'td');
984 $classesTagArray = t3lib_div::trimExplode(',' , $classesTagList);
985 $configureRTEInJavascriptString = '
986 RTEarea[editornumber].classesTag = new Object();';
987 foreach ($classesTagArray as $classesTagName) {
988 $HTMLAreaJSClasses = ($this->thisConfig[$classesTagName])?('"' . $this->cleanList($this->thisConfig[$classesTagName]) . '";'):'null;';
989 $configureRTEInJavascriptString .= '
990 RTEarea[editornumber].classesTag.'. $classesTagConvert[$classesTagName] .' = '. $HTMLAreaJSClasses;
991 }
992 // Include JS arrays of configured classes
993 $configureRTEInJavascriptString .= '
994 RTEarea[editornumber].classesUrl = "' . $this->writeTemporaryFile('', 'classes_'.$LANG->lang, 'js', $this->buildJSClassesArray()) . '";';
995 return $configureRTEInJavascriptString;
996 }
997
998 /**
999 * Return JS arrays of classes configuration
1000 *
1001 * @return string JS classes arrays
1002 */
1003 function buildJSClassesArray() {
1004 if ($this->is_FE()) {
1005 $RTEProperties = $this->RTEsetup;
1006 } else {
1007 $RTEProperties = $this->RTEsetup['properties'];
1008 }
1009 $classesArray = array('labels' => array(), 'values' => array(), 'noShow' => array(), 'alternating' => array(), 'counting' => array(), 'XOR' => array());
1010 $JSClassesArray = '';
1011 // Scanning the list of classes if specified in the RTE config
1012 if (is_array($RTEProperties['classes.'])) {
1013 foreach ($RTEProperties['classes.'] as $className => $conf) {
1014 $className = rtrim($className, '.');
1015 $classesArray['labels'][$className] = $this->getPageConfigLabel($conf['name'], FALSE);
1016 $classesArray['values'][$className] = str_replace('\\\'', '\'', $conf['value']);
1017 if (isset($conf['noShow'])) {
1018 $classesArray['noShow'][$className] = $conf['noShow'];
1019 }
1020 if (is_array($conf['alternating.'])) {
1021 $classesArray['alternating'][$className] = $conf['alternating.'];
1022 }
1023 if (is_array($conf['counting.'])) {
1024 $classesArray['counting'][$className] = $conf['counting.'];
1025 }
1026 }
1027 }
1028 // Scanning the list of sets of mutually exclusives classes if specified in the RTE config
1029 if (is_array($RTEProperties['mutuallyExclusiveClasses.'])) {
1030 foreach ($RTEProperties['mutuallyExclusiveClasses.'] as $listName => $conf) {
1031 $classSet = t3lib_div::trimExplode(',', $conf, 1);
1032 $classList = implode(',', $classSet);
1033 foreach ($classSet as $className) {
1034 $classesArray['XOR'][$className] = '/^(' . implode('|', t3lib_div::trimExplode(',', t3lib_div::rmFromList($className, $classList), 1)) . ')$/';
1035 }
1036 }
1037 }
1038 foreach ($classesArray as $key => $subArray) {
1039 $JSClassesArray .= 'HTMLArea.classes' . ucfirst($key) . ' = ' . $this->buildNestedJSArray($subArray) . ';' . LF;
1040 }
1041 return $JSClassesArray;
1042 }
1043
1044 /**
1045 * Translate Page TS Config array in JS nested array definition
1046 * Replace 0 values with false
1047 * Unquote regular expression values
1048 * Replace empty arrays with empty objects
1049 *
1050 * @param array $conf: Page TSConfig configuration array
1051 *
1052 * @return string nested JS array definition
1053 */
1054 function buildNestedJSArray($conf) {
1055 $convertedConf = t3lib_div::removeDotsFromTS($conf);
1056 if ($this->is_FE()) {
1057 $GLOBALS['TSFE']->csConvObj->convArray($convertedConf, ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] ? $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] : 'iso-8859-1'), 'utf-8');
1058 } else {
1059 $GLOBALS['LANG']->csConvObj->convArray($convertedConf, $GLOBALS['LANG']->charSet, 'utf-8');
1060 }
1061 return str_replace(array(':"0"', ':"\/^(', ')$\/i"', ':"\/^(', ')$\/"', '[]'), array(':false', ':/^(', ')$/i', ':/^(', ')$/', '{}'), json_encode($convertedConf));
1062 }
1063
1064 /**
1065 * Return a Javascript localization array for htmlArea RTE
1066 *
1067 * @return string Javascript localization array
1068 */
1069 function buildJSMainLangArray() {
1070 $JSLanguageArray = 'HTMLArea.I18N = new Object();' . LF;
1071 $labelsArray = array('tooltips' => array(), 'msg' => array(), 'dialogs' => array());
1072 foreach ($labelsArray as $labels => $subArray) {
1073 $LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $this->ID . '/htmlarea/locallang_' . $labels . '.xml', $this->language, 'utf-8');
1074 if (!empty($LOCAL_LANG[$this->language])) {
1075 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'], $LOCAL_LANG[$this->language]);
1076 } else {
1077 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1078 }
1079 $labelsArray[$labels] = $LOCAL_LANG[$this->language];
1080 }
1081 $JSLanguageArray .= 'HTMLArea.I18N = ' . json_encode($labelsArray) . ';' . LF;
1082 return $JSLanguageArray;
1083 }
1084
1085 /**
1086 * Writes contents in a file in typo3temp/rtehtmlarea directory and returns the file name
1087 *
1088 * @param string $sourceFileName: The name of the file from which the contents should be extracted
1089 * @param string $label: A label to insert at the beginning of the name of the file
1090 * @param string $fileExtension: The file extension of the file, defaulting to 'js'
1091 * @param string $contents: The contents to write into the file if no $sourceFileName is provided
1092 *
1093 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1094 */
1095 public function writeTemporaryFile($sourceFileName='', $label, $fileExtension='js', $contents='', $concatenate = FALSE) {
1096 global $TYPO3_CONF_VARS;
1097
1098 if ($sourceFileName) {
1099 $output = '';
1100 $source = t3lib_div::getFileAbsFileName($sourceFileName);
1101 $output = file_get_contents($source);
1102 } else {
1103 $output = $contents;
1104 }
1105 $compress = $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] && ($fileExtension == 'js') && ($output != '');
1106 $relativeFilename = 'typo3temp/' . $this->ID . '/' . str_replace('-','_',$label) . '_' . t3lib_div::shortMD5(($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . ($sourceFileName ? $sourceFileName : $output)), 20) . ($compress ? '_compressed' : '') . '.' . $fileExtension;
1107 $destination = PATH_site . $relativeFilename;
1108 if(!file_exists($destination)) {
1109 $compressedJavaScript = '';
1110 if ($compress) {
1111 $compressedJavaScript = t3lib_div::minifyJavaScript($output);
1112 }
1113 $failure = t3lib_div::writeFileToTypo3tempDir($destination, $compressedJavaScript?$compressedJavaScript:$output);
1114 if ($failure) {
1115 die($failure);
1116 }
1117 }
1118 if ($concatenate) {
1119 $this->cumulativeScripts[$this->TCEform->RTEcounter][] = $destination;
1120 }
1121 if ($this->is_FE()) {
1122 return ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . t3lib_div::createVersionNumberedFilename($relativeFilename);
1123 } else {
1124 $filename = t3lib_div::createVersionNumberedFilename('../' . $this->backPath . $relativeFilename);
1125 if ($this->isFrontendEditActive()) {
1126 $filename = preg_replace('/^..\//', '', $filename);
1127 }
1128 return $filename;
1129 }
1130 }
1131 /**
1132 * Concatenates all accumulated scripts in a file in typo3temp/rtehtmlarea directory and returns the file name
1133 *
1134 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1135 *
1136 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1137 */
1138 protected function doConcatenate($RTEcounter) {
1139 $fileExtension = 'js';
1140 $compress = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts'];
1141 $token = implode('|', $this->cumulativeScripts[$RTEcounter]);
1142 $relativeFilename = 'typo3temp/' . $this->ID . '/' . 'htmlarea_cumulative' . '_' . t3lib_div::shortMD5(($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . $token ), 20) . ($compress ? '_compressed' : '') . '.' . $fileExtension;
1143 $destination = PATH_site . $relativeFilename;
1144 if (!file_exists($destination)) {
1145 foreach ($this->cumulativeScripts[$RTEcounter] as $fileName) {
1146 $contents = file_get_contents($fileName);
1147 if (!file_exists($destination)) {
1148 $failure = t3lib_div::writeFileToTypo3tempDir($destination, $contents);
1149 if ($failure) {
1150 die($failure);
1151 }
1152 } else {
1153 $success = file_put_contents($destination, $contents, FILE_APPEND);
1154 if (!$success) {
1155 die('Could not append script' + $fileName);
1156 }
1157 }
1158 }
1159 }
1160 if ($this->is_FE()) {
1161 $filename = ($GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . t3lib_div::createVersionNumberedFilename($relativeFilename);
1162 } else {
1163 if ($compress) {
1164 $compressor = t3lib_div::makeInstance('t3lib_Compressor');
1165 $filename = $compressor->compressJsFile('../' . $this->backPath . $relativeFilename);
1166 } else {
1167 $filename = t3lib_div::createVersionNumberedFilename('../' . $this->backPath . $relativeFilename);
1168 }
1169 if ($this->isFrontendEditActive()) {
1170 $filename = preg_replace('/^..\//', '', $filename);
1171 }
1172 }
1173 return $filename;
1174 }
1175
1176 /**
1177 * Return a file name containing the main JS language array for HTMLArea
1178 *
1179 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1180 *
1181 * @return string filename
1182 */
1183 function buildJSMainLangFile($RTEcounter) {
1184 $contents = $this->buildJSMainLangArray() . LF;
1185 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
1186 $contents .= $this->buildJSLangArray($pluginId) . LF;
1187 }
1188 return $this->writeTemporaryFile('', $this->language.'_'.$this->OutputCharset, 'js', $contents, TRUE);
1189 }
1190
1191 /**
1192 * Return a Javascript localization array for the plugin
1193 *
1194 * @param string $plugin: identification string of the plugin
1195 *
1196 * @return string Javascript localization array
1197 */
1198
1199 function buildJSLangArray($plugin) {
1200 $LOCAL_LANG = FALSE;
1201 $extensionKey = is_object($this->registeredPlugins[$plugin]) ? $this->registeredPlugins[$plugin]->getExtensionKey() : $this->ID;
1202 $LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $plugin . '/locallang.xml', $this->language, 'utf-8', 1);
1203 $linebreak = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['enableCompressedScripts'] ? '' : LF;
1204 $JSLanguageArray = 'HTMLArea.I18N["' . $plugin . '"] = new Object();' . $linebreak;
1205 if (is_array($LOCAL_LANG)) {
1206 if (!empty($LOCAL_LANG[$this->language])) {
1207 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'],$LOCAL_LANG[$this->language]);
1208 } else {
1209 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1210 }
1211 $JSLanguageArray .= 'HTMLArea.I18N["' . $plugin . '"] = ' . json_encode($LOCAL_LANG[$this->language]) . ';'. LF;
1212 }
1213 return $JSLanguageArray;
1214 }
1215
1216 /**
1217 * Return the JS code of the toolbar configuration for the HTMLArea editor
1218 *
1219 * @return string the JS code as nested JS arrays
1220 */
1221 protected function getJSToolbarArray() {
1222 // The toolbar array
1223 $toolbar = array();
1224 // The current row; a "linebreak" ends the current row
1225 $row = array();
1226 // The current group; each group is between "bar"s; a "linebreak" ends the current group
1227 $group = array();
1228 // Process each toolbar item in the toolbar order list
1229 foreach ($this->toolbarOrderArray as $item) {
1230 switch ($item) {
1231 case 'linebreak':
1232 // Add row to toolbar if not empty
1233 if (!empty($group)) {
1234 $row[] = $group;
1235 $group = array();
1236 }
1237 if (!empty($row)) {
1238 $toolbar[] = $row;
1239 $row = array();
1240 }
1241 break;
1242 case 'bar':
1243 // Add group to row if not empty
1244 if (!empty($group)) {
1245 $row[] = $group;
1246 $group = array();
1247 }
1248 break;
1249 case 'space':
1250 if (end($group) != $this->convertToolbarForHTMLArea($item)) {
1251 $group[] = $this->convertToolbarForHTMLArea($item);
1252 }
1253 break;
1254 default:
1255 if (in_array($item, $this->toolbar)) {
1256 // Add the item to the group
1257 $convertedItem = $this->convertToolbarForHTMLArea($item);
1258 if ($convertedItem) {
1259 $group[] = $convertedItem;
1260 }
1261 }
1262 break;
1263 }
1264 }
1265 // Add the last group and last line, if not empty
1266 if (!empty($group)) {
1267 $row[] = $group;
1268 }
1269 if (!empty($row)) {
1270 $toolbar[] = $row;
1271 }
1272 return json_encode($toolbar);
1273 }
1274
1275 public function getLLContent($string) {
1276 global $LANG;
1277
1278 $BE_lang = $LANG->lang;
1279 $BE_charSet = $LANG->charSet;
1280 $LANG->lang = $this->contentTypo3Language;
1281 $LANG->charSet = $this->contentCharset;
1282 $LLString = $LANG->JScharCode($LANG->sL($string));
1283 $LANG->lang = $BE_lang;
1284 $LANG->charSet = $BE_charSet;
1285 return $LLString;
1286 }
1287
1288 public function getPageConfigLabel($string,$JScharCode=1) {
1289 global $LANG, $TSFE, $TYPO3_CONF_VARS;
1290
1291 if ($this->is_FE()) {
1292 if (strcmp(substr($string,0,4),'LLL:') && $TYPO3_CONF_VARS['BE']['forceCharset']) {
1293 // A pure string coming from Page TSConfig must be in forceCharset, otherwise we just don't know..
1294 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $TYPO3_CONF_VARS['BE']['forceCharset'], $this->OutputCharset);
1295 } else {
1296 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $this->charset, $this->OutputCharset);
1297 }
1298 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1299 $label = $JScharCode ? $this->feJScharCode($label) : $label;
1300 } else {
1301 if (strcmp(substr($string,0,4),'LLL:')) {
1302 $label = $string;
1303 } else {
1304 $label = $LANG->sL(trim($string));
1305 }
1306 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1307 $label = $JScharCode ? $LANG->JScharCode($label): $label;
1308 }
1309 return $label;
1310 }
1311
1312 function feJScharCode($str) {
1313 global $TSFE;
1314 // Convert string to UTF-8:
1315 if ($this->OutputCharset != 'utf-8') $str = $TSFE->csConvObj->utf8_encode($str,$this->OutputCharset);
1316 // Convert the UTF-8 string into a array of char numbers:
1317 $nArr = $TSFE->csConvObj->utf8_to_numberarray($str);
1318 return 'String.fromCharCode('.implode(',',$nArr).')';
1319 }
1320
1321 public function getFullFileName($filename) {
1322 if (substr($filename,0,4)=='EXT:') { // extension
1323 list($extKey,$local) = explode('/',substr($filename,4),2);
1324 $newFilename = '';
1325 if (strcmp($extKey,'') && t3lib_extMgm::isLoaded($extKey) && strcmp($local,'')) {
1326 $newFilename = ($this->is_FE() ? t3lib_extMgm::siteRelPath($extKey) : $this->backPath . t3lib_extMgm::extRelPath($extKey)) . $local;
1327 }
1328 } elseif (substr($filename,0,1) != '/') {
1329 $newFilename = ($this->is_FE() ? '' : ($this->isFrontendEditActive() ? '' : '../') . $this->backPath) . $filename;
1330 } else {
1331 $newFilename = ($this->is_FE() ? '' : ($this->isFrontendEditActive() ? '' : '../') . $this->backPath) . substr($filename, 1);
1332 }
1333 return $newFilename;
1334 }
1335
1336 /**
1337 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1338 * This is for submit function of the form.
1339 *
1340 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1341 * @param string $formName: the name of the form
1342 * @param string $textareaId: the id of the textarea
1343 *
1344 * @return string Javascript code
1345 */
1346 function setSaveRTE($RTEcounter, $formName, $textareaId) {
1347 return 'if (RTEarea["' . $textareaId . '"]) { document.' . $formName . '["' . $textareaId . '"].value = RTEarea["' . $textareaId . '"].editor.getHTML(); } else { OK = 0; };';
1348 }
1349
1350 /**
1351 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1352 * This is for submit function of the form.
1353 *
1354 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1355 * @param string $formName: the name of the form
1356 * @param string $textareaId: the id of the textarea
1357 *
1358 * @return string Javascript code
1359 */
1360 function setDeleteRTE($RTEcounter, $formName, $textareaId) {
1361 return 'if (RTEarea["' . $textareaId . '"]) { RTEarea["' . $textareaId . '"].deleted = true;}';
1362 }
1363
1364 /**
1365 * Return true if we are in the FE, but not in the FE editing feature of BE.
1366 *
1367 * @return boolean
1368 */
1369
1370 function is_FE() {
1371 return is_object($GLOBALS['TSFE']) && !$this->isFrontendEditActive();
1372 }
1373
1374 /**
1375 * Checks whether frontend editing is active.
1376 *
1377 * @return boolean
1378 */
1379 public function isFrontendEditActive() {
1380 return is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->beUserLogin && ($GLOBALS['BE_USER']->frontendEdit instanceof t3lib_frontendedit);
1381 }
1382 /**
1383 * Client Browser Information
1384 *
1385 * @param string $userAgent: The useragent string, t3lib_div::getIndpEnv('HTTP_USER_AGENT')
1386 * @return array Contains keys "useragent", "browser", "version", "system"
1387 * where "browser" is limited to the engines
1388 * and where "version" is a floating number
1389 */
1390 function clientInfo ($userAgent='') {
1391 if (!$userAgent) {
1392 $userAgent = t3lib_div::getIndpEnv('HTTP_USER_AGENT');
1393 }
1394 $browserInfo = t3lib_utility_Client::getBrowserInfo($userAgent);
1395 // Known engines: order is not irrelevant.
1396 $knownEngines = array('opera', 'msie', 'gecko', 'webkit');
1397 if (is_array($browserInfo['all'])) {
1398 foreach ($knownEngines as $engine) {
1399 if ($browserInfo['all'][$engine]) {
1400 $browserInfo['browser'] = $engine;
1401 switch ($engine) {
1402 case 'gecko':
1403 // We need the Gecko revision number as version of the Gecko engine, not the build date
1404 $tmp = strstr($browserInfo['useragent'], 'rv:');
1405 $browserInfo['version'] = t3lib_utility_Client::getVersion(substr($tmp, 3));
1406 break;
1407 default:
1408 $browserInfo['version'] = t3lib_utility_Client::getVersion($browserInfo['all'][$engine]);
1409 break;
1410 }
1411 break;
1412 }
1413 }
1414 }
1415 return $browserInfo;
1416 }
1417 /***************************
1418 *
1419 * OTHER FUNCTIONS: (from Classic RTE)
1420 *
1421 ***************************/
1422 /**
1423 * @return [type] ...
1424 * @desc
1425 */
1426
1427 function RTEtsConfigParams() {
1428 if($this->is_FE()) {
1429 return '';
1430 } else {
1431 $p = t3lib_BEfunc::getSpecConfParametersFromArray($this->specConf['rte_transform']['parameters']);
1432 return $this->elementParts[0].':'.$this->elementParts[1].':'.$this->elementParts[2].':'.$this->thePid.':'.$this->typeVal.':'.$this->tscPID.':'.$p['imgpath'];
1433 }
1434 }
1435
1436 public function cleanList($str) {
1437 if (strstr($str,'*')) {
1438 $str = '*';
1439 } else {
1440 $str = implode(',',array_unique(t3lib_div::trimExplode(',',$str,1)));
1441 }
1442 return $str;
1443 }
1444
1445 function filterStyleEl($elValue,$matchList) {
1446 $matchParts = t3lib_div::trimExplode(',',$matchList,1);
1447 $styleParts = explode(';',$elValue);
1448 $nStyle=array();
1449 foreach ($styleParts as $k => $p) {
1450 $pp = t3lib_div::trimExplode(':',$p);
1451 if ($pp[0]&&$pp[1]) {
1452 foreach ($matchParts as $el) {
1453 $star=substr($el,-1)=='*';
1454 if (!strcmp($pp[0],$el) || ($star && t3lib_div::isFirstPartOfStr($pp[0],substr($el,0,-1)) )) {
1455 $nStyle[]=$pp[0].':'.$pp[1];
1456 } else unset($styleParts[$k]);
1457 }
1458 } else {
1459 unset($styleParts[$k]);
1460 }
1461 }
1462 return implode('; ',$nStyle);
1463 }
1464
1465 // Hook on lorem_ipsum extension to insert text into the RTE in wysiwyg mode
1466 function loremIpsumInsert($params) {
1467 return "
1468 if (typeof(lorem_ipsum) == 'function' && " . $params['element'] . ".tagName.toLowerCase() == 'textarea' ) lorem_ipsum(" . $params['element'] . ", lipsum_temp_strings[lipsum_temp_pointer]);
1469 ";
1470 }
1471 }
1472 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']) {
1473 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']);
1474 }
1475 ?>