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