* Feature #3633: Individual height of inline RTE. Thanks to Ralf Hettinger.
[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 var $language;
142 public $contentTypo3Language;
143 public $contentISOLanguage;
144 public $contentCharset;
145 var $BECharset;
146 var $OutputCharset;
147 var $editorCSS;
148 var $specConf;
149 var $toolbar = array(); // Save the buttons for the toolbar
150 var $toolbar_level_size; // The size for each level in the toolbar:
151 var $toolbarOrderArray = array();
152 protected $pluginEnabledArray = array(); // Array of plugin id's enabled in the current RTE editing area
153 protected $pluginEnabledCumulativeArray = array(); // Cumulative array of plugin id's enabled so far in any of the RTE editing areas of the form
154 protected $registeredPlugins = array(); // Array of registered plugins indexd by their plugin Id's
155
156 /**
157 * Returns true if the RTE is available. Here you check if the browser requirements are met.
158 * If there are reasons why the RTE cannot be displayed you simply enter them as text in ->errorLog
159 *
160 * @return boolean TRUE if this RTE object offers an RTE in the current browser environment
161 */
162
163 function isAvailable() {
164 global $TYPO3_CONF_VARS;
165
166 $this->client = $this->clientInfo();
167 $this->errorLog = array();
168 if (!$this->debugMode) { // If debug-mode, let any browser through
169 $rteIsAvailable = 0;
170 $rteConfBrowser = $this->conf_supported_browser;
171 if (!$TYPO3_CONF_VARS['EXTCONF']['rtehtmlarea']['enableInOpera9']) unset($rteConfBrowser['opera']);
172 if (is_array($rteConfBrowser)) {
173 foreach ($rteConfBrowser as $browser => $browserConf) {
174 if ($browser == $this->client['BROWSER']) {
175 // Config for Browser found, check it:
176 if (is_array($browserConf)) {
177 foreach ($browserConf as $browserConfNr => $browserConfSub) {
178 if ($browserConfSub['version'] <= $this->client['VERSION'] || empty($browserConfSub['version'])) {
179 // Version is correct
180 if ($browserConfSub['system'] == $this->client['SYSTEM'] || empty($browserConfSub['system'])) {
181 // System is correctly
182 $rteIsAvailable = 1;
183 }// End of System
184 }// End of Version
185 }// End of foreach-BrowserSubpart
186 } else {
187 // no config for this browser found, so all versions or system with this browsers are allow
188 $rteIsAvailable = 1;
189 }
190 } // End of Browser Check
191 } // foreach: Browser Check
192 } else {
193 // no Browser config for this RTE-Editor, so all Clients are allow
194 }
195 if (!$rteIsAvailable) {
196 $this->errorLog[] = 'rte: Browser not supported. Only msie Version 5 or higher and Mozilla based client 1. and higher.';
197 }
198 if (t3lib_div::int_from_ver(TYPO3_version) < 4000000) {
199 $rteIsAvailable = 0;
200 $this->errorLog[] = 'rte: This version of htmlArea RTE cannot run under this version of TYPO3.';
201 }
202 }
203 if ($rteIsAvailable) return true;
204 }
205
206 /**
207 * Draws the RTE as an iframe
208 *
209 * @param object Reference to parent object, which is an instance of the TCEforms.
210 * @param string The table name
211 * @param string The field name
212 * @param array The current row from which field is being rendered
213 * @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.
214 * @param array "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
215 * @param array Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
216 * @param string Record "type" field value.
217 * @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!
218 * @param integer PID value of record (true parent page id)
219 * @return string HTML code for RTE!
220 */
221
222 function drawRTE($parentObject, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue) {
223 global $BE_USER, $LANG, $TYPO3_DB, $TYPO3_CONF_VARS;
224
225 $this->TCEform =& $parentObject;
226 $inline =& $this->TCEform->inline;
227 $LANG->includeLLFile('EXT:' . $this->ID . '/locallang.xml');
228 $this->client = $this->clientInfo();
229 $this->typoVersion = t3lib_div::int_from_ver(TYPO3_version);
230 $this->userUid = 'BE_' . $BE_USER->user['uid'];
231
232 // Draw form element:
233 if ($this->debugMode) { // Draws regular text area (debug mode)
234 $item = parent::drawRTE($this->TCEform, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue);
235 } else { // Draw real RTE
236
237 /* =======================================
238 * INIT THE EDITOR-SETTINGS
239 * =======================================
240 */
241
242 // first get the http-path to typo3:
243 $this->httpTypo3Path = substr( substr( t3lib_div::getIndpEnv('TYPO3_SITE_URL'), strlen( t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') ) ), 0, -1 );
244 if (strlen($this->httpTypo3Path) == 1) {
245 $this->httpTypo3Path = '/';
246 } else {
247 $this->httpTypo3Path .= '/';
248 }
249 // Get the path to this extension:
250 $this->extHttpPath = $this->httpTypo3Path . t3lib_extMgm::siteRelPath($this->ID);
251 // Get the site URL
252 $this->siteURL = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
253 // Get the host URL
254 $this->hostURL = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST');
255
256 // Element ID + pid
257 $this->elementId = $PA['itemFormElName']; // Form element name
258 $this->elementParts = explode('][',ereg_replace('\]$','',ereg_replace('^(TSFE_EDIT\[data\]\[|data\[)','',$this->elementId)));
259
260 // Find the page PIDs:
261 list($this->tscPID,$this->thePid) = t3lib_BEfunc::getTSCpid(trim($this->elementParts[0]),trim($this->elementParts[1]),$thePidValue);
262
263 // Record "types" field value:
264 $this->typeVal = $RTEtypeVal; // TCA "types" value for record
265
266 // Find "thisConfig" for record/editor:
267 unset($this->RTEsetup);
268 $this->RTEsetup = $BE_USER->getTSConfig('RTE',t3lib_BEfunc::getPagesTSconfig($this->tscPID));
269 $this->thisConfig = $thisConfig;
270
271 // Special configuration and default extras:
272 $this->specConf = $specConf;
273
274 if ($this->thisConfig['forceHTTPS']) {
275 $this->httpTypo3Path = preg_replace('/^(http|https)/', 'https', $this->httpTypo3Path);
276 $this->extHttpPath = preg_replace('/^(http|https)/', 'https', $this->extHttpPath);
277 $this->siteURL = preg_replace('/^(http|https)/', 'https', $this->siteURL);
278 $this->hostURL = preg_replace('/^(http|https)/', 'https', $this->hostURL);
279 }
280
281 /* =======================================
282 * LANGUAGES & CHARACTER SETS
283 * =======================================
284 */
285
286 // Languages: interface and content
287 $this->language = $LANG->lang;
288 if ($this->language=='default' || !$this->language) {
289 $this->language='en';
290 }
291 $this->contentTypo3Language = $this->language;
292
293 $this->contentLanguageUid = ($row['sys_language_uid'] > 0) ? $row['sys_language_uid'] : 0;
294 if (t3lib_extMgm::isLoaded('static_info_tables')) {
295 if ($this->contentLanguageUid) {
296 $tableA = 'sys_language';
297 $tableB = 'static_languages';
298 $languagesUidsList = $this->contentLanguageUid;
299 $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2,' . $tableB . '.lg_typo3';
300 $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
301 $whereClause = $tableA . '.uid IN (' . $languagesUidsList . ') ';
302 $whereClause .= t3lib_BEfunc::BEenableFields($tableA);
303 $whereClause .= t3lib_BEfunc::deleteClause($tableA);
304 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
305 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
306 $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']).(trim($languageRow['lg_country_iso_2'])?'_'.trim($languageRow['lg_country_iso_2']):''));
307 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
308 }
309 } else {
310 $this->contentISOLanguage = trim($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['defaultDictionary']) ? trim($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['defaultDictionary']) : 'en';
311 $selectFields = 'lg_iso_2, lg_typo3';
312 $tableAB = 'static_languages';
313 $whereClause = 'lg_iso_2 = ' . $TYPO3_DB->fullQuoteStr(strtoupper($this->contentISOLanguage), $tableAB);
314 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
315 while($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
316 $this->contentTypo3Language = strtolower(trim($languageRow['lg_typo3']));
317 }
318 }
319 }
320
321 // Character sets: interface and content
322 $this->charset = $LANG->csConvObj->charSetArray[$this->language];
323 $this->charset = $this->charset ? $this->charset : 'iso-8859-1';
324 $this->BECharset = trim($TYPO3_CONF_VARS['BE']['forceCharset']) ? trim($TYPO3_CONF_VARS['BE']['forceCharset']) : $this->charset;
325 $this->OutputCharset = $this->BECharset;
326
327 $this->contentCharset = $LANG->csConvObj->charSetArray[$this->contentTypo3Language];
328 $this->contentCharset = $this->contentCharset ? $this->contentCharset : 'iso-8859-1';
329 $this->origContentCharSet = $this->contentCharset;
330 $this->contentCharset = (trim($TYPO3_CONF_VARS['BE']['forceCharset']) ? trim($TYPO3_CONF_VARS['BE']['forceCharset']) : $this->contentCharset);
331
332 /* =======================================
333 * TOOLBAR CONFIGURATION
334 * =======================================
335 */
336
337 // htmlArea plugins list
338 $this->pluginEnabledArray = t3lib_div::trimExplode(',', $this->pluginList, 1);
339 $this->enableRegisteredPlugins();
340 $hidePlugins = array();
341 if ($this->client['BROWSER'] == 'msie') {
342 $this->thisConfig['keepButtonGroupTogether'] = 0;
343 }
344 if ($this->client['BROWSER'] == 'opera') {
345 $hidePlugins[] = 'ContextMenu';
346 $this->thisConfig['keepButtonGroupTogether'] = 0;
347 }
348 if ($this->client['BROWSER'] == 'gecko' && $this->client['VERSION'] == '1.3') {
349 $this->thisConfig['keepButtonGroupTogether'] = 0;
350 }
351 $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
352
353 // Toolbar
354 $this->setToolbar();
355
356 // Check if some plugins need to be disabled
357 $this->setPlugins();
358
359 // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
360 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = $this->pluginEnabledArray;
361 if ($this->TCEform->RTEcounter > 1 && isset($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1]) && is_array($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])) {
362 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = array_unique(array_values(array_merge($this->pluginEnabledArray,$this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter-1])));
363 }
364
365 /* =======================================
366 * SET STYLES
367 * =======================================
368 */
369
370 $RTEWidth = isset($BE_USER->userTS['options.']['RTESmallWidth']) ? $BE_USER->userTS['options.']['RTESmallWidth'] : '530';
371 $RTEHeight = isset($BE_USER->userTS['options.']['RTESmallHeight']) ? $BE_USER->userTS['options.']['RTESmallHeight'] : '380';
372 $RTEWidth = $RTEWidth + ($this->TCEform->docLarge ? (isset($BE_USER->userTS['options.']['RTELargeWidthIncrement']) ? $BE_USER->userTS['options.']['RTELargeWidthIncrement'] : '150') : 0);
373 $RTEWidth -= ($inline->getStructureDepth() > 0 ? ($inline->getStructureDepth()+1)*$inline->getLevelMargin() : 0);
374 $RTEHeight = $RTEHeight + ($this->TCEform->docLarge ? (isset($BE_USER->userTS['options.']['RTELargeHeightIncrement']) ? $BE_USER->userTS['options.']['RTELargeHeightIncrement'] : 0) : 0);
375 $RTEHeightOverride = intval($this->thisConfig['RTEHeightOverride']);
376 $RTEHeight = ($RTEHeightOverride > 0) ? $RTEHeightOverride : $RTEHeight;
377 $editorWrapWidth = $RTEWidth . 'px';
378 $editorWrapHeight = $RTEHeight . 'px';
379 $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:' . $RTEHeight . 'px; width:'.$RTEWidth.'px; border: 1px solid black; padding: 2px 0px 2px 2px;';
380 $this->toolbar_level_size = $RTEWidth;
381
382 /* =======================================
383 * LOAD CSS AND JAVASCRIPT
384 * =======================================
385 */
386
387 // Preloading the pageStyle
388 $filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/res/contentcss/default.css';
389 $this->TCEform->additionalCode_pre['loadCSS'] = '
390 <link rel="alternate stylesheet" type="text/css" href="' . $this->getFullFileName($filename) . '" title="HTMLArea RTE Content CSS" />';
391
392 // Loading the editor skin
393 $skinFilename = trim($this->thisConfig['skin']) ? trim($this->thisConfig['skin']) : 'EXT:' . $this->ID . '/htmlarea/skins/default/htmlarea.css';
394 if($this->client['BROWSER'] == 'gecko' && $this->client['VERSION'] == '1.3' && substr($skinFilename,0,4) == 'EXT:') {
395 $skinFilename = 'EXT:' . $this->ID . '/htmlarea/skins/default/htmlarea.css';
396 }
397 if (substr($skinFilename,0,4) == 'EXT:') { // extension
398 list($extKey,$local) = explode('/',substr($skinFilename,4),2);
399 $skinFilename='';
400 if (strcmp($extKey,'') && t3lib_extMgm::isLoaded($extKey) && strcmp($local,'')) {
401 $skinFilename = $this->httpTypo3Path . t3lib_extMgm::siteRelPath($extKey) . $local;
402 $skinDir = $this->siteURL . t3lib_extMgm::siteRelPath($extKey) . dirname($local);
403 }
404 } elseif (substr($skinFilename,0,1) != '/') {
405 $skinDir = $this->siteURL.dirname($skinFilename);
406 $skinFilename = $this->siteURL . $skinFilename;
407 } else {
408 $skinDir = substr($this->siteURL,0,-1) . dirname($skinFilename);
409 }
410 $this->editorCSS = $skinFilename;
411 $this->editedContentCSS = $skinDir . '/htmlarea-edited-content.css';
412 $this->TCEform->additionalCode_pre['loadCSS'] .= '
413 <link rel="alternate stylesheet" type="text/css" href="' . $this->editedContentCSS . '" />';
414
415 // Main skin
416 $this->TCEform->additionalCode_pre['loadCSS'] .= '
417 <link rel="stylesheet" type="text/css" href="' . $this->editorCSS . '" />';
418
419 // Additional icons from registered plugins
420 foreach ($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] as $pluginId) {
421 if (is_object($this->registeredPlugins[$pluginId])) {
422 $pathToSkin = $this->registeredPlugins[$pluginId]->getPathToSkin();
423 if ($pathToSkin) {
424 $this->TCEform->additionalCode_pre['loadCSS'] .= '
425 <link rel="stylesheet" type="text/css" href="' . $this->httpTypo3Path . t3lib_extMgm::siteRelPath($this->registeredPlugins[$pluginId]->getExtensionKey()) . $pathToSkin . '" />';
426 }
427 }
428 }
429
430 // Loading JavaScript files and code
431 if ($this->TCEform->RTEcounter == 1) {
432 $this->TCEform->additionalCode_pre['loadJSfiles'] = $this->loadJSfiles($this->TCEform->RTEcounter);
433 $this->TCEform->additionalJS_pre['loadJScode'] = $this->loadJScode($this->TCEform->RTEcounter);
434 }
435
436 /* =======================================
437 * DRAW THE EDITOR
438 * =======================================
439 */
440
441 // Transform value:
442 $value = $this->transformContent('rte',$PA['itemFormElValue'],$table,$field,$row,$specConf,$thisConfig,$RTErelPath,$thePidValue);
443
444 // Further content transformation by registered plugins
445 foreach ($this->registeredPlugins as $pluginId => $plugin) {
446 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "transformContent")) {
447 $value = $plugin->transformContent($value);
448 }
449 }
450 // Register RTE windows
451 $this->TCEform->RTEwindows[] = $PA['itemFormElName'];
452
453 // Check if wizard_rte called this for fullscreen edtition; if so, change the size of the RTE to fullscreen using JS
454 if (basename(PATH_thisScript) == 'wizard_rte.php') {
455 $height = 'window.innerHeight';
456 $width = 'window.innerWidth';
457 if ($this->client['BROWSER'] == 'msie') {
458 $height = 'document.body.offsetHeight';
459 $width = 'document.body.offsetWidth';
460 }
461 $editorWrapWidth = '100%';
462 $editorWrapHeight = '100%';
463 $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:100%; width:100%; border: 1px solid black; padding: 2px 0px 2px 2px;';
464 $this->TCEform->additionalJS_post[] = $this->setRTEsizeByJS('RTEarea'.$this->TCEform->RTEcounter, $height, $width);
465 }
466
467 // Register RTE in JS:
468 $this->TCEform->additionalJS_post[] = $this->registerRTEinJS($this->TCEform->RTEcounter, $table, $row['uid'], $field);
469
470 // Set the save option for the RTE:
471 $this->TCEform->additionalJS_submit[] = $this->setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, htmlspecialchars($PA['itemFormElName']));
472
473 // Draw the textarea
474 $visibility = 'hidden';
475 $item = $this->triggerField($PA['itemFormElName']).'
476 <div id="pleasewait' . $this->TCEform->RTEcounter . '" class="pleasewait" style="display: none;" >' . $LANG->getLL('Please wait') . '</div>
477 <div id="editorWrap' . $this->TCEform->RTEcounter . '" class="editorWrap" style="width:' . $editorWrapWidth . '; height:' . $editorWrapHeight . ';">
478 <textarea id="RTEarea'.$this->TCEform->RTEcounter.'" name="'.htmlspecialchars($PA['itemFormElName']).'" style="'.t3lib_div::deHSCentities(htmlspecialchars($this->RTEdivStyle)).'">'.t3lib_div::formatForTextarea($value).'</textarea>
479 </div>' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableDebugMode'] ? '<div id="HTMLAreaLog"></div>' : '') . '
480 ';
481 }
482
483 // Return form item:
484 return $item;
485 }
486
487 /**
488 * Add registered plugins to the array of enabled plugins
489 *
490 */
491 function enableRegisteredPlugins() {
492 global $TYPO3_CONF_VARS;
493 // Traverse registered plugins
494 if (is_array($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'])) {
495 foreach($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'] as $pluginId => $pluginObjectConfiguration) {
496 $plugin = &t3lib_div::getUserObj($pluginObjectConfiguration['objectReference']);
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' => 'p', '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 if($this->is_FE()) {
1106 $JSLanguageArray = $TSFE->csConvObj->conv($JSLanguageArray, 'iso-8859-1', $this->OutputCharset);
1107 } else {
1108 $JSLanguageArray = $LANG->csConvObj->conv($JSLanguageArray, 'iso-8859-1', $this->OutputCharset);
1109 }
1110
1111 $subArrays = array( 'tooltips', 'msg' , 'dialogs');
1112 $subArraysIndex = 0;
1113 foreach($subArrays as $labels) {
1114 $JSLanguageArray .= (($subArraysIndex++)?',':'') . $labels . ': {' . $linebreak;
1115 if($this->is_FE()) {
1116 $LOCAL_LANG = $TSFE->readLLfile(t3lib_extMgm::extPath($this->ID).'htmlarea/locallang_' . $labels . '.xml', $this->language);
1117 $TSFE->csConvObj->convArray($LOCAL_LANG['default'], 'iso-8859-1', $this->OutputCharset);
1118 if(!empty($LOCAL_LANG[$this->language])) $TSFE->csConvObj->convArray($LOCAL_LANG[$this->language], $this->charset, $this->OutputCharset);
1119 } else {
1120 $LOCAL_LANG = $LANG->readLLfile(t3lib_extMgm::extPath($this->ID).'htmlarea/locallang_' . $labels . '.xml');
1121 $LANG->csConvObj->convArray($LOCAL_LANG['default'], 'iso-8859-1', $this->OutputCharset);
1122 if(!empty($LOCAL_LANG[$this->language])) $LANG->csConvObj->convArray($LOCAL_LANG[$this->language], $this->charset, $this->OutputCharset);
1123 }
1124 if(!empty($LOCAL_LANG[$this->language])) {
1125 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'], $LOCAL_LANG[$this->language]);
1126 } else {
1127 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1128 }
1129 $index = 0;
1130 foreach ( $LOCAL_LANG[$this->language] as $labelKey => $labelValue ) {
1131 $JSLanguageArray .= (($index++)?',':'') . '"' . $labelKey . '":"' . str_replace('"', '\"', $labelValue) . '"' . $linebreak;
1132 }
1133 if($this->is_FE()) {
1134 $JSLanguageArray .= $TSFE->csConvObj->conv(' }' . chr(10), 'iso-8859-1', $this->OutputCharset);
1135 } else {
1136 $JSLanguageArray .= $LANG->csConvObj->conv(' }' . chr(10), 'iso-8859-1', $this->OutputCharset);
1137 }
1138 }
1139
1140 if($this->is_FE()) {
1141 $JSLanguageArray .= $TSFE->csConvObj->conv(' }' . chr(10), 'iso-8859-1', $this->OutputCharset);
1142 } else {
1143 $JSLanguageArray .= $LANG->csConvObj->conv(' }' . chr(10), 'iso-8859-1', $this->OutputCharset);
1144 }
1145 return $JSLanguageArray;
1146 }
1147
1148 /**
1149 * Writes contents in a file in typo3temp/rtehtmlarea directory and returns the file name
1150 *
1151 * @param string $sourceFileName: The name of the file from which the contents should be extracted
1152 * @param string $label: A label to insert at the beginning of the name of the file
1153 * @param string $fileExtension: The file extension of the file, defaulting to 'js'
1154 * @param string $contents: The contents to write into the file if no $sourceFileName is provided
1155 *
1156 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1157 */
1158 public function writeTemporaryFile($sourceFileName='', $label, $fileExtension='js', $contents='') {
1159 global $TYPO3_CONF_VARS;
1160
1161 if ($sourceFileName) {
1162 $output = '';
1163 $source = t3lib_div::getFileAbsFileName($sourceFileName);
1164 $inputHandle = @fopen($source, "rb");
1165 while (!feof($inputHandle)) {
1166 $output .= @fread($inputHandle, 8192);
1167 }
1168 fclose($inputHandle);
1169 } else {
1170 $output = $contents;
1171 }
1172 $compress = $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] && ($fileExtension == 'js') && ($output != '');
1173 $relativeFilename = 'typo3temp/' . $this->ID . '/' . str_replace('-','_',$label) . '_' . t3lib_div::shortMD5(($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . ($sourceFileName?$sourceFileName:$output)), 20) . ($compress ? '_compressed' : '') . '.' . $fileExtension;
1174 $destination = PATH_site . $relativeFilename;
1175 if(!file_exists($destination)) {
1176 $compressedJavaScript = '';
1177 if ($compress) {
1178 $compressedJavaScript = t3lib_div::minifyJavaScript($output);
1179 }
1180 $failure = t3lib_div::writeFileToTypo3tempDir($destination, $compressedJavaScript?$compressedJavaScript:$output);
1181 if ($failure) {
1182 die($failure);
1183 }
1184 }
1185 return ($this->thisConfig['forceHTTPS']?$this->siteURL:$this->httpTypo3Path) . $relativeFilename;
1186 }
1187
1188 /**
1189 * Return a file name containing the main JS language array for HTMLArea
1190 *
1191 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1192 *
1193 * @return string filename
1194 */
1195
1196 function buildJSMainLangFile($RTEcounter) {
1197 $contents = $this->buildJSMainLangArray() . chr(10);
1198 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
1199 $contents .= $this->buildJSLangArray($pluginId) . chr(10);
1200 }
1201 return $this->writeTemporaryFile('', $this->language.'_'.$this->OutputCharset, 'js', $contents);
1202 }
1203
1204 /**
1205 * Return a Javascript localization array for the plugin
1206 *
1207 * @param string $plugin: identification string of the plugin
1208 *
1209 * @return string Javascript localization array
1210 */
1211
1212 function buildJSLangArray($plugin) {
1213 global $TSFE, $LANG, $TYPO3_CONF_VARS;
1214
1215 $extensionKey = is_object($this->registeredPlugins[$plugin]) ? $this->registeredPlugins[$plugin]->getExtensionKey() : $this->ID;
1216
1217 $linebreak = $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] ? '' : chr(10);
1218 if($this->is_FE()) {
1219 $LOCAL_LANG = $TSFE->readLLfile(t3lib_extMgm::extPath($extensionKey).'htmlarea/plugins/' . $plugin . '/locallang.xml', $this->language);
1220 if(!empty($LOCAL_LANG['default'])) $TSFE->csConvObj->convArray($LOCAL_LANG['default'], 'iso-8859-1', $this->OutputCharset);
1221 if(!empty($LOCAL_LANG[$this->language])) $TSFE->csConvObj->convArray($LOCAL_LANG[$this->language], $this->charset, $this->OutputCharset);
1222 } else {
1223 $LOCAL_LANG = $LANG->readLLfile(t3lib_extMgm::extPath($extensionKey).'htmlarea/plugins/' . $plugin . '/locallang.xml');
1224 if(!empty($LOCAL_LANG['default'])) $LANG->csConvObj->convArray($LOCAL_LANG['default'], 'iso-8859-1', $this->OutputCharset);
1225 if(!empty($LOCAL_LANG[$this->language])) $LANG->csConvObj->convArray($LOCAL_LANG[$this->language], $this->charset, $this->OutputCharset);
1226 }
1227
1228 if(!empty($LOCAL_LANG[$this->language])) {
1229 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'],$LOCAL_LANG[$this->language]);
1230 } else {
1231 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1232 }
1233
1234 $JSLanguageArray .= 'var ' . $plugin . '_langArray = new Object();' . $linebreak;
1235 $JSLanguageArray .= $plugin . '_langArray = {' . $linebreak;
1236 if($this->is_FE()) {
1237 $JSLanguageArray = $TSFE->csConvObj->conv($JSLanguageArray, 'iso-8859-1', $this->OutputCharset);
1238 } else {
1239 $JSLanguageArray = $LANG->csConvObj->conv($JSLanguageArray, 'iso-8859-1', $this->OutputCharset);
1240 }
1241
1242 $index = 0;
1243 foreach ( $LOCAL_LANG[$this->language] as $labelKey => $labelValue ) {
1244 $JSLanguageArray .= (($index++)?',':'') . '"' . $labelKey . '":"' . str_replace('"', '\"', $labelValue) . '"' . $linebreak;
1245 }
1246
1247 if($this->is_FE()) {
1248 $JSLanguageArray .= $TSFE->csConvObj->conv(' }' . chr(10), 'iso-8859-1', $this->OutputCharset);
1249 } else {
1250 $JSLanguageArray .= $LANG->csConvObj->conv(' }' . chr(10), 'iso-8859-1', $this->OutputCharset);
1251 }
1252
1253 return $JSLanguageArray;
1254 }
1255
1256 /**
1257 * Return the JS-Code for the Toolbar-Config-Array for HTML-Area
1258 *
1259 * @return string the JS-Code as an JS-Array
1260 */
1261
1262 function getJSToolbarArray() {
1263 $toolbar = ''; // The JS-Code for the toolbar
1264 $group = ''; // The TS-Code for the group in the moment, each group are between "bar"s
1265 $group_has_button = false; // True if the group has any enabled buttons
1266 $group_needs_starting_bar = false;
1267 $previous_is_space = false;
1268
1269 // process each button in the order list
1270 foreach ($this->toolbarOrderArray as $button) {
1271 // check if a new group starts
1272 if (($button == 'bar' || $button == 'linebreak') && $group_has_button) {
1273 // New line
1274 if ($button == 'linebreak') {
1275 $convertButton = '"' . $this->convertToolbarForHTMLArea('linebreak') . '"';
1276 $group = ($group!='') ? ($group . ', ' . $convertButton) : $convertButton;
1277 }
1278 // New group
1279 $toolbar .= $toolbar ? (', ' . $group) : ('[[' . $group);
1280 $group = '';
1281 $previous_is_space = false;
1282 $group_has_button = false;
1283 $group_needs_starting_bar = true;
1284 } elseif ($toolbar && $button == 'linebreak' && !$group_has_button) {
1285 // Insert linebreak if no group is opened
1286 $group = '';
1287 $previous_is_space = false;
1288 $group_needs_starting_bar = false;
1289 $toolbar .= ', "' . $this->convertToolbarForHTMLArea($button) . '"';
1290 } elseif ($button == 'bar' && !$group_has_button) {
1291 $group_needs_starting_bar = true;
1292 } elseif ($button == 'space' && $group_has_button && !$previous_is_space) {
1293 $convertButton = $this->convertToolbarForHTMLArea($button);
1294 $convertButton = '"' . $convertButton . '"';
1295 $group .= $group ? (', ' . $convertButton) : ($group_needs_starting_bar ? ('"' . $this->convertToolbarForHTMLArea('bar') . '", ' . $convertButton) : $convertButton);
1296 $group_needs_starting_bar = false;
1297 $previous_is_space = true;
1298 } elseif (in_array($button, $this->toolbar)) {
1299 // Add the button to the group
1300 $convertButton = $this->convertToolbarForHTMLArea($button);
1301 if ($convertButton) {
1302 $convertButton = '"' . $convertButton . '"';
1303 $group .= $group ? (', ' . $convertButton) : ($group_needs_starting_bar ? ('"' . $this->convertToolbarForHTMLArea('bar') . '", ' . $convertButton) : $convertButton);
1304 $group_has_button = true;
1305 $group_needs_starting_bar = false;
1306 $previous_is_space = false;
1307 }
1308 }
1309 // else ignore
1310 }
1311 // add the last group
1312 if($group_has_button) $toolbar .= $toolbar ? (', ' . $group) : ('[[' . $group);
1313 $toolbar = $toolbar . ']]';
1314 return $toolbar;
1315 }
1316
1317 public function getLLContent($string) {
1318 global $LANG;
1319
1320 $BE_lang = $LANG->lang;
1321 $BE_origCharset = $LANG->origCharSet;
1322 $BE_charSet = $LANG->charSet;
1323 $LANG->lang = $this->contentTypo3Language;
1324 $LANG->origCharSet = $this->origContentCharSet;
1325 $LANG->charSet = $this->contentCharset;
1326 $LLString = $LANG->JScharCode($LANG->sL($string));
1327 $LANG->lang = $BE_lang;
1328 $LANG->origCharSet = $BE_origCharset;
1329 $LANG->charSet = $BE_charSet;
1330 return $LLString;
1331 }
1332
1333 public function getPageConfigLabel($string,$JScharCode=1) {
1334 global $LANG, $TSFE;
1335
1336 if ($this->is_FE()) {
1337 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $TSFE->renderCharset, $TSFE->metaCharset);
1338 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1339 $label = $JScharCode ? $this->feJScharCode($label) : $label;
1340 } else {
1341 if (strcmp(substr($string,0,4),'LLL:')) {
1342 $label = $string;
1343 } else {
1344 $label = $LANG->sL(trim($string));
1345 }
1346 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1347 $label = $JScharCode ? $LANG->JScharCode($label): $label;
1348 }
1349 return $label;
1350 }
1351
1352 function feJScharCode($str) {
1353 global $TSFE;
1354 // Convert string to UTF-8:
1355 if ($this->OutputCharset != 'utf-8') $str = $TSFE->csConvObj->utf8_encode($str,$this->OutputCharset);
1356 // Convert the UTF-8 string into a array of char numbers:
1357 $nArr = $TSFE->csConvObj->utf8_to_numberarray($str);
1358 return 'String.fromCharCode('.implode(',',$nArr).')';
1359 }
1360
1361 public function getFullFileName($filename) {
1362 if (substr($filename,0,4)=='EXT:') { // extension
1363 list($extKey,$local) = explode('/',substr($filename,4),2);
1364 $newFilename = '';
1365 if (strcmp($extKey,'') && t3lib_extMgm::isLoaded($extKey) && strcmp($local,'')) {
1366 $newFilename = $this->siteURL . t3lib_extMgm::siteRelPath($extKey) . $local;
1367 }
1368 } elseif (substr($filename,0,1) != '/') {
1369 $newFilename = $this->siteURL . $filename;
1370 } else {
1371 $newFilename = $this->siteURL . substr($filename,1);
1372 }
1373 return $newFilename;
1374 }
1375
1376 /**
1377 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1378 * This is for submit function of the form.
1379 *
1380 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1381 * @param string $formName: the name of the form
1382 * @param string $textareaId: the id of the textarea
1383 *
1384 * @return string Javascript code
1385 */
1386 function setSaveRTE($RTEcounter, $formName, $textareaId) {
1387 return '
1388 editornumber = '.$RTEcounter.';
1389 if (RTEarea[editornumber]) {
1390 document.'.$formName.'["'.$textareaId.'"].value = RTEarea[editornumber]["editor"].getHTML();
1391 }
1392 else {
1393 OK=0;
1394 }
1395 ';
1396 }
1397
1398 /**
1399 * Return true if we are in the FE, but not in the FE editing feature of BE.
1400 *
1401 * @return boolean
1402 */
1403
1404 function is_FE() {
1405 global $TSFE;
1406 return is_object($TSFE) && !strstr($this->elementId,'TSFE_EDIT');
1407 }
1408
1409 /**
1410 * Client Browser Information
1411 *
1412 * Usage: 4
1413 *
1414 * @param string Alternative User Agent string (if empty, t3lib_div::getIndpEnv('HTTP_USER_AGENT') is used)
1415 * @return array Parsed information about the HTTP_USER_AGENT in categories BROWSER, VERSION, SYSTEM and FORMSTYLE
1416 */
1417
1418 function clientInfo($useragent='') {
1419 global $TYPO3_CONF_VARS;
1420
1421 if (!$useragent) $useragent=t3lib_div::getIndpEnv('HTTP_USER_AGENT');
1422
1423 $bInfo=array();
1424 // Which browser?
1425 if (strstr($useragent,'Konqueror')) {
1426 $bInfo['BROWSER']= 'konqu';
1427 } elseif (strstr($useragent,'Opera')) {
1428 $bInfo['BROWSER']= 'opera';
1429 } elseif (strstr($useragent,'MSIE')) {
1430 $bInfo['BROWSER']= 'msie';
1431 } elseif (strstr($useragent,'Gecko/')) {
1432 $bInfo['BROWSER']='gecko';
1433 } elseif (strstr($useragent,'Safari/')) {
1434 $bInfo['BROWSER']='safari';
1435 } elseif (strstr($useragent,'Mozilla/4')) {
1436 $bInfo['BROWSER']='net';
1437 }
1438
1439 if ($bInfo['BROWSER']) {
1440 // Browser version
1441 switch($bInfo['BROWSER']) {
1442 case 'net':
1443 $bInfo['VERSION']= doubleval(substr($useragent,8));
1444 if (strstr($useragent,'Netscape6/')) {$bInfo['VERSION']=doubleval(substr(strstr($useragent,'Netscape6/'),10));}
1445 if (strstr($useragent,'Netscape/7')) {$bInfo['VERSION']=doubleval(substr(strstr($useragent,'Netscape/7'),9));}
1446 break;
1447 case 'gecko':
1448 $tmp = strstr($useragent,'rv:');
1449 $bInfo['VERSION'] = doubleval(ereg_replace('^[^0-9]*','',substr($tmp,3)));
1450 break;
1451 case 'msie':
1452 $tmp = strstr($useragent,'MSIE');
1453 $bInfo['VERSION'] = doubleval(ereg_replace('^[^0-9]*','',substr($tmp,4)));
1454 break;
1455 case 'safari':
1456 $tmp = strstr($useragent,'Safari/');
1457 $bInfo['VERSION'] = doubleval(ereg_replace('^[^0-9]*','',substr($tmp,3)));
1458 break;
1459 case 'opera':
1460 $tmp = strstr($useragent,'Opera');
1461 $bInfo['VERSION'] = doubleval(ereg_replace('^[^0-9]*','',substr($tmp,5)));
1462 break;
1463 case 'konqu':
1464 $tmp = strstr($useragent,'Konqueror/');
1465 $bInfo['VERSION'] = doubleval(substr($tmp,10));
1466 break;
1467 }
1468
1469 // Client system
1470 if (strstr($useragent,'Win')) {
1471 $bInfo['SYSTEM'] = 'win';
1472 } elseif (strstr($useragent,'Mac')) {
1473 $bInfo['SYSTEM'] = 'mac';
1474 } elseif (strstr($useragent,'Linux') || strstr($useragent,'X11') || strstr($useragent,'SGI') || strstr($useragent,' SunOS ') || strstr($useragent,' HP-UX ')) {
1475 $bInfo['SYSTEM'] = 'unix';
1476 }
1477 }
1478
1479 // Is true if the browser supports css to format forms, especially the width
1480 $bInfo['FORMSTYLE']=($bInfo['BROWSER']=='msie' || ($bInfo['BROWSER']=='net'&&$bInfo['VERSION']>=5) || $bInfo['BROWSER']=='opera' || $bInfo['BROWSER']=='konqu');
1481 return $bInfo;
1482 }
1483
1484 /***************************
1485 *
1486 * OTHER FUNCTIONS: (from Classic RTE)
1487 *
1488 ***************************/
1489 /**
1490 * @return [type] ...
1491 * @desc
1492 */
1493
1494 function RTEtsConfigParams() {
1495 if($this->is_FE()) {
1496 return '';
1497 } else {
1498 $p = t3lib_BEfunc::getSpecConfParametersFromArray($this->specConf['rte_transform']['parameters']);
1499 return $this->elementParts[0].':'.$this->elementParts[1].':'.$this->elementParts[2].':'.$this->thePid.':'.$this->typeVal.':'.$this->tscPID.':'.$p['imgpath'];
1500 }
1501 }
1502
1503 public function cleanList($str) {
1504 if (strstr($str,'*')) {
1505 $str = '*';
1506 } else {
1507 $str = implode(',',array_unique(t3lib_div::trimExplode(',',$str,1)));
1508 }
1509 return $str;
1510 }
1511
1512 function filterStyleEl($elValue,$matchList) {
1513 $matchParts = t3lib_div::trimExplode(',',$matchList,1);
1514 $styleParts = explode(';',$elValue);
1515 $nStyle=array();
1516 foreach ($styleParts as $k => $p) {
1517 $pp = t3lib_div::trimExplode(':',$p);
1518 if ($pp[0]&&$pp[1]) {
1519 foreach ($matchParts as $el) {
1520 $star=substr($el,-1)=='*';
1521 if (!strcmp($pp[0],$el) || ($star && t3lib_div::isFirstPartOfStr($pp[0],substr($el,0,-1)) )) {
1522 $nStyle[]=$pp[0].':'.$pp[1];
1523 } else unset($styleParts[$k]);
1524 }
1525 } else {
1526 unset($styleParts[$k]);
1527 }
1528 }
1529 return implode('; ',$nStyle);
1530 }
1531
1532 // Hook on lorem_ipsum extension to insert text into the RTE in wysiwyg mode
1533 function loremIpsumInsert($params) {
1534 return "
1535 if (typeof(lorem_ipsum) == 'function' && " . $params['element'] . ".tagName.toLowerCase() == 'textarea' ) lorem_ipsum(" . $params['element'] . ", lipsum_temp_strings[lipsum_temp_pointer]);
1536 ";
1537 }
1538 }
1539
1540 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']) {
1541 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']);
1542 }
1543
1544 ?>