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