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