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