b9f29c49c35d6cdeb8acc9763b6fa514f389c36c
[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 public $registeredPlugins = array(); // Array of registered plugins indexed 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 $textAreaId = htmlspecialchars($PA['itemFormElName']);
435
436 // Check if wizard_rte called this for fullscreen edtition; if so, change the size of the RTE to fullscreen using JS
437 if (basename(PATH_thisScript) == 'wizard_rte.php') {
438 $height = 'window.innerHeight';
439 $width = 'window.innerWidth';
440 if ($this->client['BROWSER'] == 'msie') {
441 $height = 'document.body.offsetHeight';
442 $width = 'document.body.offsetWidth';
443 }
444 $editorWrapWidth = '100%';
445 $editorWrapHeight = '100%';
446 $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:100%; width:100%; border: 1px solid black; padding: 2px 0px 2px 2px;';
447 $this->TCEform->additionalJS_post[] = $this->setRTEsizeByJS('RTEarea' . $textAreaId, $height, $width);
448 }
449
450 // Register RTE in JS:
451 $this->TCEform->additionalJS_post[] = $this->registerRTEinJS($this->TCEform->RTEcounter, $table, $row['uid'], $field, $textAreaId);
452
453 // Set the save option for the RTE:
454 $this->TCEform->additionalJS_submit[] = $this->setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
455 $this->TCEform->additionalJS_delete[] = $this->setDeleteRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
456
457 // Draw the textarea
458 $visibility = 'hidden';
459 $unuqid = uniqid('rte');
460 $item = $this->triggerField($PA['itemFormElName']).'
461 <div id="pleasewait' . $textAreaId . '" class="pleasewait" style="display: block;" >' . $LANG->getLL('Please wait') . '</div>
462 <div id="editorWrap' . $textAreaId . '" class="editorWrap" style="visibility: hidden; width:' . $editorWrapWidth . '; height:' . $editorWrapHeight . ';">
463 <textarea id="RTEarea' . $textAreaId . '" name="'.htmlspecialchars($PA['itemFormElName']).'" style="'.t3lib_div::deHSCentities(htmlspecialchars($this->RTEdivStyle)).'">'.t3lib_div::formatForTextarea($value).'</textarea>
464 </div>' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableDebugMode'] ? '<div id="HTMLAreaLog"></div>' : '') . '
465 ';
466 }
467
468 // Return form item:
469 return $item;
470 }
471
472 /**
473 * Add registered plugins to the array of enabled plugins
474 *
475 */
476 function enableRegisteredPlugins() {
477 global $TYPO3_CONF_VARS;
478 // Traverse registered plugins
479 if (is_array($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'])) {
480 foreach($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'] as $pluginId => $pluginObjectConfiguration) {
481 $plugin = false;
482 if (is_array($pluginObjectConfiguration) && count($pluginObjectConfiguration)) {
483 $plugin = &t3lib_div::getUserObj($pluginObjectConfiguration['objectReference']);
484 }
485 if (is_object($plugin)) {
486 if ($plugin->main($this)) {
487 $this->registeredPlugins[$pluginId] = $plugin;
488 // Override buttons from previously registered plugins
489 $pluginButtons = t3lib_div::trimExplode(',', $plugin->getPluginButtons(), 1);
490 foreach ($this->pluginButton as $previousPluginId => $buttonList) {
491 $this->pluginButton[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginButton[$previousPluginId], 1), $pluginButtons));
492 }
493 $this->pluginButton[$pluginId] = $plugin->getPluginButtons();
494 $pluginLabels = t3lib_div::trimExplode(',', $plugin->getPluginLabels(), 1);
495 foreach ($this->pluginLabel as $previousPluginId => $labelList) {
496 $this->pluginLabel[$previousPluginId] = implode(',',array_diff(t3lib_div::trimExplode(',', $this->pluginLabel[$previousPluginId], 1), $pluginLabels));
497 }
498 $this->pluginLabel[$pluginId] = $plugin->getPluginLabels();
499 $this->pluginEnabledArray[] = $pluginId;
500 }
501 }
502 }
503 }
504 // Process overrides
505 $hidePlugins = array();
506 foreach ($this->registeredPlugins as $pluginId => $plugin) {
507 if ($plugin->addsButtons() && !$this->pluginButton[$pluginId]) {
508 $hidePlugins[] = $pluginId;
509 }
510 }
511 $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
512 }
513
514 /**
515 * Set the toolbar config (only in this PHP-Object, not in JS):
516 *
517 */
518
519 function setToolbar() {
520 global $BE_USER;
521
522 $this->defaultToolbarOrder = 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
523 bar, formattext, bold, strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code, definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span,
524 bar, fontstyle, space, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote,
525 bar, left, center, right, justifyfull,
526 bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, lefttoright, righttoleft,
527 bar, textcolor, bgcolor, textindicator,
528 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,
529 bar, chMode, inserttag, removeformat, bar, copy, cut, paste, bar, undo, redo, bar, showhelp, about, linebreak,
530 ' . ($this->thisConfig['hideTableOperationsInToolbar'] ? '': 'bar, toggleborders,') . ' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
531 columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
532 cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
533
534 // Special toolbar for Mozilla Wamcom on Mac OS 9
535 if($this->client['BROWSER'] == 'gecko' && $this->client['VERSION'] == '1.3') {
536 $this->defaultToolbarOrder = $this->TCEform->docLarge ? 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
537 bar, fontstyle, space, fontsize, space, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, bar, bold, italic, underline, strikethrough,
538 subscript, superscript, lefttoright, righttoleft, bar, left, center, right, justifyfull, linebreak,
539 bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, textcolor, bgcolor, textindicator, bar, emoticon,
540 insertcharacter, line, link, unlink, image, table, user, acronym, bar, findreplace, spellcheck, bar, chMode, inserttag,
541 removeformat, bar, copy, cut, paste, bar, undo, redo, bar, showhelp, about, linebreak,
542 bar, toggleborders, bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
543 columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
544 cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge'
545 : 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
546 bar, fontstyle, space, fontsize, space, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, bar, bold, italic, underline, strikethrough,
547 subscript, superscript, linebreak, bar, lefttoright, righttoleft, bar, left, center, right, justifyfull,
548 orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, textcolor, bgcolor, textindicator, bar, emoticon,
549 insertcharacter, line, link, unlink, image, table, user, acronym, linebreak, bar, findreplace, spellcheck, bar, chMode, inserttag,
550 removeformat, bar, copy, cut, paste, bar, undo, redo, bar, showhelp, about, linebreak,
551 bar, toggleborders, bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
552 columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
553 cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
554 }
555
556 // Additional buttons from registered plugins
557 foreach($this->registeredPlugins as $pluginId => $plugin) {
558 if ($this->isPluginEnabled($pluginId)) {
559 $this->defaultToolbarOrder = $plugin->addButtonsToToolbar();
560 }
561 }
562 $toolbarOrder = $this->thisConfig['toolbarOrder'] ? $this->thisConfig['toolbarOrder'] : $this->defaultToolbarOrder;
563
564 // Getting rid of undefined buttons
565 $this->toolbarOrderArray = array_intersect(t3lib_div::trimExplode(',', $toolbarOrder, 1), t3lib_div::trimExplode(',', $this->defaultToolbarOrder, 1));
566 $toolbarOrder = array_unique(array_values($this->toolbarOrderArray));
567
568 // Fetching specConf for field from backend
569 $pList = is_array($this->specConf['richtext']['parameters']) ? implode(',',$this->specConf['richtext']['parameters']) : '';
570 if ($pList != '*') { // If not all
571 $show = is_array($this->specConf['richtext']['parameters']) ? $this->specConf['richtext']['parameters'] : array();
572 if ($this->thisConfig['showButtons']) {
573 if (!t3lib_div::inList($this->thisConfig['showButtons'],'*')) {
574 $show = array_unique(array_merge($show,t3lib_div::trimExplode(',',$this->thisConfig['showButtons'],1)));
575 } else {
576 $show = array_unique(array_merge($show, $toolbarOrder));
577 }
578 }
579 if (is_array($this->thisConfig['showButtons.'])) {
580 foreach ($this->thisConfig['showButtons.'] as $buttonId => $value) {
581 if ($value) $show[] = $buttonId;
582 }
583 $show = array_unique($show);
584 }
585 } else {
586 $show = $toolbarOrder;
587 }
588
589 // Resticting to RTEkeyList for backend user
590 if(is_object($BE_USER)) {
591 $RTEkeyList = isset($BE_USER->userTS['options.']['RTEkeyList']) ? $BE_USER->userTS['options.']['RTEkeyList'] : '*';
592 if ($RTEkeyList != '*') { // If not all
593 $show = array_intersect($show, t3lib_div::trimExplode(',',$RTEkeyList,1));
594 }
595 }
596
597 // Hiding buttons of disabled plugins
598 $hideButtons = array('space', 'bar', 'linebreak');
599 foreach ($this->pluginButton as $pluginId => $buttonList) {
600 if (!$this->isPluginEnabled($pluginId)) {
601 $buttonArray = t3lib_div::trimExplode(',',$buttonList,1);
602 foreach ($buttonArray as $button) {
603 $hideButtons[] = $button;
604 }
605 }
606 }
607
608 // Hiding labels of disabled plugins
609 foreach ($this->pluginLabel as $pluginId => $label) {
610 if (!$this->isPluginEnabled($pluginId)) {
611 $hideButtons[] = $label;
612 }
613 }
614
615 // Hiding buttons
616 $show = array_diff($show, $this->conf_toolbar_hide, t3lib_div::trimExplode(',',$this->thisConfig['hideButtons'],1));
617
618 // Apply toolbar constraints from registered plugins
619 foreach ($this->registeredPlugins as $pluginId => $plugin) {
620 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, "applyToolbarConstraints")) {
621 $show = $plugin->applyToolbarConstraints($show);
622 }
623 }
624 // Adding the always show buttons
625 $show = array_unique(array_merge($show, $this->conf_toolbar_show));
626 $toolbarOrder = array_unique(array_merge($toolbarOrder, $this->conf_toolbar_show));
627 foreach ($this->conf_toolbar_show as $buttonId) {
628 if (!in_array($buttonId, $this->toolbarOrderArray)) $this->toolbarOrderArray[] = $buttonId;
629 }
630
631 // Getting rid of the buttons for which we have no position
632 $show = array_intersect($show, $toolbarOrder);
633 $this->toolbar = $show;
634 }
635
636 /**
637 * Disable some plugins
638 *
639 */
640 function setPlugins() {
641
642 // Disabling a plugin that adds buttons if none of its buttons is in the toolbar
643 $hidePlugins = array();
644 foreach ($this->pluginButton as $pluginId => $buttonList) {
645 if ($this->registeredPlugins[$pluginId]->addsButtons()) {
646 $showPlugin = false;
647 $buttonArray = t3lib_div::trimExplode(',', $buttonList, 1);
648 foreach ($buttonArray as $button) {
649 if (in_array($button, $this->toolbar)) {
650 $showPlugin = true;
651 }
652 }
653 if (!$showPlugin) {
654 $hidePlugins[] = $pluginId;
655 }
656 }
657 }
658 $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
659
660 // Hiding labels of disabled plugins
661 $hideLabels = array();
662 foreach ($this->pluginLabel as $pluginId => $label) {
663 if (!$this->isPluginEnabled($pluginId)) {
664 $hideLabels[] = $label;
665 }
666 }
667 $this->toolbar = array_diff($this->toolbar, $hideLabels);
668
669 // Adding plugins declared as prerequisites by enabled plugins
670 $requiredPlugins = array();
671 foreach ($this->registeredPlugins as $pluginId => $plugin) {
672 if ($this->isPluginEnabled($pluginId)) {
673 $requiredPlugins = array_merge($requiredPlugins, t3lib_div::trimExplode(',', $plugin->getRequiredPlugins(), 1));
674 }
675 }
676 $requiredPlugins = array_unique($requiredPlugins);
677 foreach ($requiredPlugins as $pluginId) {
678 if (is_object($this->registeredPlugins[$pluginId]) && !$this->isPluginEnabled($pluginId)) {
679 $this->pluginEnabledArray[] = $pluginId;
680 }
681 }
682
683 // Completing the toolbar converion array for htmlArea
684 foreach ($this->registeredPlugins as $pluginId => $plugin) {
685 if ($this->isPluginEnabled($pluginId)) {
686 $this->convertToolbarForHtmlAreaArray = array_unique(array_merge($this->convertToolbarForHtmlAreaArray, $plugin->getConvertToolbarForHtmlAreaArray()));
687 }
688 }
689 }
690
691 /**
692 * Convert the TYPO3 names of buttons into the names for htmlArea RTE
693 *
694 * @param string buttonname (typo3-name)
695 * @return string buttonname (htmlarea-name)
696 */
697
698 function convertToolbarForHTMLArea($button) {
699 return $this->convertToolbarForHtmlAreaArray[$button];
700 }
701
702 /**
703 * Return the JS-function for setting the RTE size.
704 *
705 * @param string DivID-Name
706 * @param int the height for the RTE
707 * @param int the width for the RTE
708 * @return string Loader function in JS
709 */
710 function setRTEsizeByJS($divId, $height, $width) {
711 return '
712 setRTEsizeByJS(\''.$divId.'\','.$height.', '.$width.');
713 ';
714 }
715
716 /**
717 * Return the HTML code for loading the Javascript files
718 *
719 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
720 *
721 * @return string the html code for loading the Javascript Files
722 */
723 function loadJSfiles($RTEcounter) {
724 global $TYPO3_CONF_VARS;
725
726 $loadJavascriptCode = '
727 <script type="text/javascript">
728 /*<![CDATA[*/
729 function rteHtmlAreaGetElementsByClassName(className) {
730 var allElements = document.getElementsByTagName("*");
731 var result = new Array();
732
733 for (var i = 0; i < allElements.length; i++) {
734 var c = " " + allElements[i].className + " ";
735 if (c.indexOf(" " + className + " ") != -1) {
736 result[result.length] = allElements[i];
737 }
738 }
739 return result;
740 }
741
742 wait_elements = rteHtmlAreaGetElementsByClassName("pleasewait");
743 wrap_elements = rteHtmlAreaGetElementsByClassName("editorWrap");
744 for (i = 0; i < wait_elements.length; i++) {
745 wait_elements[i].style.display = "block";
746 wrap_elements[i].style.visibility = "hidden";
747 }
748 RTEarea = new Array();
749 RTEarea[0] = new Object();
750 RTEarea[0]["version"] = "' . $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . '";'
751 . (($this->client['BROWSER'] == 'msie') ? ('
752 RTEarea[0]["htmlarea-ie"] = "' . $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-ie.js', "htmlarea-ie") . '";')
753 : ('
754 RTEarea[0]["htmlarea-gecko"] = "' . $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea-gecko.js', "htmlarea-gecko") . '";')) . '
755 _editor_url = "' . $this->extHttpPath . 'htmlarea";
756 _editor_lang = "' . $this->language . '";
757 _editor_CSS = "' . $this->editorCSS . '";
758 _editor_skin = "' . dirname($this->editorCSS) . '";
759 _editor_edited_content_CSS = "' . $this->editedContentCSS . '";
760 _typo3_host_url = "' . $this->hostURL . '";
761 _editor_debug_mode = ' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableDebugMode'] ? 'true' : 'false') . ';
762 _editor_compressed_scripts = ' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] ? 'true' : 'false') . ';'
763 . (($this->client['BROWSER'] == 'gecko') ? ('
764 _editor_mozAllowClipboard_url = "' . ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['mozAllowClipboardURL'] ? $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['mozAllowClipboardURL'] : '') . '";')
765 : '') . '
766 /*]]>*/
767 </script>';
768 $loadJavascriptCode .= '
769 <script type="text/javascript" src="' . $this->buildJSMainLangFile($RTEcounter) . '"></script>
770 <script type="text/javascript" src="' . $this->writeTemporaryFile('EXT:' . $this->ID . '/htmlarea/htmlarea.js', "htmlarea") . '"></script>
771 ';
772 return $loadJavascriptCode;
773 }
774
775 /**
776 * Return the inline Javascript code for initializing the RTE
777 *
778 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
779 *
780 * @return string the inline Javascript code for initializing the RTE
781 */
782
783 function loadJScode($RTEcounter) {
784 global $TYPO3_CONF_VARS;
785
786 $loadPluginCode = '';
787 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
788 $extensionKey = is_object($this->registeredPlugins[$pluginId]) ? $this->registeredPlugins[$pluginId]->getExtensionKey() : $this->ID;
789 $loadPluginCode .= '
790 HTMLArea.loadPlugin("' . $pluginId . '", "' . $this->writeTemporaryFile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $pluginId . '/' . strtolower(preg_replace('/([a-z])([A-Z])([a-z])/', "$1".'-'."$2"."$3", $pluginId)) . '.js', $pluginId) . '", '. ($this->registeredPlugins[$pluginId]->requiresSynchronousLoad()?'false':'true'). ');';
791 }
792 return (!$this->is_FE() ? '' : '
793 ' . '/*<![CDATA[*/') . ($this->is_FE() ? '' : '
794 RTEarea[0]["RTEtsConfigParams"] = "&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams()) . '";')
795 . $loadPluginCode . '
796 HTMLArea.init();' . (!$this->is_FE() ? '' : '
797 /*]]>*/
798 ');
799 }
800
801 /**
802 * Return the Javascript code for configuring the RTE
803 *
804 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
805 * @param string $table: The table that includes this RTE (optional, necessary for IRRE).
806 * @param string $uid: The uid of that table that includes this RTE (optional, necessary for IRRE).
807 * @param string $field: The field of that record that includes this RTE (optional).
808 *
809 * @return string the Javascript code for configuring the RTE
810 */
811 function registerRTEinJS($RTEcounter, $table='', $uid='', $field='', $textAreaId = '') {
812 global $TYPO3_CONF_VARS;
813
814 $configureRTEInJavascriptString = (!$this->is_FE() ? '' : '
815 ' . '/*<![CDATA[*/') . '
816 editornumber = RTEarea.length;
817 document.getElementById("pleasewait' . $textAreaId . '").id = "pleasewait" + editornumber;
818 document.getElementById("editorWrap' . $textAreaId . '").id = "editorWrap" + editornumber;
819 document.getElementById("RTEarea' . $textAreaId . '").id = "RTEarea" + editornumber;
820 RTEarea[editornumber] = new Object();
821 RTEarea[editornumber].RTEtsConfigParams = "&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams()) . '";
822 RTEarea[editornumber].number = editornumber;
823 RTEarea[editornumber].deleted = false;
824 RTEarea[editornumber].textAreaId = "' . $textAreaId . '";
825 RTEarea[editornumber].id = "RTEarea" + editornumber;
826 RTEarea[editornumber].enableWordClean = ' . (trim($this->thisConfig['enableWordClean'])?'true':'false') . ';
827 RTEarea[editornumber]["htmlRemoveComments"] = ' . (trim($this->thisConfig['removeComments'])?'true':'false') . ';
828 RTEarea[editornumber].disableEnterParagraphs = ' . (trim($this->thisConfig['disableEnterParagraphs'])?'true':'false') . ';
829 RTEarea[editornumber].disableObjectResizing = ' . (trim($this->thisConfig['disableObjectResizing'])?'true':'false') . ';
830 RTEarea[editornumber]["removeTrailingBR"] = ' . (trim($this->thisConfig['removeTrailingBR'])?'true':'false') . ';
831 RTEarea[editornumber]["useCSS"] = ' . (trim($this->thisConfig['useCSS'])?'true':'false') . ';
832 RTEarea[editornumber]["keepButtonGroupTogether"] = ' . (trim($this->thisConfig['keepButtonGroupTogether'])?'true':'false') . ';
833 RTEarea[editornumber]["disablePCexamples"] = ' . (trim($this->thisConfig['disablePCexamples'])?'true':'false') . ';
834 RTEarea[editornumber]["statusBar"] = ' . (trim($this->thisConfig['showStatusBar'])?'true':'false') . ';
835 RTEarea[editornumber]["showTagFreeClasses"] = ' . (trim($this->thisConfig['showTagFreeClasses'])?'true':'false') . ';
836 RTEarea[editornumber]["useHTTPS"] = ' . ((trim(stristr($this->siteURL, 'https')) || $this->thisConfig['forceHTTPS'])?'true':'false') . ';
837 RTEarea[editornumber]["enableMozillaExtension"] = ' . (($this->client['BROWSER'] == 'gecko' && $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableMozillaExtension'])?'true':'false') . ';
838 RTEarea[editornumber]["tceformsNested"] = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(true) : '[]') . ';
839 RTEarea[editornumber].dialogueWindows = new Object();
840 RTEarea[editornumber].dialogueWindows.defaultPositionFromTop = ' . (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromTop'])? intval($this->thisConfig['dialogueWindows.']['defaultPositionFromTop']) : '100') . ';
841 RTEarea[editornumber].dialogueWindows.defaultPositionFromLeft = ' . (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'])? intval($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft']) : '100') . ';
842 RTEarea[editornumber].dialogueWindows.doNotResize = ' . (trim($this->thisConfig['dialogueWindows.']['doNotResize'])?'true':'false') . ';
843 RTEarea[editornumber].dialogueWindows.doNotCenter = ' . (trim($this->thisConfig['dialogueWindows.']['doNotCenter'])?'true':'false') . ';';
844
845 // The following properties apply only to the backend
846 if (!$this->is_FE()) {
847 $configureRTEInJavascriptString .= '
848 RTEarea[editornumber].sys_language_content = "' . $this->contentLanguageUid . '";
849 RTEarea[editornumber].typo3ContentLanguage = "' . $this->contentTypo3Language . '";
850 RTEarea[editornumber].typo3ContentCharset = "' . $this->contentCharset . '";
851 RTEarea[editornumber].userUid = "' . $this->userUid . '";';
852 }
853
854 // Setting the plugin flags
855 $configureRTEInJavascriptString .= '
856 RTEarea[editornumber].plugin = new Object();
857 RTEarea[editornumber].pathToPluginDirectory = new Object();';
858 foreach ($this->pluginEnabledArray as $pluginId) {
859 $configureRTEInJavascriptString .= '
860 RTEarea[editornumber].plugin.'.$pluginId.' = true;';
861 if (is_object($this->registeredPlugins[$pluginId])) {
862 $pathToPluginDirectory = $this->registeredPlugins[$pluginId]->getPathToPluginDirectory();
863 if ($pathToPluginDirectory) {
864 $configureRTEInJavascriptString .= '
865 RTEarea[editornumber].pathToPluginDirectory.'.$pluginId.' = "' . $pathToPluginDirectory . '";';
866 }
867 }
868 }
869
870 // Setting the buttons configuration
871 $configureRTEInJavascriptString .= '
872 RTEarea[editornumber].buttons = new Object();';
873 if (is_array($this->thisConfig['buttons.'])) {
874 foreach ($this->thisConfig['buttons.'] as $buttonIndex => $conf) {
875 $button = substr($buttonIndex, 0, -1);
876 if (in_array($button,$this->toolbar)) {
877 $configureRTEInJavascriptString .= '
878 RTEarea[editornumber].buttons.'.$button.' = ' . $this->buildNestedJSArray($conf) . ';';
879 }
880 }
881 }
882
883 // Setting the list of tags to be removed if specified in the RTE config
884 if (trim($this->thisConfig['removeTags'])) {
885 $configureRTEInJavascriptString .= '
886 RTEarea[editornumber]["htmlRemoveTags"] = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTags'], 1)) . ')$/i;';
887 }
888
889 // Setting the list of tags to be removed with their contents if specified in the RTE config
890 if (trim($this->thisConfig['removeTagsAndContents'])) {
891 $configureRTEInJavascriptString .= '
892 RTEarea[editornumber]["htmlRemoveTagsAndContents"] = /^(' . implode('|', t3lib_div::trimExplode(',', $this->thisConfig['removeTagsAndContents'], 1)) . ')$/i;';
893 }
894
895 // Process default style configuration
896 $configureRTEInJavascriptString .= '
897 RTEarea[editornumber].defaultPageStyle = "' . $this->hostURL . $this->writeTemporaryFile('', 'defaultPageStyle', 'css', $this->buildStyleSheet()) . '";';
898
899 // Setting the pageStyle
900 $filename = trim($this->thisConfig['contentCSS']) ? trim($this->thisConfig['contentCSS']) : 'EXT:' . $this->ID . '/res/contentcss/default.css';
901 $configureRTEInJavascriptString .= '
902 RTEarea[editornumber].pageStyle = "' . $this->getFullFileName($filename) .'";';
903
904 // Process classes configuration
905 $classesConfigurationRequired = false;
906 foreach ($this->registeredPlugins as $pluginId => $plugin) {
907 if ($this->isPluginEnabled($pluginId)) {
908 $classesConfigurationRequired = $classesConfigurationRequired || $plugin->requiresClassesConfiguration();
909 }
910 }
911 if ($classesConfigurationRequired) {
912 $configureRTEInJavascriptString .= $this->buildJSClassesConfig($RTEcounter);
913 }
914
915 // Add Javascript configuration for registered plugins
916 foreach ($this->registeredPlugins as $pluginId => $plugin) {
917 if ($this->isPluginEnabled($pluginId)) {
918 $configureRTEInJavascriptString .= $plugin->buildJavascriptConfiguration('editornumber');
919 }
920 }
921
922 $configureRTEInJavascriptString .= '
923 RTEarea[editornumber].toolbar = ' . $this->getJSToolbarArray() . ';
924 RTEarea[editornumber].convertButtonId = ' . t3lib_div::array2json(array_flip($this->convertToolbarForHtmlAreaArray)) .';
925 HTMLArea.initEditor(editornumber);' . (!$this->is_FE() ? '' : '
926 /*]]>*/');
927 return $configureRTEInJavascriptString;
928 }
929
930 /**
931 * Return true, if the plugin can be loaded
932 *
933 * @param string $pluginId: The identification string of the plugin
934 *
935 * @return boolean true if the plugin can be loaded
936 */
937
938 function isPluginEnabled($pluginId) {
939 return in_array($pluginId, $this->pluginEnabledArray);
940 }
941
942 /**
943 * Build the default content style sheet
944 *
945 * @return string Style sheet
946 */
947 function buildStyleSheet() {
948
949 if (!trim($this->thisConfig['ignoreMainStyleOverride'])) {
950 $mainStyle_font = $this->thisConfig['mainStyle_font'] ? $this->thisConfig['mainStyle_font']: 'Verdana,sans-serif';
951
952 $mainElements = array();
953 $mainElements['P'] = $this->thisConfig['mainStyleOverride_add.']['P'];
954 $elList = explode(',','H1,H2,H3,H4,H5,H6,PRE');
955 foreach ($elList as $elListName) {
956 if ($this->thisConfig['mainStyleOverride_add.'][$elListName]) {
957 $mainElements[$elListName] = $this->thisConfig['mainStyleOverride_add.'][$elListName];
958 }
959 }
960
961 $addElementCode = '';
962 foreach ($mainElements as $elListName => $elValue) {
963 $addElementCode .= strToLower($elListName) . ' {' . $elValue . '}' . chr(10);
964 }
965
966 $stylesheet = $this->thisConfig['mainStyleOverride'] ? $this->thisConfig['mainStyleOverride'] : chr(10) .
967 'body.htmlarea-content-body { font-family: ' . $mainStyle_font .
968 '; font-size: '.($this->thisConfig['mainStyle_size'] ? $this->thisConfig['mainStyle_size'] : '12px') .
969 '; color: '.($this->thisConfig['mainStyle_color']?$this->thisConfig['mainStyle_color'] : 'black') .
970 '; background-color: '.($this->thisConfig['mainStyle_bgcolor'] ? $this->thisConfig['mainStyle_bgcolor'] : 'white') .
971 ';'.$this->thisConfig['mainStyleOverride_add.']['BODY'].'}' . chr(10) .
972 'td { ' . $this->thisConfig['mainStyleOverride_add.']['TD'].'}' . chr(10) .
973 'div { ' . $this->thisConfig['mainStyleOverride_add.']['DIV'].'}' . chr(10) .
974 'pre { ' . $this->thisConfig['mainStyleOverride_add.']['PRE'].'}' . chr(10) .
975 'ol { ' . $this->thisConfig['mainStyleOverride_add.']['OL'].'}' . chr(10) .
976 'ul { ' . $this->thisConfig['mainStyleOverride_add.']['UL'].'}' . chr(10) .
977 'blockquote { ' . $this->thisConfig['mainStyleOverride_add.']['BLOCKQUOTE'].'}' . chr(10) .
978 $addElementCode;
979
980 if (is_array($this->thisConfig['inlineStyle.'])) {
981 $stylesheet .= chr(10) . implode(chr(10), $this->thisConfig['inlineStyle.']) . chr(10);
982 }
983 } else {
984 $stylesheet = '/* mainStyleOverride and inlineStyle properties ignored. */';
985 }
986 return $stylesheet;
987 }
988
989 /**
990 * Return Javascript configuration of classes
991 *
992 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
993 *
994 * @return string Javascript configuration of classes
995 */
996 function buildJSClassesConfig($RTEcounter) {
997 // Build JS array of lists of classes
998 $classesTagList = 'classesCharacter, classesParagraph, classesImage, classesTable, classesLinks, classesTD';
999 $classesTagConvert = array( 'classesCharacter' => 'span', 'classesParagraph' => 'div', 'classesImage' => 'img', 'classesTable' => 'table', 'classesLinks' => 'a', 'classesTD' => 'td');
1000 $classesTagArray = t3lib_div::trimExplode(',' , $classesTagList);
1001 $configureRTEInJavascriptString = '
1002 RTEarea[editornumber]["classesTag"] = new Object();';
1003 foreach ($classesTagArray as $classesTagName) {
1004 $HTMLAreaJSClasses = ($this->thisConfig[$classesTagName])?('"' . $this->cleanList($this->thisConfig[$classesTagName]) . '";'):'null;';
1005 $configureRTEInJavascriptString .= '
1006 RTEarea[editornumber]["classesTag"]["'. $classesTagConvert[$classesTagName] .'"] = '. $HTMLAreaJSClasses;
1007 }
1008
1009 // Include JS arrays of configured classes
1010 $configureRTEInJavascriptString .= '
1011 RTEarea[editornumber]["classesUrl"] = "' . $this->hostURL . $this->writeTemporaryFile('', 'classes_'.$LANG->lang, 'js', $this->buildJSClassesArray()) . '";';
1012
1013 return $configureRTEInJavascriptString;
1014 }
1015
1016 /**
1017 * Return JS arrays of classes labels and noShow flags
1018 *
1019 * @return string JS classes arrays
1020 */
1021 function buildJSClassesArray() {
1022 global $TSFE, $LANG, $TYPO3_CONF_VARS;
1023
1024 if ($this->is_FE()) {
1025 $RTEProperties = $this->RTEsetup;
1026 } else {
1027 $RTEProperties = $this->RTEsetup['properties'];
1028 }
1029
1030 $linebreak = $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] ? '' : chr(10);
1031 $index = 0;
1032 $indexNoShow = 0;
1033 $indexAlternating = 0;
1034 $indexCounting = 0;
1035 $JSClassesLabelsArray = 'HTMLArea.classesLabels = { ' . $linebreak;
1036 $JSClassesValuesArray = 'HTMLArea.classesValues = { ' . $linebreak;
1037 $JSClassesNoShowArray = 'HTMLArea.classesNoShow = { ' . $linebreak;
1038 $JSClassesAlternatingArray = 'HTMLArea.classesAlternating = { ' . $linebreak;
1039 $JSClassesCountingArray = 'HTMLArea.classesCounting = { ' . $linebreak;
1040 $JSClassesXORArray = 'HTMLArea.classesXOR = { ' . $linebreak;
1041
1042 // Scanning the list of classes if specified in the RTE config
1043 if (is_array($RTEProperties['classes.'])) {
1044 foreach ($RTEProperties['classes.'] as $className => $conf) {
1045 $className = substr($className,0,-1);
1046 $classLabel = $this->getPageConfigLabel($conf['name']);
1047 $JSClassesLabelsArray .= ($index?',':'') . '"' . $className . '": ' . $classLabel . $linebreak;
1048 $JSClassesValuesArray .= ($index?',':'') . '"' . $className . '":"' . str_replace('"', '\"', str_replace('\\\'', '\'', $conf['value'])) . '"' . $linebreak;
1049 if ($conf['noShow']) {
1050 $JSClassesNoShowArray .= ($indexNoShow?',':'') . '"' . $className . '":' . ($conf['noShow']?'true':'false') . $linebreak;
1051 $indexNoShow++;
1052 }
1053 if (is_array($conf['alternating.'])) {
1054 $JSClassesAlternatingArray .= ($indexAlternating?',':'') . '"' . $className . '":' . (is_array($conf['alternating.']) ? $this->buildNestedJSArray($conf['alternating.']) : ' "false"') . $linebreak;
1055 $indexAlternating++;
1056 }
1057 if (is_array($conf['counting.'])) {
1058 $JSClassesCountingArray .= ($indexCounting?',':'') . '"' . $className . '":' . (is_array($conf['counting.']) ? $this->buildNestedJSArray($conf['counting.']) : ' "false"') . $linebreak;
1059 $indexCounting++;
1060 }
1061 $index++;
1062 }
1063 }
1064 // Scanning the list of sets of mutually exclusives classes if specified in the RTE config
1065 $index = 0;
1066 if (is_array($RTEProperties['mutuallyExclusiveClasses.'])) {
1067 foreach ($RTEProperties['mutuallyExclusiveClasses.'] as $listName => $conf) {
1068 $classArray = t3lib_div::trimExplode(',', $conf, 1);
1069 $classList = implode(',', $classArray);
1070 foreach ($classArray as $className) {
1071 $JSClassesXORArray .= ($index?',':'') . '"' . $className . '": /^(' . implode('|', t3lib_div::trimExplode(',', t3lib_div::rmFromList($className, $classList), 1)) . ')$/i' . $linebreak;
1072 $index++;
1073 }
1074 }
1075 }
1076 $JSClassesLabelsArray .= '};' . $linebreak;
1077 $JSClassesValuesArray .= '};' . $linebreak;
1078 $JSClassesNoShowArray .= '};' . $linebreak;
1079 $JSClassesAlternatingArray .= '};' . $linebreak;
1080 $JSClassesCountingArray .= '};' . $linebreak;
1081 $JSClassesXORArray .= '};' . $linebreak;
1082
1083 return $JSClassesLabelsArray . $JSClassesValuesArray . $JSClassesNoShowArray . $JSClassesAlternatingArray . $JSClassesCountingArray . $JSClassesXORArray;
1084 }
1085
1086 /**
1087 * Translate Page TS Config array in JS nested array definition
1088 *
1089 * @param array $conf: Page TSConfig configuration array
1090 *
1091 * @return string nested JS array definition
1092 */
1093 function buildNestedJSArray($conf) {
1094 $configureRTEInJavascriptString = '{';
1095 $index = 0;
1096 if (is_array($conf)) {
1097 foreach ($conf as $propertyName => $conf1) {
1098 $property = $propertyName;
1099 if ($index) {
1100 $configureRTEInJavascriptString .= ', ';
1101 }
1102 if (is_array($conf1)) {
1103 $property = substr($property, 0, -1);
1104 $indexProperty = 0;
1105 $configureRTEInJavascriptString .= '"'.$property.'" : {';
1106 foreach ($conf1 as $property1Name => $conf2) {
1107 $property1 = $property1Name;
1108 if ($indexProperty) {
1109 $configureRTEInJavascriptString .= ', ';
1110 }
1111 if (is_array($conf2)) {
1112 $property1 = substr($property1, 0, -1);
1113 $indexProperty1 = 0;
1114 $configureRTEInJavascriptString .= '"'.$property1.'" : {';
1115 foreach ($conf2 as $property2Name => $conf3) {
1116 $property2 = $property2Name;
1117 if ($indexProperty1) {
1118 $configureRTEInJavascriptString .= ', ';
1119 }
1120 if (is_array($conf3)) {
1121 $property2 = substr($property2, 0, -1);
1122 $indexProperty2 = 0;
1123 $configureRTEInJavascriptString .= '"'.$property2.'" : {';
1124 foreach($conf3 as $property3Name => $conf4) {
1125 $property3 = $property3Name;
1126 if ($indexProperty2) {
1127 $configureRTEInJavascriptString .= ', ';
1128 }
1129 if (!is_array($conf4)) {
1130 $configureRTEInJavascriptString .= '"'.$property3.'" : '.($conf4?'"'.$conf4.'"':'false');
1131 }
1132 $indexProperty2++;
1133 }
1134 $configureRTEInJavascriptString .= '}';
1135 } else {
1136 $configureRTEInJavascriptString .= '"'.$property2.'" : '.($conf3?'"'.$conf3.'"':'false');
1137 }
1138 $indexProperty1++;
1139 }
1140 $configureRTEInJavascriptString .= '}';
1141 } else {
1142 $configureRTEInJavascriptString .= '"'.$property1.'" : '.($conf2?'"'.$conf2.'"':'false');
1143 }
1144 $indexProperty++;
1145 }
1146 $configureRTEInJavascriptString .= '}';
1147 } else {
1148 $configureRTEInJavascriptString .= '"'.$property.'" : '.($conf1?'"'.$conf1.'"':'false');
1149 }
1150 $index++;
1151 }
1152 }
1153 $configureRTEInJavascriptString .= '}';
1154 return $configureRTEInJavascriptString;
1155 }
1156
1157 /**
1158 * Return a Javascript localization array for htmlArea RTE
1159 *
1160 * @return string Javascript localization array
1161 */
1162 function buildJSMainLangArray() {
1163 global $TSFE, $LANG, $TYPO3_CONF_VARS;
1164
1165 $linebreak = $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] ? '' : chr(10);
1166 $JSLanguageArray .= 'var HTMLArea_langArray = new Object();' . $linebreak;
1167 $JSLanguageArray .= 'HTMLArea_langArray = { ' . $linebreak;
1168 $subArrays = array( 'tooltips', 'msg' , 'dialogs');
1169 $subArraysIndex = 0;
1170 foreach ($subArrays as $labels) {
1171 $JSLanguageArray .= (($subArraysIndex++)?',':'') . $labels . ': {' . $linebreak;
1172 if ($this->is_FE()) {
1173 $LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $this->ID . '/htmlarea/locallang_' . $labels . '.xml', $this->language, $this->OutputCharset);
1174 } else {
1175 $LOCAL_LANG = $LANG->readLLfile(t3lib_extMgm::extPath($this->ID).'htmlarea/locallang_' . $labels . '.xml');
1176 }
1177 if (!empty($LOCAL_LANG[$this->language])) {
1178 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'], $LOCAL_LANG[$this->language]);
1179 } else {
1180 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1181 }
1182 $index = 0;
1183 foreach ($LOCAL_LANG[$this->language] as $labelKey => $labelValue ) {
1184 $JSLanguageArray .= (($index++)?',':'') . '"' . $labelKey . '":"' . str_replace('"', '\"', $labelValue) . '"' . $linebreak;
1185 }
1186 $JSLanguageArray .= ' }' . chr(10);
1187 }
1188 $JSLanguageArray .= ' };' . chr(10);
1189 return $JSLanguageArray;
1190 }
1191
1192 /**
1193 * Writes contents in a file in typo3temp/rtehtmlarea directory and returns the file name
1194 *
1195 * @param string $sourceFileName: The name of the file from which the contents should be extracted
1196 * @param string $label: A label to insert at the beginning of the name of the file
1197 * @param string $fileExtension: The file extension of the file, defaulting to 'js'
1198 * @param string $contents: The contents to write into the file if no $sourceFileName is provided
1199 *
1200 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1201 */
1202 public function writeTemporaryFile($sourceFileName='', $label, $fileExtension='js', $contents='') {
1203 global $TYPO3_CONF_VARS;
1204
1205 if ($sourceFileName) {
1206 $output = '';
1207 $source = t3lib_div::getFileAbsFileName($sourceFileName);
1208 $output = file_get_contents($source);
1209 } else {
1210 $output = $contents;
1211 }
1212 $compress = $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] && ($fileExtension == 'js') && ($output != '');
1213 $relativeFilename = 'typo3temp/' . $this->ID . '/' . str_replace('-','_',$label) . '_' . t3lib_div::shortMD5(($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . ($sourceFileName?$sourceFileName:$output)), 20) . ($compress ? '_compressed' : '') . '.' . $fileExtension;
1214 $destination = PATH_site . $relativeFilename;
1215 if(!file_exists($destination)) {
1216 $compressedJavaScript = '';
1217 if ($compress) {
1218 $compressedJavaScript = t3lib_div::minifyJavaScript($output);
1219 }
1220 $failure = t3lib_div::writeFileToTypo3tempDir($destination, $compressedJavaScript?$compressedJavaScript:$output);
1221 if ($failure) {
1222 die($failure);
1223 }
1224 }
1225 return ($this->thisConfig['forceHTTPS']?$this->siteURL:$this->httpTypo3Path) . $relativeFilename;
1226 }
1227
1228 /**
1229 * Return a file name containing the main JS language array for HTMLArea
1230 *
1231 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1232 *
1233 * @return string filename
1234 */
1235
1236 function buildJSMainLangFile($RTEcounter) {
1237 $contents = $this->buildJSMainLangArray() . chr(10);
1238 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
1239 $contents .= $this->buildJSLangArray($pluginId) . chr(10);
1240 }
1241 return $this->writeTemporaryFile('', $this->language.'_'.$this->OutputCharset, 'js', $contents);
1242 }
1243
1244 /**
1245 * Return a Javascript localization array for the plugin
1246 *
1247 * @param string $plugin: identification string of the plugin
1248 *
1249 * @return string Javascript localization array
1250 */
1251
1252 function buildJSLangArray($plugin) {
1253 global $LANG, $TYPO3_CONF_VARS;
1254
1255 $extensionKey = is_object($this->registeredPlugins[$plugin]) ? $this->registeredPlugins[$plugin]->getExtensionKey() : $this->ID;
1256
1257 $linebreak = $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['enableCompressedScripts'] ? '' : chr(10);
1258 if($this->is_FE()) {
1259 $LOCAL_LANG = t3lib_div::readLLfile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $plugin . '/locallang.xml', $this->language, $this->OutputCharset);
1260 } else {
1261 $LOCAL_LANG = $LANG->readLLfile(t3lib_extMgm::extPath($extensionKey).'htmlarea/plugins/' . $plugin . '/locallang.xml');
1262 }
1263
1264 if (!empty($LOCAL_LANG[$this->language])) {
1265 $LOCAL_LANG[$this->language] = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG['default'],$LOCAL_LANG[$this->language]);
1266 } else {
1267 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1268 }
1269
1270 $JSLanguageArray .= 'var ' . $plugin . '_langArray = new Object();' . $linebreak;
1271 $JSLanguageArray .= $plugin . '_langArray = {' . $linebreak;
1272 $index = 0;
1273 foreach ($LOCAL_LANG[$this->language] as $labelKey => $labelValue ) {
1274 $JSLanguageArray .= (($index++)?',':'') . '"' . $labelKey . '":"' . str_replace('"', '\"', $labelValue) . '"' . $linebreak;
1275 }
1276 $JSLanguageArray .= ' };' . chr(10);
1277
1278 return $JSLanguageArray;
1279 }
1280
1281 /**
1282 * Return the JS-Code for the Toolbar-Config-Array for HTML-Area
1283 *
1284 * @return string the JS-Code as an JS-Array
1285 */
1286
1287 function getJSToolbarArray() {
1288 $toolbar = ''; // The JS-Code for the toolbar
1289 $group = ''; // The TS-Code for the group in the moment, each group are between "bar"s
1290 $group_has_button = false; // True if the group has any enabled buttons
1291 $group_needs_starting_bar = false;
1292 $previous_is_space = false;
1293
1294 // process each button in the order list
1295 foreach ($this->toolbarOrderArray as $button) {
1296 // check if a new group starts
1297 if (($button == 'bar' || $button == 'linebreak') && $group_has_button) {
1298 // New line
1299 if ($button == 'linebreak') {
1300 $convertButton = '"' . $this->convertToolbarForHTMLArea('linebreak') . '"';
1301 $group = ($group!='') ? ($group . ', ' . $convertButton) : $convertButton;
1302 }
1303 // New group
1304 $toolbar .= $toolbar ? (', ' . $group) : ('[[' . $group);
1305 $group = '';
1306 $previous_is_space = false;
1307 $group_has_button = false;
1308 $group_needs_starting_bar = true;
1309 } elseif ($toolbar && $button == 'linebreak' && !$group_has_button) {
1310 // Insert linebreak if no group is opened
1311 $group = '';
1312 $previous_is_space = false;
1313 $group_needs_starting_bar = false;
1314 $toolbar .= ', "' . $this->convertToolbarForHTMLArea($button) . '"';
1315 } elseif ($button == 'bar' && !$group_has_button) {
1316 $group_needs_starting_bar = true;
1317 } elseif ($button == 'space' && $group_has_button && !$previous_is_space) {
1318 $convertButton = $this->convertToolbarForHTMLArea($button);
1319 $convertButton = '"' . $convertButton . '"';
1320 $group .= $group ? (', ' . $convertButton) : ($group_needs_starting_bar ? ('"' . $this->convertToolbarForHTMLArea('bar') . '", ' . $convertButton) : $convertButton);
1321 $group_needs_starting_bar = false;
1322 $previous_is_space = true;
1323 } elseif (in_array($button, $this->toolbar)) {
1324 // Add the button to the group
1325 $convertButton = $this->convertToolbarForHTMLArea($button);
1326 if ($convertButton) {
1327 $convertButton = '"' . $convertButton . '"';
1328 $group .= $group ? (', ' . $convertButton) : ($group_needs_starting_bar ? ('"' . $this->convertToolbarForHTMLArea('bar') . '", ' . $convertButton) : $convertButton);
1329 $group_has_button = true;
1330 $group_needs_starting_bar = false;
1331 $previous_is_space = false;
1332 }
1333 }
1334 // else ignore
1335 }
1336 // add the last group
1337 if($group_has_button) $toolbar .= $toolbar ? (', ' . $group) : ('[[' . $group);
1338 $toolbar = $toolbar . ']]';
1339 return $toolbar;
1340 }
1341
1342 public function getLLContent($string) {
1343 global $LANG;
1344
1345 $BE_lang = $LANG->lang;
1346 $BE_charSet = $LANG->charSet;
1347 $LANG->lang = $this->contentTypo3Language;
1348 $LANG->charSet = $this->contentCharset;
1349 $LLString = $LANG->JScharCode($LANG->sL($string));
1350 $LANG->lang = $BE_lang;
1351 $LANG->charSet = $BE_charSet;
1352 return $LLString;
1353 }
1354
1355 public function getPageConfigLabel($string,$JScharCode=1) {
1356 global $LANG, $TSFE, $TYPO3_CONF_VARS;
1357
1358 if ($this->is_FE()) {
1359 if (strcmp(substr($string,0,4),'LLL:') && $TYPO3_CONF_VARS['BE']['forceCharset']) {
1360 // A pure string coming from Page TSConfig must be in forceCharset, otherwise we just don't know..
1361 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $TYPO3_CONF_VARS['BE']['forceCharset'], $this->OutputCharset);
1362 } else {
1363 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $this->charset, $this->OutputCharset);
1364 }
1365 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1366 $label = $JScharCode ? $this->feJScharCode($label) : $label;
1367 } else {
1368 if (strcmp(substr($string,0,4),'LLL:')) {
1369 $label = $string;
1370 } else {
1371 $label = $LANG->sL(trim($string));
1372 }
1373 $label = str_replace('"', '\"', str_replace('\\\'', '\'', $label));
1374 $label = $JScharCode ? $LANG->JScharCode($label): $label;
1375 }
1376 return $label;
1377 }
1378
1379 function feJScharCode($str) {
1380 global $TSFE;
1381 // Convert string to UTF-8:
1382 if ($this->OutputCharset != 'utf-8') $str = $TSFE->csConvObj->utf8_encode($str,$this->OutputCharset);
1383 // Convert the UTF-8 string into a array of char numbers:
1384 $nArr = $TSFE->csConvObj->utf8_to_numberarray($str);
1385 return 'String.fromCharCode('.implode(',',$nArr).')';
1386 }
1387
1388 public function getFullFileName($filename) {
1389 if (substr($filename,0,4)=='EXT:') { // extension
1390 list($extKey,$local) = explode('/',substr($filename,4),2);
1391 $newFilename = '';
1392 if (strcmp($extKey,'') && t3lib_extMgm::isLoaded($extKey) && strcmp($local,'')) {
1393 $newFilename = $this->siteURL . t3lib_extMgm::siteRelPath($extKey) . $local;
1394 }
1395 } elseif (substr($filename,0,1) != '/') {
1396 $newFilename = $this->siteURL . $filename;
1397 } else {
1398 $newFilename = $this->siteURL . substr($filename,1);
1399 }
1400 return $newFilename;
1401 }
1402
1403 /**
1404 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1405 * This is for submit function of the form.
1406 *
1407 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1408 * @param string $formName: the name of the form
1409 * @param string $textareaId: the id of the textarea
1410 *
1411 * @return string Javascript code
1412 */
1413 function setSaveRTE($RTEcounter, $formName, $textareaId) {
1414 return '
1415 rteFound = false;
1416 for (editornumber = 1; editornumber < RTEarea.length; editornumber++) {
1417 if (RTEarea[editornumber].textAreaId == "' . $textareaId . '") {
1418 if (!RTEarea[editornumber].deleted) {
1419 document.'.$formName.'["'.$textareaId.'"].value = RTEarea[editornumber]["editor"].getHTML();
1420 }
1421 rteFound = true;
1422 break;
1423 }
1424 }
1425 if (!rteFound) {
1426 OK = 0;
1427 }
1428 ';
1429 }
1430
1431 /**
1432 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1433 * This is for submit function of the form.
1434 *
1435 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1436 * @param string $formName: the name of the form
1437 * @param string $textareaId: the id of the textarea
1438 *
1439 * @return string Javascript code
1440 */
1441 function setDeleteRTE($RTEcounter, $formName, $textareaId) {
1442 return '
1443 for (editornumber = 1; editornumber < RTEarea.length; editornumber++) {
1444 if (RTEarea[editornumber].textAreaId == "' . $textareaId . '") {
1445 if (RTEarea[editornumber]) {
1446 RTEarea[editornumber].deleted = true;
1447 }
1448 }
1449 break;
1450 }
1451 ';
1452 }
1453
1454 /**
1455 * Return true if we are in the FE, but not in the FE editing feature of BE.
1456 *
1457 * @return boolean
1458 */
1459
1460 function is_FE() {
1461 global $TSFE;
1462 return is_object($TSFE) && is_array($this->LOCAL_LANG) && !strstr($this->elementId,'TSFE_EDIT');
1463 }
1464
1465 /**
1466 * Client Browser Information
1467 *
1468 * Usage: 4
1469 *
1470 * @param string Alternative User Agent string (if empty, t3lib_div::getIndpEnv('HTTP_USER_AGENT') is used)
1471 * @return array Parsed information about the HTTP_USER_AGENT in categories BROWSER, VERSION, SYSTEM and FORMSTYLE
1472 */
1473
1474 function clientInfo($useragent='') {
1475 global $TYPO3_CONF_VARS;
1476
1477 if (!$useragent) $useragent=t3lib_div::getIndpEnv('HTTP_USER_AGENT');
1478
1479 $bInfo=array();
1480 // Which browser?
1481 if (strstr($useragent,'Konqueror')) {
1482 $bInfo['BROWSER']= 'konqu';
1483 } elseif (strstr($useragent,'Opera')) {
1484 $bInfo['BROWSER']= 'opera';
1485 } elseif (strstr($useragent,'MSIE')) {
1486 $bInfo['BROWSER']= 'msie';
1487 } elseif (strstr($useragent,'Gecko/')) {
1488 $bInfo['BROWSER']='gecko';
1489 } elseif (strstr($useragent,'Safari/')) {
1490 $bInfo['BROWSER']='safari';
1491 } elseif (strstr($useragent,'Mozilla/4')) {
1492 $bInfo['BROWSER']='net';
1493 }
1494
1495 if ($bInfo['BROWSER']) {
1496 // Browser version
1497 switch($bInfo['BROWSER']) {
1498 case 'net':
1499 $bInfo['VERSION']= doubleval(substr($useragent,8));
1500 if (strstr($useragent,'Netscape6/')) {$bInfo['VERSION']=doubleval(substr(strstr($useragent,'Netscape6/'),10));}
1501 if (strstr($useragent,'Netscape/7')) {$bInfo['VERSION']=doubleval(substr(strstr($useragent,'Netscape/7'),9));}
1502 break;
1503 case 'gecko':
1504 $tmp = strstr($useragent,'rv:');
1505 $bInfo['VERSION'] = doubleval(ereg_replace('^[^0-9]*','',substr($tmp,3)));
1506 break;
1507 case 'msie':
1508 $tmp = strstr($useragent,'MSIE');
1509 $bInfo['VERSION'] = doubleval(ereg_replace('^[^0-9]*','',substr($tmp,4)));
1510 break;
1511 case 'safari':
1512 $tmp = strstr($useragent,'Safari/');
1513 $bInfo['VERSION'] = doubleval(ereg_replace('^[^0-9]*','',substr($tmp,3)));
1514 break;
1515 case 'opera':
1516 $tmp = strstr($useragent,'Opera');
1517 $bInfo['VERSION'] = doubleval(ereg_replace('^[^0-9]*','',substr($tmp,5)));
1518 break;
1519 case 'konqu':
1520 $tmp = strstr($useragent,'Konqueror/');
1521 $bInfo['VERSION'] = doubleval(substr($tmp,10));
1522 break;
1523 }
1524
1525 // Client system
1526 if (strstr($useragent,'Win')) {
1527 $bInfo['SYSTEM'] = 'win';
1528 } elseif (strstr($useragent,'Mac')) {
1529 $bInfo['SYSTEM'] = 'mac';
1530 } elseif (strstr($useragent,'Linux') || strstr($useragent,'X11') || strstr($useragent,'SGI') || strstr($useragent,' SunOS ') || strstr($useragent,' HP-UX ')) {
1531 $bInfo['SYSTEM'] = 'unix';
1532 }
1533 }
1534
1535 // Is true if the browser supports css to format forms, especially the width
1536 $bInfo['FORMSTYLE']=($bInfo['BROWSER']=='msie' || ($bInfo['BROWSER']=='net'&&$bInfo['VERSION']>=5) || $bInfo['BROWSER']=='opera' || $bInfo['BROWSER']=='konqu');
1537 return $bInfo;
1538 }
1539
1540 /***************************
1541 *
1542 * OTHER FUNCTIONS: (from Classic RTE)
1543 *
1544 ***************************/
1545 /**
1546 * @return [type] ...
1547 * @desc
1548 */
1549
1550 function RTEtsConfigParams() {
1551 if($this->is_FE()) {
1552 return '';
1553 } else {
1554 $p = t3lib_BEfunc::getSpecConfParametersFromArray($this->specConf['rte_transform']['parameters']);
1555 return $this->elementParts[0].':'.$this->elementParts[1].':'.$this->elementParts[2].':'.$this->thePid.':'.$this->typeVal.':'.$this->tscPID.':'.$p['imgpath'];
1556 }
1557 }
1558
1559 public function cleanList($str) {
1560 if (strstr($str,'*')) {
1561 $str = '*';
1562 } else {
1563 $str = implode(',',array_unique(t3lib_div::trimExplode(',',$str,1)));
1564 }
1565 return $str;
1566 }
1567
1568 function filterStyleEl($elValue,$matchList) {
1569 $matchParts = t3lib_div::trimExplode(',',$matchList,1);
1570 $styleParts = explode(';',$elValue);
1571 $nStyle=array();
1572 foreach ($styleParts as $k => $p) {
1573 $pp = t3lib_div::trimExplode(':',$p);
1574 if ($pp[0]&&$pp[1]) {
1575 foreach ($matchParts as $el) {
1576 $star=substr($el,-1)=='*';
1577 if (!strcmp($pp[0],$el) || ($star && t3lib_div::isFirstPartOfStr($pp[0],substr($el,0,-1)) )) {
1578 $nStyle[]=$pp[0].':'.$pp[1];
1579 } else unset($styleParts[$k]);
1580 }
1581 } else {
1582 unset($styleParts[$k]);
1583 }
1584 }
1585 return implode('; ',$nStyle);
1586 }
1587
1588 // Hook on lorem_ipsum extension to insert text into the RTE in wysiwyg mode
1589 function loremIpsumInsert($params) {
1590 return "
1591 if (typeof(lorem_ipsum) == 'function' && " . $params['element'] . ".tagName.toLowerCase() == 'textarea' ) lorem_ipsum(" . $params['element'] . ", lipsum_temp_strings[lipsum_temp_pointer]);
1592 ";
1593 }
1594 }
1595
1596 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']) {
1597 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/rtehtmlarea/class.tx_rtehtmlarea_base.php']);
1598 }
1599
1600 ?>