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