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