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