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