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