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