[BUGFIX] Enable the RTE with WebKit version 534 on iOS and Android
[Packages/TYPO3.CMS.git] / typo3 / sysext / rtehtmlarea / Classes / RteHtmlAreaBase.php
1 <?php
2 namespace TYPO3\CMS\Rtehtmlarea;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2004-2011 Kasper Skårhøj (kasper@typo3.com)
8 * (c) 2004-2011 Philipp Borgmann <philipp.borgmann@gmx.de>
9 * (c) 2004-2012 Stanislas Rolland <typo3(arobas)sjbr.ca>
10 * All rights reserved
11 *
12 * This script is part of the TYPO3 project. The TYPO3 project is
13 * free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * The GNU General Public License can be found at
19 * http://www.gnu.org/copyleft/gpl.html.
20 * A copy is found in the textfile GPL.txt and important notices to the license
21 * from the author is found in LICENSE.txt distributed with these scripts.
22 *
23 *
24 * This script is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * This copyright notice MUST APPEAR in all copies of the script!
30 ***************************************************************/
31 /**
32 * A RTE using the htmlArea editor
33 *
34 * @author Philipp Borgmann <philipp.borgmann@gmx.de>
35 * @author Stanislas Rolland <typo3(arobas)sjbr.ca>
36 */
37 class RteHtmlAreaBase extends \TYPO3\CMS\Backend\Rte\AbstractRte {
38
39 // Configuration of supported browsers
40 /**
41 * @todo Define visibility
42 */
43 public $conf_supported_browser = array(
44 'msie' => array(
45 array(
46 'version' => 6.0,
47 'system' => array(
48 'allowed' => array(
49 'winNT',
50 'win98',
51 'win95'
52 )
53 )
54 )
55 ),
56 'gecko' => array(
57 array(
58 'version' => 1.8
59 )
60 ),
61 'webkit' => array(
62 array(
63 'version' => 534
64 ),
65 array(
66 'version' => 523,
67 'system' => array(
68 'disallowed' => array(
69 'iOS',
70 'android'
71 )
72 )
73 )
74 ),
75 'opera' => array(
76 array(
77 'version' => 9.62,
78 'system' => array(
79 'disallowed' => array(
80 'iOS',
81 'android'
82 )
83 )
84 )
85 )
86 );
87
88 // Always hide these toolbar buttons (TYPO3 button name)
89 /**
90 * @todo Define visibility
91 */
92 public $conf_toolbar_hide = array(
93 'showhelp'
94 );
95
96 // The order of the toolbar: the name is the TYPO3-button name
97 /**
98 * @todo Define visibility
99 */
100 public $defaultToolbarOrder;
101
102 // Conversion array: TYPO3 button names to htmlArea button names
103 /**
104 * @todo Define visibility
105 */
106 public $convertToolbarForHtmlAreaArray = array(
107 'showhelp' => 'ShowHelp',
108 'space' => 'space',
109 'bar' => 'separator',
110 'linebreak' => 'linebreak'
111 );
112
113 /**
114 * @todo Define visibility
115 */
116 public $pluginButton = array();
117
118 /**
119 * @todo Define visibility
120 */
121 public $pluginLabel = array();
122
123 // Alternative style for RTE <div> tag.
124 public $RTEdivStyle;
125
126 // Relative path to this extension. It ends with "/"
127 public $extHttpPath;
128
129 public $backPath = '';
130
131 // TYPO3 site url
132 public $siteURL;
133
134 // TYPO3 host url
135 public $hostURL;
136
137 // Typo3 version
138 public $typoVersion;
139
140 // Identifies the RTE as being the one from the "rtehtmlarea" extension if any external code needs to know
141 /**
142 * @todo Define visibility
143 */
144 public $ID = 'rtehtmlarea';
145
146 // If set, the content goes into a regular TEXT area field - for developing testing of transformations.
147 /**
148 * @todo Define visibility
149 */
150 public $debugMode = FALSE;
151
152 // For the editor
153 /**
154 * @todo Define visibility
155 */
156 public $client;
157
158 /**
159 * Reference to parent object, which is an instance of the TCEforms
160 *
161 * @var \TYPO3\CMS\Backend\Form\FormEngine
162 * @todo Define visibility
163 */
164 public $TCEform;
165
166 /**
167 * @todo Define visibility
168 */
169 public $elementId;
170
171 /**
172 * @todo Define visibility
173 */
174 public $elementParts;
175
176 /**
177 * @todo Define visibility
178 */
179 public $tscPID;
180
181 /**
182 * @todo Define visibility
183 */
184 public $typeVal;
185
186 /**
187 * @todo Define visibility
188 */
189 public $thePid;
190
191 /**
192 * @todo Define visibility
193 */
194 public $RTEsetup;
195
196 /**
197 * @todo Define visibility
198 */
199 public $thisConfig;
200
201 /**
202 * @todo Define visibility
203 */
204 public $confValues;
205
206 public $language;
207 /**
208 * TYPO3 language code of the content language
209 */
210 public $contentTypo3Language;
211 /**
212 * ISO language code of the content language
213 */
214 public $contentISOLanguage;
215 /**
216 * Language service object for localization to the content language
217 */
218 protected $contentLanguageService;
219 public $charset = 'utf-8';
220
221 public $contentCharset = 'utf-8';
222
223 public $OutputCharset = 'utf-8';
224
225 /**
226 * @todo Define visibility
227 */
228 public $editorCSS;
229
230 /**
231 * @todo Define visibility
232 */
233 public $specConf;
234
235 /**
236 * @todo Define visibility
237 */
238 public $toolbar = array();
239
240 // Save the buttons for the toolbar
241 /**
242 * @todo Define visibility
243 */
244 public $toolbarOrderArray = array();
245
246 protected $pluginEnabledArray = array();
247
248 // Array of plugin id's enabled in the current RTE editing area
249 protected $pluginEnabledCumulativeArray = array();
250
251 // Cumulative array of plugin id's enabled so far in any of the RTE editing areas of the form
252 public $registeredPlugins = array();
253
254 // Array of registered plugins indexed by their plugin Id's
255 protected $fullScreen = FALSE;
256 // Page renderer object
257 protected $pageRenderer;
258
259 /**
260 * Returns TRUE if the RTE is available. Here you check if the browser requirements are met.
261 * If there are reasons why the RTE cannot be displayed you simply enter them as text in ->errorLog
262 *
263 * @return boolean TRUE if this RTE object offers an RTE in the current browser environment
264 * @todo Define visibility
265 */
266 public function isAvailable() {
267 $this->client = $this->clientInfo();
268 $this->errorLog = array();
269 if (!$this->debugMode) {
270 // If debug-mode, let any browser through
271 $rteIsAvailable = FALSE;
272 $rteConfBrowser = $this->conf_supported_browser;
273 if (is_array($rteConfBrowser)) {
274 foreach ($rteConfBrowser as $browser => $browserConf) {
275 if ($browser == $this->client['browser']) {
276 // Config for Browser found, check it:
277 if (is_array($browserConf)) {
278 foreach ($browserConf as $browserConfSub) {
279 if ($browserConfSub['version'] <= $this->client['version'] || empty($browserConfSub['version'])) {
280 // Version is supported
281 if (is_array($browserConfSub['system'])) {
282 // Check against allowed systems
283 if (is_array($browserConfSub['system']['allowed'])) {
284 foreach ($browserConfSub['system']['allowed'] as $system) {
285 if (in_array($system, $this->client['all_systems'])) {
286 $rteIsAvailable = TRUE;
287 break;
288 }
289 }
290 } else {
291 // All allowed
292 $rteIsAvailable = TRUE;
293 }
294 // Check against disallowed systems
295 if (is_array($browserConfSub['system']['disallowed'])) {
296 foreach ($browserConfSub['system']['disallowed'] as $system) {
297 if (in_array($system, $this->client['all_systems'])) {
298 $rteIsAvailable = FALSE;
299 break;
300 }
301 }
302 }
303 } else {
304 // No system config: system is supported
305 $rteIsAvailable = TRUE;
306 break;
307 }
308 }
309 }
310 } else {
311 // no config for this browser found, so all versions or system with this browsers are allow
312 $rteIsAvailable = TRUE;
313 break;
314 }
315 }
316 }
317 } else {
318
319 }
320 if (!$rteIsAvailable) {
321 $this->errorLog[] = 'RTE: Browser not supported.';
322 }
323 if (\TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version) < 4000000) {
324 $rteIsAvailable = FALSE;
325 $this->errorLog[] = 'rte: This version of htmlArea RTE cannot run under this version of TYPO3.';
326 }
327 }
328 return $rteIsAvailable;
329 }
330
331 /**
332 * Draws the RTE as an iframe
333 *
334 * @param object Reference to parent object, which is an instance of the TCEforms.
335 * @param string The table name
336 * @param string The field name
337 * @param array The current row from which field is being rendered
338 * @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.
339 * @param array "special" configuration - what is found at position 4 in the types configuration of a field from record, parsed into an array.
340 * @param array Configuration for RTEs; A mix between TSconfig and otherwise. Contains configuration for display, which buttons are enabled, additional transformation information etc.
341 * @param string Record "type" field value.
342 * @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!
343 * @param integer PID value of record (true parent page id)
344 * @return string HTML code for RTE!
345 * @todo Define visibility
346 */
347 public function drawRTE(&$parentObject, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue) {
348 global $LANG, $TYPO3_DB, $TYPO3_CONF_VARS;
349 $this->TCEform = $parentObject;
350 $inline = $this->TCEform->inline;
351 $LANG->includeLLFile('EXT:' . $this->ID . '/locallang.xml');
352 $this->client = $this->clientInfo();
353 $this->typoVersion = \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger(TYPO3_version);
354 $this->userUid = 'BE_' . $GLOBALS['BE_USER']->user['uid'];
355 // Draw form element:
356 if ($this->debugMode) {
357 // Draws regular text area (debug mode)
358 $item = parent::drawRTE($this->TCEform, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue);
359 } else {
360 // Draw real RTE
361 /* =======================================
362 * INIT THE EDITOR-SETTINGS
363 * =======================================
364 */
365 // Set backPath
366 $this->backPath = $this->TCEform->backPath;
367 // Get the path to this extension:
368 $this->extHttpPath = $this->backPath . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($this->ID);
369 // Get the site URL
370 $this->siteURL = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
371 // Get the host URL
372 $this->hostURL = $this->siteURL . TYPO3_mainDir;
373 // Element ID + pid
374 $this->elementId = $PA['itemFormElName'];
375 // Form element name
376 $this->elementParts = explode('][', preg_replace('/\\]$/', '', preg_replace('/^(TSFE_EDIT\\[data\\]\\[|data\\[)/', '', $this->elementId)));
377 // Find the page PIDs:
378 list($this->tscPID, $this->thePid) = \TYPO3\CMS\Backend\Utility\BackendUtility::getTSCpid(trim($this->elementParts[0]), trim($this->elementParts[1]), $thePidValue);
379 // Record "types" field value:
380 $this->typeVal = $RTEtypeVal;
381 // TCA "types" value for record
382 // Find "thisConfig" for record/editor:
383 unset($this->RTEsetup);
384 $this->RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE', \TYPO3\CMS\Backend\Utility\BackendUtility::getPagesTSconfig($this->tscPID));
385 $this->thisConfig = $thisConfig;
386 // Special configuration and default extras:
387 $this->specConf = $specConf;
388 if ($this->thisConfig['forceHTTPS']) {
389 $this->extHttpPath = preg_replace('/^(http|https)/', 'https', $this->extHttpPath);
390 $this->siteURL = preg_replace('/^(http|https)/', 'https', $this->siteURL);
391 $this->hostURL = preg_replace('/^(http|https)/', 'https', $this->hostURL);
392 }
393 // Register RTE windows
394 $this->TCEform->RTEwindows[] = $PA['itemFormElName'];
395 $textAreaId = preg_replace('/[^a-zA-Z0-9_:.-]/', '_', $PA['itemFormElName']);
396 $textAreaId = htmlspecialchars(preg_replace('/^[^a-zA-Z]/', 'x', $textAreaId));
397 /* =======================================
398 * LANGUAGES & CHARACTER SETS
399 * =======================================
400 */
401 // Languages: interface and content
402 $this->language = $LANG->lang;
403 if ($this->language == 'default' || !$this->language) {
404 $this->language = 'en';
405 }
406 $this->contentTypo3Language = $this->language == 'en' ? 'default' : $this->language;
407 $this->contentISOLanguage = 'en';
408 $this->contentLanguageUid = $row['sys_language_uid'] > 0 ? $row['sys_language_uid'] : 0;
409 if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('static_info_tables')) {
410 if ($this->contentLanguageUid) {
411 $tableA = 'sys_language';
412 $tableB = 'static_languages';
413 $languagesUidsList = $this->contentLanguageUid;
414 $selectFields = $tableA . '.uid,' . $tableB . '.lg_iso_2,' . $tableB . '.lg_country_iso_2,' . $tableB . '.lg_typo3';
415 $tableAB = $tableA . ' LEFT JOIN ' . $tableB . ' ON ' . $tableA . '.static_lang_isocode=' . $tableB . '.uid';
416 $whereClause = $tableA . '.uid IN (' . $languagesUidsList . ') ';
417 $whereClause .= \TYPO3\CMS\Backend\Utility\BackendUtility::BEenableFields($tableA);
418 $whereClause .= \TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause($tableA);
419 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
420 while ($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
421 $this->contentISOLanguage = strtolower(trim($languageRow['lg_iso_2']) . (trim($languageRow['lg_country_iso_2']) ? '_' . trim($languageRow['lg_country_iso_2']) : ''));
422 $this->contentTypo3Language = trim($languageRow['lg_typo3']) ? strtolower(trim($languageRow['lg_typo3'])) : 'default';
423 }
424 } else {
425 $this->contentISOLanguage = trim($this->thisConfig['defaultContentLanguage']) ? trim($this->thisConfig['defaultContentLanguage']) : 'en';
426 $selectFields = 'lg_iso_2, lg_typo3';
427 $tableAB = 'static_languages';
428 $whereClause = 'lg_iso_2 = ' . $TYPO3_DB->fullQuoteStr(strtoupper($this->contentISOLanguage), $tableAB);
429 $res = $TYPO3_DB->exec_SELECTquery($selectFields, $tableAB, $whereClause);
430 while ($languageRow = $TYPO3_DB->sql_fetch_assoc($res)) {
431 $this->contentTypo3Language = trim($languageRow['lg_typo3']) ? strtolower(trim($languageRow['lg_typo3'])) : 'default';
432 }
433 }
434 }
435 // Create content laguage service
436 $this->contentLanguageService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Lang\\LanguageService');
437 $this->contentLanguageService->init($this->contentTypo3Language);
438 /* =======================================
439 * TOOLBAR CONFIGURATION
440 * =======================================
441 */
442 $this->initializeToolbarConfiguration();
443 /* =======================================
444 * SET STYLES
445 * =======================================
446 */
447 // Check if wizard_rte called this for fullscreen edtition
448 if (basename(PATH_thisScript) == 'wizard_rte.php') {
449 $this->fullScreen = TRUE;
450 $RTEWidth = '100%';
451 $RTEHeight = '100%';
452 $RTEPaddingRight = '0';
453 $editorWrapWidth = '100%';
454 } else {
455 $RTEWidth = isset($GLOBALS['BE_USER']->userTS['options.']['RTESmallWidth']) ? $GLOBALS['BE_USER']->userTS['options.']['RTESmallWidth'] : '530';
456 $RTEHeight = isset($GLOBALS['BE_USER']->userTS['options.']['RTESmallHeight']) ? $GLOBALS['BE_USER']->userTS['options.']['RTESmallHeight'] : '380';
457 $RTEWidth = $RTEWidth + ($this->TCEform->docLarge ? (isset($GLOBALS['BE_USER']->userTS['options.']['RTELargeWidthIncrement']) ? $GLOBALS['BE_USER']->userTS['options.']['RTELargeWidthIncrement'] : '150') : 0);
458 $RTEWidth -= $inline->getStructureDepth() > 0 ? ($inline->getStructureDepth() + 1) * $inline->getLevelMargin() : 0;
459 $RTEWidthOverride = is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteWidth']) && trim($GLOBALS['BE_USER']->uc['rteWidth']) ? trim($GLOBALS['BE_USER']->uc['rteWidth']) : trim($this->thisConfig['RTEWidthOverride']);
460 if ($RTEWidthOverride) {
461 if (strstr($RTEWidthOverride, '%')) {
462 if ($this->client['browser'] != 'msie') {
463 $RTEWidth = intval($RTEWidthOverride) > 0 ? $RTEWidthOverride : '100%';
464 }
465 } else {
466 $RTEWidth = intval($RTEWidthOverride) > 0 ? intval($RTEWidthOverride) : $RTEWidth;
467 }
468 }
469 $RTEWidth = strstr($RTEWidth, '%') ? $RTEWidth : $RTEWidth . 'px';
470 $RTEHeight = $RTEHeight + ($this->TCEform->docLarge ? (isset($GLOBALS['BE_USER']->userTS['options.']['RTELargeHeightIncrement']) ? $GLOBALS['BE_USER']->userTS['options.']['RTELargeHeightIncrement'] : 0) : 0);
471 $RTEHeightOverride = is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteHeight']) && intval($GLOBALS['BE_USER']->uc['rteHeight']) ? intval($GLOBALS['BE_USER']->uc['rteHeight']) : intval($this->thisConfig['RTEHeightOverride']);
472 $RTEHeight = $RTEHeightOverride > 0 ? $RTEHeightOverride : $RTEHeight;
473 $RTEPaddingRight = '2px';
474 $editorWrapWidth = '99%';
475 }
476 $editorWrapHeight = '100%';
477 $this->RTEdivStyle = 'position:relative; left:0px; top:0px; height:' . $RTEHeight . 'px; width:' . $RTEWidth . '; border: 1px solid black; padding: 2px ' . $RTEPaddingRight . ' 2px 2px;';
478 /* =======================================
479 * LOAD CSS AND JAVASCRIPT
480 * =======================================
481 */
482 $this->pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
483 // Preloading the pageStyle and including RTE skin stylesheets
484 $this->addPageStyle();
485 $this->addSkin();
486 // Register RTE in JS
487 $this->TCEform->additionalJS_post[] = $this->registerRTEinJS($this->TCEform->RTEcounter, $table, $row['uid'], $field, $textAreaId);
488 // Set the save option for the RTE
489 $this->TCEform->additionalJS_submit[] = $this->setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId, $PA['itemFormElName']);
490 $this->TCEform->additionalJS_delete[] = $this->setDeleteRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
491 // Loading ExtJs inline code
492 $this->pageRenderer->enableExtJSQuickTips();
493 // Add TYPO3 notifications JavaScript
494 $this->pageRenderer->addJsFile('../t3lib/js/extjs/notifications.js');
495 // Add RTE JavaScript
496 $this->addRteJsFiles($this->TCEform->RTEcounter);
497 $this->pageRenderer->addJsFile($this->buildJSMainLangFile($this->TCEform->RTEcounter));
498 $this->pageRenderer->addJsInlineCode('HTMLArea-init', $this->getRteInitJsCode(), TRUE);
499 /* =======================================
500 * DRAW THE EDITOR
501 * =======================================
502 */
503 // Transform value:
504 $value = $this->transformContent('rte', $PA['itemFormElValue'], $table, $field, $row, $specConf, $thisConfig, $RTErelPath, $thePidValue);
505 // Further content transformation by registered plugins
506 foreach ($this->registeredPlugins as $pluginId => $plugin) {
507 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, 'transformContent')) {
508 $value = $plugin->transformContent($value);
509 }
510 }
511 // Draw the textarea
512 $visibility = 'hidden';
513 $item = $this->triggerField($PA['itemFormElName']) . '
514 <div id="pleasewait' . $textAreaId . '" class="pleasewait" style="display: block;" >' . $LANG->getLL('Please wait') . '</div>
515 <div id="editorWrap' . $textAreaId . '" class="editorWrap" style="visibility: hidden; width:' . $editorWrapWidth . '; height:' . $editorWrapHeight . ';">
516 <textarea id="RTEarea' . $textAreaId . '" name="' . htmlspecialchars($PA['itemFormElName']) . '" rows="0" cols="0" style="' . \TYPO3\CMS\Core\Utility\GeneralUtility::deHSCentities(htmlspecialchars($this->RTEdivStyle)) . '">' . \TYPO3\CMS\Core\Utility\GeneralUtility::formatForTextarea($value) . '</textarea>
517 </div>' . LF;
518 }
519 // Return form item:
520 return $item;
521 }
522
523 /**
524 * Add link to content style sheet to document header
525 *
526 * @return void
527 */
528 protected function addPageStyle() {
529 $this->addStyleSheet('rtehtmlarea-page-style', $this->getContentCssFileName(), 'htmlArea RTE Content CSS', 'alternate stylesheet');
530 }
531
532 /**
533 * Get the name of the contentCSS file to use
534 *
535 * @return the full file name of the content css file to use
536 */
537 protected function getContentCssFileName() {
538 // Get stylesheet file name from Page TSConfig if any
539 $fileName = trim($this->thisConfig['contentCSS']);
540 if ($fileName) {
541 $fileName = $this->getFullFileName($fileName);
542 }
543 $absolutePath = $fileName ? \TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath(PATH_site . ($this->is_FE() || $this->isFrontendEditActive() ? '' : TYPO3_mainDir) . $fileName) : '';
544 // Fallback to default content css file if configured file does not exists or is of zero size
545 if (!$fileName || !file_exists($absolutePath) || !filesize($absolutePath)) {
546 $fileName = $this->getFullFileName('EXT:' . $this->ID . '/res/contentcss/default.css');
547 }
548 return $fileName;
549 }
550
551 /**
552 * Add links to skin style sheet(s) to document header
553 *
554 * @return void
555 */
556 protected function addSkin() {
557 // Get skin file name from Page TSConfig if any
558 $skinFilename = trim($this->thisConfig['skin']) ? trim($this->thisConfig['skin']) : 'EXT:' . $this->ID . '/htmlarea/skins/default/htmlarea.css';
559 $this->editorCSS = $this->getFullFileName($skinFilename);
560 $skinDir = dirname($this->editorCSS);
561 // Editing area style sheet
562 $this->editedContentCSS = $skinDir . '/htmlarea-edited-content.css';
563 $this->addStyleSheet('rtehtmlarea-editing-area-skin', $this->editedContentCSS);
564 // Main skin
565 $this->addStyleSheet('rtehtmlarea-skin', $this->editorCSS);
566 // Additional icons from registered plugins
567 foreach ($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] as $pluginId) {
568 if (is_object($this->registeredPlugins[$pluginId])) {
569 $pathToSkin = $this->registeredPlugins[$pluginId]->getPathToSkin();
570 if ($pathToSkin) {
571 $key = $this->registeredPlugins[$pluginId]->getExtensionKey();
572 $this->addStyleSheet('rtehtmlarea-plugin-' . $pluginId . '-skin', ($this->is_FE() ? \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($key) : $this->backPath . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($key)) . $pathToSkin);
573 }
574 }
575 }
576 }
577
578 /**
579 * Add style sheet file to document header
580 *
581 * @param string $key: some key identifying the style sheet
582 * @param string $href: uri to the style sheet file
583 * @param string $title: value for the title attribute of the link element
584 * @param string $relation: value for the rel attribute of the link element
585 * @return void
586 */
587 protected function addStyleSheet($key, $href, $title = '', $relation = 'stylesheet') {
588 // 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
589 if (is_object($this->TCEform->inline) && $this->TCEform->inline->isAjaxCall) {
590 $this->TCEform->additionalCode_pre[$key] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '" title="' . $title . '" />';
591 } else {
592 $this->pageRenderer->addCssFile($href, $relation, 'screen', $title);
593 }
594 }
595
596 /**
597 * Initialize toolbar configuration and enable registered plugins
598 *
599 * @return void
600 */
601 protected function initializeToolbarConfiguration() {
602 // Enable registred plugins
603 $this->enableRegisteredPlugins();
604 // Configure toolbar
605 $this->setToolbar();
606 // Check if some plugins need to be disabled
607 $this->setPlugins();
608 // Merge the list of enabled plugins with the lists from the previous RTE editing areas on the same form
609 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = $this->pluginEnabledArray;
610 if ($this->TCEform->RTEcounter > 1 && isset($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter - 1]) && is_array($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter - 1])) {
611 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = array_unique(array_values(array_merge($this->pluginEnabledArray, $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter - 1])));
612 }
613 }
614
615 /**
616 * Add registered plugins to the array of enabled plugins
617 *
618 * @todo Define visibility
619 */
620 public function enableRegisteredPlugins() {
621 global $TYPO3_CONF_VARS;
622 // Traverse registered plugins
623 if (is_array($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'])) {
624 foreach ($TYPO3_CONF_VARS['EXTCONF'][$this->ID]['plugins'] as $pluginId => $pluginObjectConfiguration) {
625 $plugin = FALSE;
626 if (is_array($pluginObjectConfiguration) && count($pluginObjectConfiguration)) {
627 $plugin = \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($pluginObjectConfiguration['objectReference']);
628 }
629 if (is_object($plugin)) {
630 if ($plugin->main($this)) {
631 $this->registeredPlugins[$pluginId] = $plugin;
632 // Override buttons from previously registered plugins
633 $pluginButtons = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $plugin->getPluginButtons(), 1);
634 foreach ($this->pluginButton as $previousPluginId => $buttonList) {
635 $this->pluginButton[$previousPluginId] = implode(',', array_diff(\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->pluginButton[$previousPluginId], 1), $pluginButtons));
636 }
637 $this->pluginButton[$pluginId] = $plugin->getPluginButtons();
638 $pluginLabels = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $plugin->getPluginLabels(), 1);
639 foreach ($this->pluginLabel as $previousPluginId => $labelList) {
640 $this->pluginLabel[$previousPluginId] = implode(',', array_diff(\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->pluginLabel[$previousPluginId], 1), $pluginLabels));
641 }
642 $this->pluginLabel[$pluginId] = $plugin->getPluginLabels();
643 $this->pluginEnabledArray[] = $pluginId;
644 }
645 }
646 }
647 }
648 // Process overrides
649 $hidePlugins = array();
650 foreach ($this->registeredPlugins as $pluginId => $plugin) {
651 if ($plugin->addsButtons() && !$this->pluginButton[$pluginId]) {
652 $hidePlugins[] = $pluginId;
653 }
654 }
655 $this->pluginEnabledArray = array_unique(array_diff($this->pluginEnabledArray, $hidePlugins));
656 }
657
658 /**
659 * Set the toolbar config (only in this PHP-Object, not in JS):
660 *
661 * @todo Define visibility
662 */
663 public function setToolbar() {
664 if ($this->client['browser'] == 'msie' || $this->client['browser'] == 'opera') {
665 $this->thisConfig['keepButtonGroupTogether'] = 0;
666 }
667 $this->defaultToolbarOrder = 'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak,
668 bar, formattext, bold, strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code, definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span,
669 bar, fontstyle, space, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, line,
670 bar, left, center, right, justifyfull,
671 bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, lefttoright, righttoleft, language, showlanguagemarks,
672 bar, textcolor, bgcolor, textindicator,
673 bar, editelement, showmicrodata, emoticon, insertcharacter, insertsofthyphen, 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,
674 bar, chMode, inserttag, removeformat, bar, copy, cut, paste, pastetoggle, pastebehaviour, bar, undo, redo, bar, showhelp, about, linebreak,
675 ' . ($this->thisConfig['hideTableOperationsInToolbar'] ? '' : 'bar, toggleborders,') . ' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar,
676 columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar,
677 cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
678 // Additional buttons from registered plugins
679 foreach ($this->registeredPlugins as $pluginId => $plugin) {
680 if ($this->isPluginEnabled($pluginId)) {
681 $this->defaultToolbarOrder = $plugin->addButtonsToToolbar();
682 }
683 }
684 $toolbarOrder = $this->thisConfig['toolbarOrder'] ? $this->thisConfig['toolbarOrder'] : $this->defaultToolbarOrder;
685 // Getting rid of undefined buttons
686 $this->toolbarOrderArray = array_intersect(\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $toolbarOrder, 1), \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->defaultToolbarOrder, 1));
687 $toolbarOrder = array_unique(array_values($this->toolbarOrderArray));
688 // Fetching specConf for field from backend
689 $pList = is_array($this->specConf['richtext']['parameters']) ? implode(',', $this->specConf['richtext']['parameters']) : '';
690 if ($pList != '*') {
691 // If not all
692 $show = is_array($this->specConf['richtext']['parameters']) ? $this->specConf['richtext']['parameters'] : array();
693 if ($this->thisConfig['showButtons']) {
694 if (!\TYPO3\CMS\Core\Utility\GeneralUtility::inList($this->thisConfig['showButtons'], '*')) {
695 $show = array_unique(array_merge($show, \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->thisConfig['showButtons'], 1)));
696 } else {
697 $show = array_unique(array_merge($show, $toolbarOrder));
698 }
699 }
700 if (is_array($this->thisConfig['showButtons.'])) {
701 foreach ($this->thisConfig['showButtons.'] as $buttonId => $value) {
702 if ($value) {
703 $show[] = $buttonId;
704 }
705 }
706 $show = array_unique($show);
707 }
708 } else {
709 $show = $toolbarOrder;
710 }
711 // Resticting to RTEkeyList for backend user
712 if (is_object($GLOBALS['BE_USER'])) {
713 $RTEkeyList = isset($GLOBALS['BE_USER']->userTS['options.']['RTEkeyList']) ? $GLOBALS['BE_USER']->userTS['options.']['RTEkeyList'] : '*';
714 if ($RTEkeyList != '*') {
715 // If not all
716 $show = array_intersect($show, \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $RTEkeyList, 1));
717 }
718 }
719 // Hiding buttons of disabled plugins
720 $hideButtons = array('space', 'bar', 'linebreak');
721 foreach ($this->pluginButton as $pluginId => $buttonList) {
722 if (!$this->isPluginEnabled($pluginId)) {
723 $buttonArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $buttonList, 1);
724 foreach ($buttonArray as $button) {
725 $hideButtons[] = $button;
726 }
727 }
728 }
729 // Hiding labels of disabled plugins
730 foreach ($this->pluginLabel as $pluginId => $label) {
731 if (!$this->isPluginEnabled($pluginId)) {
732 $hideButtons[] = $label;
733 }
734 }
735 // Hiding buttons
736 $show = array_diff($show, $this->conf_toolbar_hide, \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->thisConfig['hideButtons'], 1));
737 // Apply toolbar constraints from registered plugins
738 foreach ($this->registeredPlugins as $pluginId => $plugin) {
739 if ($this->isPluginEnabled($pluginId) && method_exists($plugin, 'applyToolbarConstraints')) {
740 $show = $plugin->applyToolbarConstraints($show);
741 }
742 }
743 // Getting rid of the buttons for which we have no position
744 $show = array_intersect($show, $toolbarOrder);
745 $this->toolbar = $show;
746 }
747
748 /**
749 * Disable some plugins
750 *
751 * @todo Define visibility
752 */
753 public function setPlugins() {
754 // Disabling a plugin that adds buttons if none of its buttons is in the toolbar
755 $hidePlugins = array();
756 foreach ($this->pluginButton as $pluginId => $buttonList) {
757 if ($this->registeredPlugins[$pluginId]->addsButtons()) {
758 $showPlugin = FALSE;
759 $buttonArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $buttonList, 1);
760 foreach ($buttonArray as $button) {
761 if (in_array($button, $this->toolbar)) {
762 $showPlugin = TRUE;
763 }
764 }
765 if (!$showPlugin) {
766 $hidePlugins[] = $pluginId;
767 }
768 }
769 }
770 $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
771 // Hiding labels of disabled plugins
772 $hideLabels = array();
773 foreach ($this->pluginLabel as $pluginId => $label) {
774 if (!$this->isPluginEnabled($pluginId)) {
775 $hideLabels[] = $label;
776 }
777 }
778 $this->toolbar = array_diff($this->toolbar, $hideLabels);
779 // Adding plugins declared as prerequisites by enabled plugins
780 $requiredPlugins = array();
781 foreach ($this->registeredPlugins as $pluginId => $plugin) {
782 if ($this->isPluginEnabled($pluginId)) {
783 $requiredPlugins = array_merge($requiredPlugins, \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $plugin->getRequiredPlugins(), 1));
784 }
785 }
786 $requiredPlugins = array_unique($requiredPlugins);
787 foreach ($requiredPlugins as $pluginId) {
788 if (is_object($this->registeredPlugins[$pluginId]) && !$this->isPluginEnabled($pluginId)) {
789 $this->pluginEnabledArray[] = $pluginId;
790 }
791 }
792 $this->pluginEnabledArray = array_unique($this->pluginEnabledArray);
793 // Completing the toolbar conversion array for htmlArea
794 foreach ($this->registeredPlugins as $pluginId => $plugin) {
795 if ($this->isPluginEnabled($pluginId)) {
796 $this->convertToolbarForHtmlAreaArray = array_unique(array_merge($this->convertToolbarForHtmlAreaArray, $plugin->getConvertToolbarForHtmlAreaArray()));
797 }
798 }
799 }
800
801 /**
802 * Convert the TYPO3 names of buttons into the names for htmlArea RTE
803 *
804 * @param string buttonname (typo3-name)
805 * @return string buttonname (htmlarea-name)
806 * @todo Define visibility
807 */
808 public function convertToolbarForHTMLArea($button) {
809 return $this->convertToolbarForHtmlAreaArray[$button];
810 }
811
812 /**
813 * Add RTE main scripts and plugin scripts
814 *
815 * @param string $RTEcounter: The index number of the current RTE editing area within the form.
816 * @return void
817 */
818 protected function addRteJsFiles($RTEcounter) {
819 $this->pageRenderer->addJsFile($this->getFullFileName('EXT:' . $this->ID . '/htmlarea/htmlarea.js'));
820 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
821 $extensionKey = is_object($this->registeredPlugins[$pluginId]) ? $this->registeredPlugins[$pluginId]->getExtensionKey() : $this->ID;
822 $this->pageRenderer->addJsFile($this->getFullFileName('EXT:' . $extensionKey . '/htmlarea/plugins/' . $pluginId . '/' . strtolower(preg_replace('/([a-z])([A-Z])([a-z])/', '$1-$2$3', $pluginId)) . '.js'));
823 }
824 }
825
826 /**
827 * Return RTE initialization inline JavaScript code
828 *
829 * @return string RTE initialization inline JavaScript code
830 */
831 protected function getRteInitJsCode() {
832 return '
833 if (typeof(RTEarea) == "undefined") {
834 RTEarea = new Object();
835 RTEarea[0] = new Object();
836 RTEarea[0].version = "' . $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->ID]['version'] . '";
837 RTEarea[0].editorUrl = "' . $this->extHttpPath . 'htmlarea/";
838 RTEarea[0].editorCSS = "' . \TYPO3\CMS\Core\Utility\GeneralUtility::createVersionNumberedFilename($this->editorCSS) . '";
839 RTEarea[0].editorSkin = "' . dirname($this->editorCSS) . '/";
840 RTEarea[0].editedContentCSS = "' . \TYPO3\CMS\Core\Utility\GeneralUtility::createVersionNumberedFilename($this->editedContentCSS) . '";
841 RTEarea[0].hostUrl = "' . $this->hostURL . '";
842 RTEarea.init = function() {
843 if (typeof(HTMLArea) == "undefined" || !Ext.isReady) {
844 window.setTimeout("RTEarea.init();", 10);
845 } else {
846 Ext.QuickTips.init();
847 HTMLArea.init();
848 }
849 };
850 RTEarea.initEditor = function(editorNumber) {
851 if (typeof(HTMLArea) == "undefined" || !HTMLArea.isReady) {
852 RTEarea.initEditor.defer(40, null, [editorNumber]);
853 } else {
854 HTMLArea.initEditor(editorNumber);
855 }
856 };
857 }
858 RTEarea.init();';
859 }
860
861 /**
862 * Return the Javascript code for configuring the RTE
863 *
864 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
865 * @param string $table: The table that includes this RTE (optional, necessary for IRRE).
866 * @param string $uid: The uid of that table that includes this RTE (optional, necessary for IRRE).
867 * @param string $field: The field of that record that includes this RTE (optional).
868 * @param string $textAreaId ID of the textarea, to have a unigue number for the editor
869 * @return string the Javascript code for configuring the RTE
870 * @todo Define visibility
871 */
872 public function registerRTEinJS($RTEcounter, $table = '', $uid = '', $field = '', $textAreaId = '') {
873 $configureRTEInJavascriptString = '
874 if (typeof(configureEditorInstance) == "undefined") {
875 configureEditorInstance = new Object();
876 }
877 configureEditorInstance["' . $textAreaId . '"] = function() {
878 if (typeof(RTEarea) == "undefined" || typeof(HTMLArea) == "undefined") {
879 window.setTimeout("configureEditorInstance[\'' . $textAreaId . '\']();", 40);
880 } else {
881 editornumber = "' . $textAreaId . '";
882 RTEarea[editornumber] = new Object();
883 RTEarea[editornumber].RTEtsConfigParams = "&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams()) . '";
884 RTEarea[editornumber].number = editornumber;
885 RTEarea[editornumber].deleted = false;
886 RTEarea[editornumber].textAreaId = "' . $textAreaId . '";
887 RTEarea[editornumber].id = "RTEarea" + editornumber;
888 RTEarea[editornumber].RTEWidthOverride = "' . (is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteWidth']) && trim($GLOBALS['BE_USER']->uc['rteWidth']) ? trim($GLOBALS['BE_USER']->uc['rteWidth']) : trim($this->thisConfig['RTEWidthOverride'])) . '";
889 RTEarea[editornumber].RTEHeightOverride = "' . (is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteHeight']) && intval($GLOBALS['BE_USER']->uc['rteHeight']) ? intval($GLOBALS['BE_USER']->uc['rteHeight']) : intval($this->thisConfig['RTEHeightOverride'])) . '";
890 RTEarea[editornumber].resizable = ' . (is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteResize']) && $GLOBALS['BE_USER']->uc['rteResize'] ? 'true' : (trim($this->thisConfig['rteResize']) ? 'true' : 'false')) . ';
891 RTEarea[editornumber].maxHeight = "' . (is_object($GLOBALS['BE_USER']) && isset($GLOBALS['BE_USER']->uc['rteMaxHeight']) && intval($GLOBALS['BE_USER']->uc['rteMaxHeight']) ? trim($GLOBALS['BE_USER']->uc['rteMaxHeight']) : (intval($this->thisConfig['rteMaxHeight']) ? intval($this->thisConfig['rteMaxHeight']) : '2000')) . '";
892 RTEarea[editornumber].fullScreen = ' . ($this->fullScreen ? 'true' : 'false') . ';
893 RTEarea[editornumber].showStatusBar = ' . (trim($this->thisConfig['showStatusBar']) ? 'true' : 'false') . ';
894 RTEarea[editornumber].enableWordClean = ' . (trim($this->thisConfig['enableWordClean']) ? 'true' : 'false') . ';
895 RTEarea[editornumber].htmlRemoveComments = ' . (trim($this->thisConfig['removeComments']) ? 'true' : 'false') . ';
896 RTEarea[editornumber].disableEnterParagraphs = ' . (trim($this->thisConfig['disableEnterParagraphs']) ? 'true' : 'false') . ';
897 RTEarea[editornumber].disableObjectResizing = ' . (trim($this->thisConfig['disableObjectResizing']) ? 'true' : 'false') . ';
898 RTEarea[editornumber].removeTrailingBR = ' . (trim($this->thisConfig['removeTrailingBR']) ? 'true' : 'false') . ';
899 RTEarea[editornumber].useCSS = ' . (trim($this->thisConfig['useCSS']) ? 'true' : 'false') . ';
900 RTEarea[editornumber].keepButtonGroupTogether = ' . (trim($this->thisConfig['keepButtonGroupTogether']) ? 'true' : 'false') . ';
901 RTEarea[editornumber].disablePCexamples = ' . (trim($this->thisConfig['disablePCexamples']) ? 'true' : 'false') . ';
902 RTEarea[editornumber].showTagFreeClasses = ' . (trim($this->thisConfig['showTagFreeClasses']) ? 'true' : 'false') . ';
903 RTEarea[editornumber].useHTTPS = ' . (trim(stristr($this->siteURL, 'https')) || $this->thisConfig['forceHTTPS'] ? 'true' : 'false') . ';
904 RTEarea[editornumber].tceformsNested = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(TRUE) : '[]') . ';
905 RTEarea[editornumber].dialogueWindows = new Object();';
906 if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromTop'])) {
907 $configureRTEInJavascriptString .= '
908 RTEarea[editornumber].dialogueWindows.positionFromTop = ' . intval($this->thisConfig['dialogueWindows.']['defaultPositionFromTop']) . ';';
909 }
910 if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'])) {
911 $configureRTEInJavascriptString .= '
912 RTEarea[editornumber].dialogueWindows.positionFromLeft = ' . intval($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft']) . ';';
913 }
914 // The following properties apply only to the backend
915 if (!$this->is_FE()) {
916 $configureRTEInJavascriptString .= '
917 RTEarea[editornumber].sys_language_content = "' . $this->contentLanguageUid . '";
918 RTEarea[editornumber].typo3ContentLanguage = "' . $this->contentTypo3Language . '";
919 RTEarea[editornumber].typo3ContentCharset = "' . $this->contentCharset . '";
920 RTEarea[editornumber].userUid = "' . $this->userUid . '";';
921 }
922 // Setting the plugin flags
923 $configureRTEInJavascriptString .= '
924 RTEarea[editornumber].plugin = new Object();
925 RTEarea[editornumber].pathToPluginDirectory = new Object();';
926 foreach ($this->pluginEnabledArray as $pluginId) {
927 $configureRTEInJavascriptString .= '
928 RTEarea[editornumber].plugin.' . $pluginId . ' = true;';
929 if (is_object($this->registeredPlugins[$pluginId])) {
930 $pathToPluginDirectory = $this->registeredPlugins[$pluginId]->getPathToPluginDirectory();
931 if ($pathToPluginDirectory) {
932 $configureRTEInJavascriptString .= '
933 RTEarea[editornumber].pathToPluginDirectory.' . $pluginId . ' = "' . $pathToPluginDirectory . '";';
934 }
935 }
936 }
937 // Setting the buttons configuration
938 $configureRTEInJavascriptString .= '
939 RTEarea[editornumber].buttons = new Object();';
940 if (is_array($this->thisConfig['buttons.'])) {
941 foreach ($this->thisConfig['buttons.'] as $buttonIndex => $conf) {
942 $button = substr($buttonIndex, 0, -1);
943 if (is_array($conf)) {
944 $configureRTEInJavascriptString .= '
945 RTEarea[editornumber].buttons.' . $button . ' = ' . $this->buildNestedJSArray($conf) . ';';
946 }
947 }
948 }
949 // Setting the list of tags to be removed if specified in the RTE config
950 if (trim($this->thisConfig['removeTags'])) {
951 $configureRTEInJavascriptString .= '
952 RTEarea[editornumber].htmlRemoveTags = /^(' . implode('|', \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->thisConfig['removeTags'], 1)) . ')$/i;';
953 }
954 // Setting the list of tags to be removed with their contents if specified in the RTE config
955 if (trim($this->thisConfig['removeTagsAndContents'])) {
956 $configureRTEInJavascriptString .= '
957 RTEarea[editornumber].htmlRemoveTagsAndContents = /^(' . implode('|', \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->thisConfig['removeTagsAndContents'], 1)) . ')$/i;';
958 }
959 // Setting array of custom tags if specified in the RTE config
960 if (!empty($this->thisConfig['customTags'])) {
961 $customTags = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->thisConfig['customTags'], 1);
962 if (!empty($customTags)) {
963 $configureRTEInJavascriptString .= '
964 RTEarea[editornumber].customTags= ' . json_encode($customTags) . ';';
965 }
966 }
967 // Setting the pageStyle
968 $configureRTEInJavascriptString .= '
969 RTEarea[editornumber].pageStyle = "' . \TYPO3\CMS\Core\Utility\GeneralUtility::createVersionNumberedFilename($this->getContentCssFileName()) . '";';
970 // Process classes configuration
971 $classesConfigurationRequired = FALSE;
972 foreach ($this->registeredPlugins as $pluginId => $plugin) {
973 if ($this->isPluginEnabled($pluginId)) {
974 $classesConfigurationRequired = $classesConfigurationRequired || $plugin->requiresClassesConfiguration();
975 }
976 }
977 if ($classesConfigurationRequired) {
978 $configureRTEInJavascriptString .= $this->buildJSClassesConfig($RTEcounter);
979 }
980 // Add Javascript configuration for registered plugins
981 foreach ($this->registeredPlugins as $pluginId => $plugin) {
982 if ($this->isPluginEnabled($pluginId)) {
983 $configureRTEInJavascriptString .= $plugin->buildJavascriptConfiguration('editornumber');
984 }
985 }
986 // Avoid premature reference to HTMLArea when being initially loaded by IRRE Ajax call
987 $configureRTEInJavascriptString .= '
988 RTEarea[editornumber].toolbar = ' . $this->getJSToolbarArray() . ';
989 RTEarea[editornumber].convertButtonId = ' . json_encode(array_flip($this->convertToolbarForHtmlAreaArray)) . ';
990 RTEarea.initEditor(editornumber);
991 }
992 };
993 configureEditorInstance["' . $textAreaId . '"]();';
994 return $configureRTEInJavascriptString;
995 }
996
997 /**
998 * Return TRUE, if the plugin can be loaded
999 *
1000 * @param string $pluginId: The identification string of the plugin
1001 * @return boolean TRUE if the plugin can be loaded
1002 * @todo Define visibility
1003 */
1004 public function isPluginEnabled($pluginId) {
1005 return in_array($pluginId, $this->pluginEnabledArray);
1006 }
1007
1008 /**
1009 * Build the default content style sheet
1010 *
1011 * @return string Style sheet
1012 * @deprecated since TYPO3 6.0, will be removed in TYPO3 6.2
1013 * @todo Define visibility
1014 */
1015 public function buildStyleSheet() {
1016 $stylesheet = '/* mainStyleOverride and inlineStyle properties ignored. */';
1017 return $stylesheet;
1018 }
1019
1020 /**
1021 * Return Javascript configuration of classes
1022 *
1023 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1024 * @return string Javascript configuration of classes
1025 * @todo Define visibility
1026 */
1027 public function buildJSClassesConfig($RTEcounter) {
1028 // Include JS arrays of configured classes
1029 $configureRTEInJavascriptString .= '
1030 RTEarea[editornumber].classesUrl = "' . ($this->is_FE() && $GLOBALS['TSFE']->absRefPrefix ? $GLOBALS['TSFE']->absRefPrefix : '') . $this->writeTemporaryFile('', ('classes_' . $this->language), 'js', $this->buildJSClassesArray(), TRUE) . '";';
1031 return $configureRTEInJavascriptString;
1032 }
1033
1034 /**
1035 * Return JS arrays of classes configuration
1036 *
1037 * @return string JS classes arrays
1038 * @todo Define visibility
1039 */
1040 public function buildJSClassesArray() {
1041 if ($this->is_FE()) {
1042 $RTEProperties = $this->RTEsetup;
1043 } else {
1044 $RTEProperties = $this->RTEsetup['properties'];
1045 }
1046 $classesArray = array('labels' => array(), 'values' => array(), 'noShow' => array(), 'alternating' => array(), 'counting' => array(), 'XOR' => array());
1047 $JSClassesArray = '';
1048 // Scanning the list of classes if specified in the RTE config
1049 if (is_array($RTEProperties['classes.'])) {
1050 foreach ($RTEProperties['classes.'] as $className => $conf) {
1051 $className = rtrim($className, '.');
1052 $classesArray['labels'][$className] = $this->getPageConfigLabel($conf['name'], FALSE);
1053 $classesArray['values'][$className] = str_replace('\\\'', '\'', $conf['value']);
1054 if (isset($conf['noShow'])) {
1055 $classesArray['noShow'][$className] = $conf['noShow'];
1056 }
1057 if (is_array($conf['alternating.'])) {
1058 $classesArray['alternating'][$className] = $conf['alternating.'];
1059 }
1060 if (is_array($conf['counting.'])) {
1061 $classesArray['counting'][$className] = $conf['counting.'];
1062 }
1063 }
1064 }
1065 // Scanning the list of sets of mutually exclusives classes if specified in the RTE config
1066 if (is_array($RTEProperties['mutuallyExclusiveClasses.'])) {
1067 foreach ($RTEProperties['mutuallyExclusiveClasses.'] as $listName => $conf) {
1068 $classSet = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $conf, 1);
1069 $classList = implode(',', $classSet);
1070 foreach ($classSet as $className) {
1071 $classesArray['XOR'][$className] = '/^(' . implode('|', \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', \TYPO3\CMS\Core\Utility\GeneralUtility::rmFromList($className, $classList), 1)) . ')$/';
1072 }
1073 }
1074 }
1075 foreach ($classesArray as $key => $subArray) {
1076 $JSClassesArray .= 'HTMLArea.classes' . ucfirst($key) . ' = ' . $this->buildNestedJSArray($subArray) . ';' . LF;
1077 }
1078 return $JSClassesArray;
1079 }
1080
1081 /**
1082 * Translate Page TS Config array in JS nested array definition
1083 * Replace 0 values with false
1084 * Unquote regular expression values
1085 * Replace empty arrays with empty objects
1086 *
1087 * @param array $conf: Page TSConfig configuration array
1088 * @return string nested JS array definition
1089 * @todo Define visibility
1090 */
1091 public function buildNestedJSArray($conf) {
1092 $convertedConf = \TYPO3\CMS\Core\Utility\GeneralUtility::removeDotsFromTS($conf);
1093 return str_replace(array(':"0"', ':"\\/^(', ')$\\/i"', ':"\\/^(', ')$\\/"', '[]'), array(':false', ':/^(', ')$/i', ':/^(', ')$/', '{}'), json_encode($convertedConf));
1094 }
1095
1096 /**
1097 * Return a Javascript localization array for htmlArea RTE
1098 *
1099 * @return string Javascript localization array
1100 * @todo Define visibility
1101 */
1102 public function buildJSMainLangArray() {
1103 $JSLanguageArray = 'HTMLArea.I18N = new Object();' . LF;
1104 $labelsArray = array('tooltips' => array(), 'msg' => array(), 'dialogs' => array());
1105 foreach ($labelsArray as $labels => $subArray) {
1106 $LOCAL_LANG = \TYPO3\CMS\Core\Utility\GeneralUtility::readLLfile('EXT:' . $this->ID . '/htmlarea/locallang_' . $labels . '.xml', $this->language, 'utf-8');
1107 if (!empty($LOCAL_LANG[$this->language])) {
1108 $LOCAL_LANG[$this->language] = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($LOCAL_LANG['default'], $LOCAL_LANG[$this->language], FALSE, FALSE);
1109 } else {
1110 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1111 }
1112 $labelsArray[$labels] = $LOCAL_LANG[$this->language];
1113 }
1114 $JSLanguageArray .= 'HTMLArea.I18N = ' . json_encode($labelsArray) . ';' . LF;
1115 return $JSLanguageArray;
1116 }
1117
1118 /**
1119 * Writes contents in a file in typo3temp/rtehtmlarea directory and returns the file name
1120 *
1121 * @param string $sourceFileName: The name of the file from which the contents should be extracted
1122 * @param string $label: A label to insert at the beginning of the name of the file
1123 * @param string $fileExtension: The file extension of the file, defaulting to 'js'
1124 * @param string $contents: The contents to write into the file if no $sourceFileName is provided
1125 * @param boolean $concatenate Not used anymore
1126 * @return string The name of the file writtten to typo3temp/rtehtmlarea
1127 */
1128 public function writeTemporaryFile($sourceFileName = '', $label, $fileExtension = 'js', $contents = '', $concatenate = FALSE) {
1129 if ($sourceFileName) {
1130 $output = '';
1131 $source = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($sourceFileName);
1132 $output = file_get_contents($source);
1133 } else {
1134 $output = $contents;
1135 }
1136 $relativeFilename = 'typo3temp/' . $this->ID . '_' . str_replace('-', '_', $label) . '_' . \TYPO3\CMS\Core\Utility\GeneralUtility::shortMD5((TYPO3_version . $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . ($sourceFileName ? $sourceFileName : $output)), 20) . '.' . $fileExtension;
1137 $destination = PATH_site . $relativeFilename;
1138 if (!file_exists($destination)) {
1139 $minifiedJavaScript = '';
1140 if ($fileExtension == 'js' && $output != '') {
1141 $minifiedJavaScript = \TYPO3\CMS\Core\Utility\GeneralUtility::minifyJavaScript($output);
1142 }
1143 $failure = \TYPO3\CMS\Core\Utility\GeneralUtility::writeFileToTypo3tempDir($destination, $minifiedJavaScript ? $minifiedJavaScript : $output);
1144 if ($failure) {
1145 throw new \RuntimeException($failure, 1294585668);
1146 }
1147 }
1148 if ($this->is_FE()) {
1149 $filename = $relativeFilename;
1150 } else {
1151 $filename = ($this->isFrontendEditActive() ? '' : $this->backPath . '../') . $relativeFilename;
1152 }
1153 return \TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath($filename);
1154 }
1155
1156 /**
1157 * Return a file name containing the main JS language array for HTMLArea
1158 *
1159 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1160 * @return string filename
1161 * @todo Define visibility
1162 */
1163 public function buildJSMainLangFile($RTEcounter) {
1164 $contents = $this->buildJSMainLangArray() . LF;
1165 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
1166 $contents .= $this->buildJSLangArray($pluginId) . LF;
1167 }
1168 return $this->writeTemporaryFile('', $this->language . '_' . $this->OutputCharset, 'js', $contents, TRUE);
1169 }
1170
1171 /**
1172 * Return a Javascript localization array for the plugin
1173 *
1174 * @param string $plugin: identification string of the plugin
1175 * @return string Javascript localization array
1176 * @todo Define visibility
1177 */
1178 public function buildJSLangArray($plugin) {
1179 $LOCAL_LANG = FALSE;
1180 $extensionKey = is_object($this->registeredPlugins[$plugin]) ? $this->registeredPlugins[$plugin]->getExtensionKey() : $this->ID;
1181 $LOCAL_LANG = \TYPO3\CMS\Core\Utility\GeneralUtility::readLLfile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $plugin . '/locallang.xml', $this->language, 'utf-8', 1);
1182 $JSLanguageArray = 'HTMLArea.I18N["' . $plugin . '"] = new Object();' . LF;
1183 if (is_array($LOCAL_LANG)) {
1184 if (!empty($LOCAL_LANG[$this->language])) {
1185 $LOCAL_LANG[$this->language] = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($LOCAL_LANG['default'], $LOCAL_LANG[$this->language], FALSE, FALSE);
1186 } else {
1187 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default'];
1188 }
1189 $JSLanguageArray .= 'HTMLArea.I18N["' . $plugin . '"] = ' . json_encode($LOCAL_LANG[$this->language]) . ';' . LF;
1190 }
1191 return $JSLanguageArray;
1192 }
1193
1194 /**
1195 * Return the JS code of the toolbar configuration for the HTMLArea editor
1196 *
1197 * @return string the JS code as nested JS arrays
1198 */
1199 protected function getJSToolbarArray() {
1200 // The toolbar array
1201 $toolbar = array();
1202 // The current row; a "linebreak" ends the current row
1203 $row = array();
1204 // The current group; each group is between "bar"s; a "linebreak" ends the current group
1205 $group = array();
1206 // Process each toolbar item in the toolbar order list
1207 foreach ($this->toolbarOrderArray as $item) {
1208 switch ($item) {
1209 case 'linebreak':
1210 // Add row to toolbar if not empty
1211 if (!empty($group)) {
1212 $row[] = $group;
1213 $group = array();
1214 }
1215 if (!empty($row)) {
1216 $toolbar[] = $row;
1217 $row = array();
1218 }
1219 break;
1220 case 'bar':
1221 // Add group to row if not empty
1222 if (!empty($group)) {
1223 $row[] = $group;
1224 $group = array();
1225 }
1226 break;
1227 case 'space':
1228 if (end($group) != $this->convertToolbarForHTMLArea($item)) {
1229 $group[] = $this->convertToolbarForHTMLArea($item);
1230 }
1231 break;
1232 default:
1233 if (in_array($item, $this->toolbar)) {
1234 // Add the item to the group
1235 $convertedItem = $this->convertToolbarForHTMLArea($item);
1236 if ($convertedItem) {
1237 $group[] = $convertedItem;
1238 }
1239 }
1240 break;
1241 }
1242 }
1243 // Add the last group and last line, if not empty
1244 if (!empty($group)) {
1245 $row[] = $group;
1246 }
1247 if (!empty($row)) {
1248 $toolbar[] = $row;
1249 }
1250 return json_encode($toolbar);
1251 }
1252
1253 /**
1254 * Localize a string using the language of the content element rather than the language of the BE interface
1255 *
1256 * @param string string: the label to be localized
1257 * @return string Localized string.
1258 */
1259 public function getLLContent($string) {
1260 return $this->contentLanguageService->JScharCode($this->contentLanguageService->sL($string));
1261 }
1262
1263 public function getPageConfigLabel($string, $JScharCode = 1) {
1264 global $LANG, $TSFE, $TYPO3_CONF_VARS;
1265 if ($this->is_FE()) {
1266 if (strcmp(substr($string, 0, 4), 'LLL:')) {
1267 // A pure string coming from Page TSConfig must be in utf-8
1268 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), 'utf-8', $this->OutputCharset);
1269 } else {
1270 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $this->charset, $this->OutputCharset);
1271 }
1272 $label = str_replace('"', '\\"', str_replace('\\\'', '\'', $label));
1273 $label = $JScharCode ? $this->feJScharCode($label) : $label;
1274 } else {
1275 if (strcmp(substr($string, 0, 4), 'LLL:')) {
1276 $label = $string;
1277 } else {
1278 $label = $LANG->sL(trim($string));
1279 }
1280 $label = str_replace('"', '\\"', str_replace('\\\'', '\'', $label));
1281 $label = $JScharCode ? $LANG->JScharCode($label) : $label;
1282 }
1283 return $label;
1284 }
1285
1286 /**
1287 * @todo Define visibility
1288 */
1289 public function feJScharCode($str) {
1290 // Convert string to UTF-8:
1291 if ($this->OutputCharset != 'utf-8') {
1292 $str = $GLOBALS['TSFE']->csConvObj->utf8_encode($str, $this->OutputCharset);
1293 }
1294 // Convert the UTF-8 string into a array of char numbers:
1295 $nArr = $GLOBALS['TSFE']->csConvObj->utf8_to_numberarray($str);
1296 return 'String.fromCharCode(' . implode(',', $nArr) . ')';
1297 }
1298
1299 public function getFullFileName($filename) {
1300 if (substr($filename, 0, 4) == 'EXT:') {
1301 // extension
1302 list($extKey, $local) = explode('/', substr($filename, 4), 2);
1303 $newFilename = '';
1304 if (strcmp($extKey, '') && \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($extKey) && strcmp($local, '')) {
1305 $newFilename = ($this->is_FE() || $this->isFrontendEditActive() ? \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($extKey) : $this->backPath . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($extKey)) . $local;
1306 }
1307 } elseif (substr($filename, 0, 1) != '/') {
1308 $newFilename = ($this->is_FE() || $this->isFrontendEditActive() ? '' : $this->backPath . '../') . $filename;
1309 } else {
1310 $newFilename = ($this->is_FE() || $this->isFrontendEditActive() ? '' : $this->backPath . '../') . substr($filename, 1);
1311 }
1312 return \TYPO3\CMS\Core\Utility\GeneralUtility::resolveBackPath($newFilename);
1313 }
1314
1315 /**
1316 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1317 * This is for submit function of the form.
1318 *
1319 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1320 * @param string $formName: the name of the form
1321 * @param string $textareaId: the id of the textarea
1322 * @param string $textareaName: the name of the textarea
1323 * @return string Javascript code
1324 * @todo Define visibility
1325 */
1326 public function setSaveRTE($RTEcounter, $formName, $textareaId, $textareaName) {
1327 return 'if (RTEarea["' . $textareaId . '"]) { document.' . $formName . '["' . $textareaName . '"].value = RTEarea["' . $textareaId . '"].editor.getHTML(); } else { OK = 0; };';
1328 }
1329
1330 /**
1331 * Return the Javascript code for copying the HTML code from the editor into the hidden input field.
1332 * This is for submit function of the form.
1333 *
1334 * @param integer $RTEcounter: The index number of the current RTE editing area within the form.
1335 * @param string $formName: the name of the form
1336 * @param string $textareaId: the id of the textarea
1337 * @return string Javascript code
1338 * @todo Define visibility
1339 */
1340 public function setDeleteRTE($RTEcounter, $formName, $textareaId) {
1341 return 'if (RTEarea["' . $textareaId . '"]) { RTEarea["' . $textareaId . '"].deleted = true;}';
1342 }
1343
1344 /**
1345 * Return TRUE if we are in the FE, but not in the FE editing feature of BE.
1346 *
1347 * @return boolean
1348 * @todo Define visibility
1349 */
1350 public function is_FE() {
1351 return is_object($GLOBALS['TSFE']) && !$this->isFrontendEditActive() && TYPO3_MODE == 'FE';
1352 }
1353
1354 /**
1355 * Checks whether frontend editing is active.
1356 *
1357 * @return boolean
1358 */
1359 public function isFrontendEditActive() {
1360 return is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->beUserLogin && $GLOBALS['BE_USER']->frontendEdit instanceof \TYPO3\CMS\Core\FrontendEditing\FrontendEditingController;
1361 }
1362
1363 /**
1364 * Client Browser Information
1365 *
1366 * @param string $userAgent: The useragent string, \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('HTTP_USER_AGENT')
1367 * @return array Contains keys "useragent", "browser", "version", "system
1368 * @todo Define visibility
1369 */
1370 public function clientInfo($userAgent = '') {
1371 if (!$userAgent) {
1372 $userAgent = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('HTTP_USER_AGENT');
1373 }
1374 $browserInfo = \TYPO3\CMS\Core\Utility\ClientUtility::getBrowserInfo($userAgent);
1375 // Known engines: order is not irrelevant!
1376 $knownEngines = array('opera', 'msie', 'gecko', 'webkit');
1377 if (is_array($browserInfo['all'])) {
1378 foreach ($knownEngines as $engine) {
1379 if ($browserInfo['all'][$engine]) {
1380 $browserInfo['browser'] = $engine;
1381 $browserInfo['version'] = \TYPO3\CMS\Core\Utility\ClientUtility::getVersion($browserInfo['all'][$engine]);
1382 break;
1383 }
1384 }
1385 }
1386 return $browserInfo;
1387 }
1388
1389 /**
1390 * Log usage of deprecated Page TS Config Property
1391 *
1392 * @param string $deprecatedProperty: Name of deprecated property
1393 * @param string $useProperty: Name of property to use instead
1394 * @param string $version: Version of TYPO3 in which the property will be removed
1395 * @return void
1396 */
1397 public function logDeprecatedProperty($deprecatedProperty, $useProperty, $version) {
1398 if (!$this->thisConfig['logDeprecatedProperties.']['disabled']) {
1399 $message = sprintf('RTE Page TSConfig property "%1$s" used on page id #%4$s is DEPRECATED and will be removed in TYPO3 %3$s. Use "%2$s" instead.', $deprecatedProperty, $useProperty, $version, $this->thePid);
1400 \TYPO3\CMS\Core\Utility\GeneralUtility::deprecationLog($message);
1401 if (is_object($GLOBALS['BE_USER']) && $this->thisConfig['logDeprecatedProperties.']['logAlsoToBELog']) {
1402 $message = sprintf($GLOBALS['LANG']->getLL('deprecatedPropertyMessage'), $deprecatedProperty, $useProperty, $version, $this->thePid);
1403 $GLOBALS['BE_USER']->simplelog($message, $this->ID);
1404 }
1405 }
1406 }
1407
1408 /***************************
1409 *
1410 * OTHER FUNCTIONS: (from Classic RTE)
1411 *
1412 ***************************/
1413 /**
1414 * @return [type] ...
1415 * @desc
1416 * @todo Define visibility
1417 */
1418 public function RTEtsConfigParams() {
1419 if ($this->is_FE()) {
1420 return '';
1421 } else {
1422 $p = \TYPO3\CMS\Backend\Utility\BackendUtility::getSpecConfParametersFromArray($this->specConf['rte_transform']['parameters']);
1423 return $this->elementParts[0] . ':' . $this->elementParts[1] . ':' . $this->elementParts[2] . ':' . $this->thePid . ':' . $this->typeVal . ':' . $this->tscPID . ':' . $p['imgpath'];
1424 }
1425 }
1426
1427 public function cleanList($str) {
1428 if (strstr($str, '*')) {
1429 $str = '*';
1430 } else {
1431 $str = implode(',', array_unique(\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $str, 1)));
1432 }
1433 return $str;
1434 }
1435
1436 /**
1437 * @todo Define visibility
1438 */
1439 public function filterStyleEl($elValue, $matchList) {
1440 $matchParts = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $matchList, 1);
1441 $styleParts = explode(';', $elValue);
1442 $nStyle = array();
1443 foreach ($styleParts as $k => $p) {
1444 $pp = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(':', $p);
1445 if ($pp[0] && $pp[1]) {
1446 foreach ($matchParts as $el) {
1447 $star = substr($el, -1) == '*';
1448 if (!strcmp($pp[0], $el) || $star && \TYPO3\CMS\Core\Utility\GeneralUtility::isFirstPartOfStr($pp[0], substr($el, 0, -1))) {
1449 $nStyle[] = $pp[0] . ':' . $pp[1];
1450 } else {
1451 unset($styleParts[$k]);
1452 }
1453 }
1454 } else {
1455 unset($styleParts[$k]);
1456 }
1457 }
1458 return implode('; ', $nStyle);
1459 }
1460
1461 // Hook on lorem_ipsum extension to insert text into the RTE in wysiwyg mode
1462 /**
1463 * @todo Define visibility
1464 */
1465 public function loremIpsumInsert($params) {
1466 return '
1467 if (typeof(lorem_ipsum) == \'function\' && ' . $params['element'] . '.tagName.toLowerCase() == \'textarea\' ) lorem_ipsum(' . $params['element'] . ', lipsum_temp_strings[lipsum_temp_pointer]);
1468 ';
1469 }
1470
1471 }
1472
1473
1474 ?>