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