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