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