58 'disallowed' => array(
69 'disallowed' => array(
97 'showhelp' =>
'ShowHelp',
100 'linebreak' =>
'linebreak' 134 public $ID =
'rtehtmlarea';
258 $this->errorLog = array();
259 if (!$this->debugMode) {
261 $rteIsAvailable = FALSE;
263 if (is_array($rteConfBrowser)) {
264 foreach ($rteConfBrowser as $browser => $browserConf) {
265 if ($browser == $this->client[
'browser']) {
267 if (is_array($browserConf)) {
268 foreach ($browserConf as $browserConfSub) {
269 if ($browserConfSub[
'version'] <= $this->client[
'version'] || empty($browserConfSub[
'version'])) {
271 if (is_array($browserConfSub[
'system'])) {
273 if (is_array($browserConfSub[
'system'][
'allowed'])) {
274 foreach ($browserConfSub[
'system'][
'allowed'] as $system) {
275 if (in_array($system, $this->client[
'all_systems'])) {
276 $rteIsAvailable = TRUE;
282 $rteIsAvailable = TRUE;
285 if (is_array($browserConfSub[
'system'][
'disallowed'])) {
286 foreach ($browserConfSub[
'system'][
'disallowed'] as $system) {
287 if (in_array($system, $this->client[
'all_systems'])) {
288 $rteIsAvailable = FALSE;
295 $rteIsAvailable = TRUE;
302 $rteIsAvailable = TRUE;
310 if (!$rteIsAvailable) {
311 $this->errorLog[] =
'RTE: Browser not supported.';
314 $rteIsAvailable = FALSE;
315 $this->errorLog[] =
'rte: This version of htmlArea RTE cannot run under this version of TYPO3.';
318 return $rteIsAvailable;
337 public function drawRTE($parentObject, $table, $field, $row, $PA,
$specConf,
$thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue) {
338 global $LANG, $TYPO3_DB;
339 $this->TCEform = $parentObject;
340 $inline = $this->TCEform->inline;
341 $LANG->includeLLFile(
'EXT:' . $this->ID .
'/locallang.xml');
344 $this->userUid =
'BE_' .
$GLOBALS[
'BE_USER']->user[
'uid'];
346 if ($this->debugMode) {
348 $item = parent::drawRTE($this->TCEform, $table, $field, $row, $PA,
$specConf,
$thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue);
356 $this->backPath = $this->TCEform->backPath;
362 $this->hostURL = $this->siteURL . TYPO3_mainDir;
364 $this->elementId = $PA[
'itemFormElName'];
366 $this->elementParts = explode(
'][', preg_replace(
'/\\]$/',
'', preg_replace(
'/^(TSFE_EDIT\\[data\\]\\[|data\\[)/',
'', $this->elementId)));
368 list($this->tscPID, $this->thePid) =
BackendUtility::getTSCpid(trim($this->elementParts[0]), trim($this->elementParts[1]), $thePidValue);
370 $this->typeVal = $RTEtypeVal;
373 unset($this->RTEsetup);
378 if ($this->thisConfig[
'forceHTTPS']) {
379 $this->extHttpPath = preg_replace(
'/^(http|https)/',
'https', $this->extHttpPath);
380 $this->siteURL = preg_replace(
'/^(http|https)/',
'https', $this->siteURL);
381 $this->hostURL = preg_replace(
'/^(http|https)/',
'https', $this->hostURL);
384 $this->TCEform->RTEwindows[] = $PA[
'itemFormElName'];
385 $textAreaId = preg_replace(
'/[^a-zA-Z0-9_:.-]/',
'_', $PA[
'itemFormElName']);
386 $textAreaId = htmlspecialchars(preg_replace(
'/^[^a-zA-Z]/',
'x', $textAreaId));
396 $this->contentLanguageUid = max($row[
'sys_language_uid'], 0);
397 if ($this->contentLanguageUid) {
400 $tableA =
'sys_language';
401 $tableB =
'static_languages';
402 $selectFields = $tableA .
'.uid,' . $tableB .
'.lg_iso_2,' . $tableB .
'.lg_country_iso_2';
403 $tableAB = $tableA .
' LEFT JOIN ' . $tableB .
' ON ' . $tableA .
'.static_lang_isocode=' . $tableB .
'.uid';
404 $whereClause = $tableA .
'.uid = ' . intval($this->contentLanguageUid);
407 $res =
$GLOBALS[
'TYPO3_DB']->exec_SELECTquery($selectFields, $tableAB, $whereClause);
408 while ($languageRow =
$GLOBALS[
'TYPO3_DB']->sql_fetch_assoc($res)) {
409 $this->contentISOLanguage = strtolower(trim($languageRow[
'lg_iso_2']) . (trim($languageRow[
'lg_country_iso_2']) ?
'_' . trim($languageRow[
'lg_country_iso_2']) :
''));
413 $this->contentISOLanguage = trim($this->thisConfig[
'defaultContentLanguage']) ?:
'en';
414 $languageCodeParts = explode(
'_', $this->contentISOLanguage);
415 $this->contentISOLanguage = strtolower($languageCodeParts[0]) . ($languageCodeParts[1] ?
'_' . strtoupper($languageCodeParts[1]) :
'');
420 if (!in_array($this->contentISOLanguage,
$locales->getLocales())) {
421 $this->contentISOLanguage =
'en';
427 $this->contentLanguageService->init($this->contentTypo3Language);
439 $this->fullScreen = TRUE;
442 $RTEPaddingRight =
'0';
443 $editorWrapWidth =
'100%';
445 $options =
$GLOBALS[
'BE_USER']->userTS[
'options.'];
446 $RTEWidth = 530 + (isset($options[
'RTELargeWidthIncrement']) ? (int)$options[
'RTELargeWidthIncrement'] : 150);
447 $RTEWidth -= $inline->getStructureDepth() > 0 ? ($inline->getStructureDepth() + 1) * $inline->getLevelMargin() : 0;
448 $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']);
449 if ($RTEWidthOverride) {
450 if (strstr($RTEWidthOverride,
'%')) {
451 if ($this->client[
'browser'] !=
'msie') {
452 $RTEWidth = (int)$RTEWidthOverride > 0 ? $RTEWidthOverride :
'100%';
455 $RTEWidth = (int)$RTEWidthOverride > 0 ? (
int)$RTEWidthOverride : $RTEWidth;
458 $RTEWidth = strstr($RTEWidth,
'%') ? $RTEWidth : $RTEWidth .
'px';
459 $RTEHeight = 380 + (isset($options[
'RTELargeHeightIncrement']) ? (int)$options[
'RTELargeHeightIncrement'] : 0);
460 $RTEHeightOverride = is_object(
$GLOBALS[
'BE_USER']) && isset(
$GLOBALS[
'BE_USER']->uc[
'rteHeight']) && (int)
$GLOBALS[
'BE_USER']->uc[
'rteHeight'] ? (
int)
$GLOBALS[
'BE_USER']->uc[
'rteHeight'] : (int)$this->thisConfig[
'RTEHeightOverride'];
461 $RTEHeight = $RTEHeightOverride > 0 ? $RTEHeightOverride : $RTEHeight;
462 $RTEPaddingRight =
'2px';
463 $editorWrapWidth =
'99%';
465 $editorWrapHeight =
'100%';
466 $this->RTEdivStyle =
'position:relative; left:0px; top:0px; height:' . $RTEHeight .
'px; width:' . $RTEWidth .
'; border: 1px solid black; padding: 2px ' . $RTEPaddingRight .
' 2px 2px;';
471 $this->pageRenderer =
$GLOBALS[
'SOBE']->doc->getPageRenderer();
476 $this->TCEform->additionalJS_post[] = $this->
registerRTEinJS($this->TCEform->RTEcounter, $table, $row[
'uid'], $field, $textAreaId);
478 $this->TCEform->additionalJS_submit[] = $this->
setSaveRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId, $PA[
'itemFormElName']);
479 $this->TCEform->additionalJS_delete[] = $this->
setDeleteRTE($this->TCEform->RTEcounter, $this->TCEform->formName, $textAreaId);
481 $this->pageRenderer->enableExtJSQuickTips();
483 $this->pageRenderer->addJsFile(
'sysext/backend/Resources/Public/JavaScript/notifications.js');
487 $this->pageRenderer->addJsInlineCode(
'HTMLArea-init', $this->
getRteInitJsCode(), TRUE);
495 foreach ($this->registeredPlugins as $pluginId => $plugin) {
496 if ($this->
isPluginEnabled($pluginId) && method_exists($plugin,
'transformContent')) {
497 $value = $plugin->transformContent($value);
501 $visibility =
'hidden';
503 <div id="pleasewait' . $textAreaId .
'" class="pleasewait" style="display: block;" >' . $LANG->getLL(
'Please wait') .
'</div> 504 <div id="editorWrap' . $textAreaId .
'" class="editorWrap" style="visibility: hidden; width:' . $editorWrapWidth .
'; height:' . $editorWrapHeight .
';"> 505 <textarea id="RTEarea' . $textAreaId .
'" name="' . htmlspecialchars($PA[
'itemFormElName']) .
'" rows="0" cols="0" style="' . htmlspecialchars($this->RTEdivStyle, ENT_COMPAT,
'UTF-8', FALSE) .
'">' .
GeneralUtility::formatForTextarea($value) .
'</textarea> 528 $fileName = trim($this->thisConfig[
'contentCSS']);
531 if (!$fileName || !file_exists($absolutePath) || !filesize($absolutePath)) {
532 $fileName =
'EXT:' . $this->ID .
'/res/contentcss/default.css';
545 $skinFilename = trim($this->thisConfig[
'skin']) ?:
'EXT:' . $this->ID .
'/htmlarea/skins/default/htmlarea.css';
547 $skinDir = dirname($this->editorCSS);
549 $this->editedContentCSS = $skinDir .
'/htmlarea-edited-content.css';
550 $this->
addStyleSheet(
'rtehtmlarea-editing-area-skin', $this->editedContentCSS);
554 foreach ($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] as $pluginId) {
555 if (is_object($this->registeredPlugins[$pluginId])) {
556 $pathToSkin = $this->registeredPlugins[$pluginId]->getPathToSkin();
558 $key = $this->registeredPlugins[$pluginId]->getExtensionKey();
574 protected function addStyleSheet($key, $href, $title =
'', $relation =
'stylesheet') {
576 if (is_object($this->TCEform->inline) && $this->TCEform->inline->isAjaxCall) {
577 $this->TCEform->additionalCode_pre[$key] =
'<link rel="' . $relation .
'" type="text/css" href="' . $href .
'" title="' . $title .
'" />';
579 $this->pageRenderer->addCssFile($href, $relation,
'screen', $title);
597 if ($this->TCEform->RTEcounter > 1 && isset($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter - 1]) && is_array($this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter - 1])) {
598 $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter] = array_unique(array_values(array_merge($this->pluginEnabledArray, $this->pluginEnabledCumulativeArray[$this->TCEform->RTEcounter - 1])));
610 if (is_array($TYPO3_CONF_VARS[
'EXTCONF'][$this->ID][
'plugins'])) {
611 foreach ($TYPO3_CONF_VARS[
'EXTCONF'][$this->ID][
'plugins'] as $pluginId => $pluginObjectConfiguration) {
613 if (is_array($pluginObjectConfiguration) && count($pluginObjectConfiguration)) {
616 if (is_object($plugin)) {
617 if ($plugin->main($this)) {
618 $this->registeredPlugins[$pluginId] = $plugin;
621 foreach ($this->pluginButton as $previousPluginId => $buttonList) {
622 $this->pluginButton[$previousPluginId] = implode(
',', array_diff(
GeneralUtility::trimExplode(
',', $this->pluginButton[$previousPluginId], TRUE), $pluginButtons));
624 $this->pluginButton[$pluginId] = $plugin->getPluginButtons();
626 foreach ($this->pluginLabel as $previousPluginId => $labelList) {
627 $this->pluginLabel[$previousPluginId] = implode(
',', array_diff(
GeneralUtility::trimExplode(
',', $this->pluginLabel[$previousPluginId], TRUE), $pluginLabels));
629 $this->pluginLabel[$pluginId] = $plugin->getPluginLabels();
630 $this->pluginEnabledArray[] = $pluginId;
636 $hidePlugins = array();
637 foreach ($this->registeredPlugins as $pluginId => $plugin) {
638 if ($plugin->addsButtons() && !$this->pluginButton[$pluginId]) {
639 $hidePlugins[] = $pluginId;
642 $this->pluginEnabledArray = array_unique(array_diff($this->pluginEnabledArray, $hidePlugins));
651 if ($this->client[
'browser'] ==
'msie' || $this->client[
'browser'] ==
'opera') {
652 $this->thisConfig[
'keepButtonGroupTogether'] = 0;
654 $this->defaultToolbarOrder =
'bar, blockstylelabel, blockstyle, space, textstylelabel, textstyle, linebreak, 655 bar, formattext, bold, strong, italic, emphasis, big, small, insertedtext, deletedtext, citation, code, definition, keyboard, monospaced, quotation, sample, variable, bidioverride, strikethrough, subscript, superscript, underline, span, 656 bar, fontstyle, space, fontsize, bar, formatblock, insertparagraphbefore, insertparagraphafter, blockquote, line, 657 bar, left, center, right, justifyfull, 658 bar, orderedlist, unorderedlist, definitionlist, definitionitem, outdent, indent, bar, lefttoright, righttoleft, language, showlanguagemarks, 659 bar, textcolor, bgcolor, textindicator, 660 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, 661 bar, chMode, inserttag, removeformat, bar, copy, cut, paste, pastetoggle, pastebehaviour, bar, undo, redo, bar, showhelp, about, linebreak, 662 ' . ($this->thisConfig[
'hideTableOperationsInToolbar'] ?
'' :
'bar, toggleborders,') .
' bar, tableproperties, tablerestyle, bar, rowproperties, rowinsertabove, rowinsertunder, rowdelete, rowsplit, bar, 663 columnproperties, columninsertbefore, columninsertafter, columndelete, columnsplit, bar, 664 cellproperties, cellinsertbefore, cellinsertafter, celldelete, cellsplit, cellmerge';
666 foreach ($this->registeredPlugins as $pluginId => $plugin) {
668 $this->defaultToolbarOrder = $plugin->addButtonsToToolbar();
674 $toolbarOrder = array_unique(array_values($this->toolbarOrderArray));
676 $pList = is_array($this->specConf[
'richtext'][
'parameters']) ? implode(
',', $this->specConf[
'richtext'][
'parameters']) :
'';
679 $show = is_array($this->specConf[
'richtext'][
'parameters']) ? $this->specConf[
'richtext'][
'parameters'] : array();
680 if ($this->thisConfig[
'showButtons']) {
684 $show = array_unique(array_merge($show, $toolbarOrder));
687 if (is_array($this->thisConfig[
'showButtons.'])) {
688 foreach ($this->thisConfig[
'showButtons.'] as $buttonId => $value) {
693 $show = array_unique($show);
696 $show = $toolbarOrder;
699 if (is_object(
$GLOBALS[
'BE_USER'])) {
700 $RTEkeyList = isset(
$GLOBALS[
'BE_USER']->userTS[
'options.'][
'RTEkeyList']) ?
$GLOBALS[
'BE_USER']->userTS[
'options.'][
'RTEkeyList'] :
'*';
701 if ($RTEkeyList !=
'*') {
707 $hideButtons = array(
'space',
'bar',
'linebreak');
708 foreach ($this->pluginButton as $pluginId => $buttonList) {
711 foreach ($buttonArray as $button) {
712 $hideButtons[] = $button;
717 foreach ($this->pluginLabel as $pluginId => $label) {
719 $hideButtons[] = $label;
725 foreach ($this->registeredPlugins as $pluginId => $plugin) {
726 if ($this->
isPluginEnabled($pluginId) && method_exists($plugin,
'applyToolbarConstraints')) {
727 $show = $plugin->applyToolbarConstraints($show);
731 $show = array_intersect($show, $toolbarOrder);
732 $this->toolbar = $show;
742 $hidePlugins = array();
743 foreach ($this->pluginButton as $pluginId => $buttonList) {
744 if ($this->registeredPlugins[$pluginId]->addsButtons()) {
747 foreach ($buttonArray as $button) {
748 if (in_array($button, $this->toolbar)) {
753 $hidePlugins[] = $pluginId;
757 $this->pluginEnabledArray = array_diff($this->pluginEnabledArray, $hidePlugins);
759 $hideLabels = array();
760 foreach ($this->pluginLabel as $pluginId => $label) {
762 $hideLabels[] = $label;
765 $this->toolbar = array_diff($this->toolbar, $hideLabels);
767 $requiredPlugins = array();
768 foreach ($this->registeredPlugins as $pluginId => $plugin) {
773 $requiredPlugins = array_unique($requiredPlugins);
774 foreach ($requiredPlugins as $pluginId) {
775 if (is_object($this->registeredPlugins[$pluginId]) && !$this->
isPluginEnabled($pluginId)) {
776 $this->pluginEnabledArray[] = $pluginId;
779 $this->pluginEnabledArray = array_unique($this->pluginEnabledArray);
781 foreach ($this->registeredPlugins as $pluginId => $plugin) {
783 $this->convertToolbarForHtmlAreaArray = array_unique(array_merge($this->convertToolbarForHtmlAreaArray, $plugin->getConvertToolbarForHtmlAreaArray()));
796 return $this->convertToolbarForHtmlAreaArray[$button];
806 $this->pageRenderer->addJsFile($this->
getFullFileName(
'EXT:' . $this->ID .
'/htmlarea/htmlarea.js'));
807 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) {
808 $extensionKey = is_object($this->registeredPlugins[$pluginId]) ? $this->registeredPlugins[$pluginId]->getExtensionKey() :
$this->ID;
809 $this->pageRenderer->addJsFile($this->
getFullFileName(
'EXT:' . $extensionKey .
'/htmlarea/plugins/' . $pluginId .
'/' . strtolower(preg_replace(
'/([a-z])([A-Z])([a-z])/',
'$1-$2$3', $pluginId)) .
'.js'));
820 if (typeof(RTEarea) == "undefined") { 821 RTEarea = new Object(); 822 RTEarea[0] = new Object(); 823 RTEarea[0].version = "' .
$GLOBALS[
'TYPO3_CONF_VARS'][
'EXTCONF'][
$this->ID][
'version'] .
'"; 824 RTEarea[0].editorUrl = "' . $this->extHttpPath .
'htmlarea/"; 826 RTEarea[0].editorSkin = "' . dirname($this->editorCSS) .
'/"; 828 RTEarea[0].hostUrl = "' . $this->hostURL .
'"; 829 RTEarea.init = function() { 830 if (typeof(HTMLArea) == "undefined" || !Ext.isReady) { 831 window.setTimeout("RTEarea.init();", 10); 833 Ext.QuickTips.init(); 837 RTEarea.initEditor = function(editorNumber) { 838 if (typeof(HTMLArea) == "undefined" || !HTMLArea.isReady) { 839 RTEarea.initEditor.defer(40, null, [editorNumber]); 841 HTMLArea.initEditor(editorNumber); 860 $configureRTEInJavascriptString =
' 861 if (typeof(configureEditorInstance) == "undefined") { 862 configureEditorInstance = new Object(); 864 configureEditorInstance["' . $textAreaId .
'"] = function() { 865 if (typeof(RTEarea) == "undefined" || typeof(HTMLArea) == "undefined") { 866 window.setTimeout("configureEditorInstance[\'' . $textAreaId .
'\']();
", 40); 868 editornumber = "' . $textAreaId . '"; 869 RTEarea[editornumber] = new Object(); 870 RTEarea[editornumber].RTEtsConfigParams = "&
RTEtsConfigParams=
' . rawurlencode($this->RTEtsConfigParams()) . '"; 871 RTEarea[editornumber].number = editornumber; 872 RTEarea[editornumber].deleted = false; 873 RTEarea[editornumber].textAreaId = "' . $textAreaId . '"; 874 RTEarea[editornumber].id = "RTEarea
" + editornumber; 875 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
'])) . '"; 876 RTEarea[editornumber].RTEHeightOverride = "' . (is_object($GLOBALS['BE_USER
']) && isset($GLOBALS['BE_USER
']->uc['rteHeight
']) && (int)$GLOBALS['BE_USER
']->uc['rteHeight
'] ? (int)$GLOBALS['BE_USER
']->uc['rteHeight
'] : (int)$this->thisConfig['RTEHeightOverride
']) . '"; 877 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')) . '; 878 RTEarea[editornumber].maxHeight = "' . (is_object($GLOBALS['BE_USER
']) && isset($GLOBALS['BE_USER
']->uc['rteMaxHeight
']) && (int)$GLOBALS['BE_USER
']->uc['rteMaxHeight
'] ? trim($GLOBALS['BE_USER
']->uc['rteMaxHeight
']) : ((int)$this->thisConfig['rteMaxHeight
'] ?: '2000
')) . '"; 879 RTEarea[editornumber].fullScreen = ' . ($this->fullScreen ? 'true' : 'false') . '; 880 RTEarea[editornumber].showStatusBar = ' . (trim($this->thisConfig['showStatusBar']) ? 'true' : 'false') . '; 881 RTEarea[editornumber].enableWordClean = ' . (trim($this->thisConfig['enableWordClean']) ? 'true' : 'false') . '; 882 RTEarea[editornumber].htmlRemoveComments = ' . (trim($this->thisConfig['removeComments']) ? 'true' : 'false') . '; 883 RTEarea[editornumber].disableEnterParagraphs = ' . (trim($this->thisConfig['disableEnterParagraphs']) ? 'true' : 'false') . '; 884 RTEarea[editornumber].disableObjectResizing = ' . (trim($this->thisConfig['disableObjectResizing']) ? 'true' : 'false') . '; 885 RTEarea[editornumber].removeTrailingBR = ' . (trim($this->thisConfig['removeTrailingBR']) ? 'true' : 'false') . '; 886 RTEarea[editornumber].useCSS = ' . (trim($this->thisConfig['useCSS']) ? 'true' : 'false') . '; 887 RTEarea[editornumber].keepButtonGroupTogether = ' . (trim($this->thisConfig['keepButtonGroupTogether']) ? 'true' : 'false') . '; 888 RTEarea[editornumber].disablePCexamples = ' . (trim($this->thisConfig['disablePCexamples']) ? 'true' : 'false') . '; 889 RTEarea[editornumber].showTagFreeClasses = ' . (trim($this->thisConfig['showTagFreeClasses']) ? 'true' : 'false') . '; 890 RTEarea[editornumber].useHTTPS = ' . (trim(stristr($this->siteURL, 'https')) || $this->thisConfig['forceHTTPS'] ? 'true' : 'false') . '; 891 RTEarea[editornumber].tceformsNested = ' . (is_object($this->TCEform) && method_exists($this->TCEform, 'getDynNestedStack') ? $this->TCEform->getDynNestedStack(TRUE) : '[]') . '; 892 RTEarea[editornumber].dialogueWindows = new Object();'; 893 if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromTop'])) { 894 $configureRTEInJavascriptString .= ' 895 RTEarea[editornumber].dialogueWindows.positionFromTop = ' . (int)$this->thisConfig['dialogueWindows.']['defaultPositionFromTop'] . ';'; 897 if (isset($this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'])) { 898 $configureRTEInJavascriptString .= ' 899 RTEarea[editornumber].dialogueWindows.positionFromLeft = ' . (int)$this->thisConfig['dialogueWindows.']['defaultPositionFromLeft'] . ';'; 901 // The following properties apply only to the backend 902 if (!$this->is_FE()) { 903 $configureRTEInJavascriptString .= ' 904 RTEarea[editornumber].sys_language_content = "' . $this->contentLanguageUid . '"; 905 RTEarea[editornumber].typo3ContentLanguage = "' . $this->contentTypo3Language . '"; 906 RTEarea[editornumber].typo3ContentCharset = "' . $this->contentCharset . '"; 907 RTEarea[editornumber].userUid = "' . $this->userUid . '";'; 909 // Setting the plugin flags 910 $configureRTEInJavascriptString .= ' 911 RTEarea[editornumber].plugin = new Object(); 912 RTEarea[editornumber].pathToPluginDirectory = new Object();'; 913 foreach ($this->pluginEnabledArray as $pluginId) { 914 $configureRTEInJavascriptString .= ' 915 RTEarea[editornumber].plugin.' . $pluginId . ' = true;'; 916 if (is_object($this->registeredPlugins[$pluginId])) { 917 $pathToPluginDirectory = $this->registeredPlugins[$pluginId]->getPathToPluginDirectory(); 918 if ($pathToPluginDirectory) { 919 $configureRTEInJavascriptString .= ' 920 RTEarea[editornumber].pathToPluginDirectory.' . $pluginId . ' = "' . $pathToPluginDirectory . '";'; 924 // Setting the buttons configuration 925 $configureRTEInJavascriptString .= ' 926 RTEarea[editornumber].buttons = new Object();'; 927 if (is_array($this->thisConfig['buttons.'])) { 928 foreach ($this->thisConfig['buttons.'] as $buttonIndex => $conf) { 929 $button = substr($buttonIndex, 0, -1); 930 if (is_array($conf)) { 931 $configureRTEInJavascriptString .= ' 932 RTEarea[editornumber].buttons.' . $button . ' = ' . $this->buildNestedJSArray($conf) . ';'; 936 // Setting the list of tags to be removed if specified in the RTE config 937 if (trim($this->thisConfig['removeTags'])) { 938 $configureRTEInJavascriptString .= ' 939 RTEarea[editornumber].htmlRemoveTags = /^(' . implode('|', GeneralUtility::trimExplode(',', $this->thisConfig['removeTags'], TRUE)) . ')$/i;'; 941 // Setting the list of tags to be removed with their contents if specified in the RTE config 942 if (trim($this->thisConfig['removeTagsAndContents'])) { 943 $configureRTEInJavascriptString .= ' 944 RTEarea[editornumber].htmlRemoveTagsAndContents = /^(' . implode('|', GeneralUtility::trimExplode(',', $this->thisConfig['removeTagsAndContents'], TRUE)) . ')$/i;'; 946 // Setting array of custom tags if specified in the RTE config 947 if (!empty($this->thisConfig['customTags'])) { 948 $customTags = GeneralUtility::trimExplode(',', $this->thisConfig['customTags'], TRUE); 949 if (!empty($customTags)) { 950 $configureRTEInJavascriptString .= ' 951 RTEarea[editornumber].customTags= ' . json_encode($customTags) . ';'; 954 // Setting the pageStyle 955 $configureRTEInJavascriptString .= ' 956 RTEarea[editornumber].pageStyle = "' . GeneralUtility::createVersionNumberedFilename($this->getContentCssFileName()) . '";'; 957 // Process classes configuration 958 $classesConfigurationRequired = FALSE; 959 foreach ($this->registeredPlugins as $pluginId => $plugin) { 960 if ($this->isPluginEnabled($pluginId)) { 961 $classesConfigurationRequired = $classesConfigurationRequired || $plugin->requiresClassesConfiguration(); 964 if ($classesConfigurationRequired) { 965 $configureRTEInJavascriptString .= $this->buildJSClassesConfig($RTEcounter); 967 // Add Javascript configuration for registered plugins 968 foreach ($this->registeredPlugins as $pluginId => $plugin) { 969 if ($this->isPluginEnabled($pluginId)) { 970 $configureRTEInJavascriptString .= $plugin->buildJavascriptConfiguration('editornumber'); 973 // Avoid premature reference to HTMLArea when being initially loaded by IRRE Ajax call 974 $configureRTEInJavascriptString .= ' 975 RTEarea[editornumber].toolbar = ' . $this->getJSToolbarArray() . '; 976 RTEarea[editornumber].convertButtonId = ' . json_encode(array_flip($this->convertToolbarForHtmlAreaArray)) . '; 977 RTEarea.initEditor(editornumber); 980 configureEditorInstance["' . $textAreaId . '"]();'; 981 return $configureRTEInJavascriptString; 991 public function isPluginEnabled($pluginId) { 992 return in_array($pluginId, $this->pluginEnabledArray); 1002 public function buildStyleSheet() { 1003 $stylesheet = '/* mainStyleOverride and inlineStyle properties ignored. */'; 1014 public function buildJSClassesConfig($RTEcounter) { 1015 // Include JS arrays of configured classes 1016 $configureRTEInJavascriptString .= ' 1017 RTEarea[editornumber].classesUrl = "' . ($this->is_FE() && $GLOBALS['TSFE
']->absRefPrefix ? $GLOBALS['TSFE
']->absRefPrefix : '') . $this->writeTemporaryFile('', ('classes_
' . $this->language), 'js
', $this->buildJSClassesArray(), TRUE) . '";'; 1018 return $configureRTEInJavascriptString; 1027 public function buildJSClassesArray() { 1028 if ($this->is_FE()) { 1029 $RTEProperties = $this->RTEsetup; 1031 $RTEProperties = $this->RTEsetup['properties']; 1033 $classesArray = array('labels' => array(), 'values' => array(), 'noShow' => array(), 'alternating' => array(), 'counting' => array(), 'XOR' => array()); 1034 $JSClassesArray = ''; 1035 // Scanning the list of classes if specified in the RTE config 1036 if (is_array($RTEProperties['classes.'])) { 1037 foreach ($RTEProperties['classes.'] as $className => $conf) { 1038 $className = rtrim($className, '.'); 1040 if (!empty($conf['name'])) { 1041 $label = $this->getPageConfigLabel($conf['name'], FALSE); 1043 $classesArray['labels'][$className] = $label; 1044 $classesArray['values'][$className] = str_replace('\\\'', '\'', $conf['value']); 1045 if (isset($conf['noShow'])) { 1046 $classesArray['noShow'][$className] = $conf['noShow']; 1048 if (is_array($conf['alternating.'])) { 1049 $classesArray['alternating'][$className] = $conf['alternating.']; 1051 if (is_array($conf['counting.'])) { 1052 $classesArray['counting'][$className] = $conf['counting.']; 1056 // Scanning the list of sets of mutually exclusives classes if specified in the RTE config 1057 if (is_array($RTEProperties['mutuallyExclusiveClasses.'])) { 1058 foreach ($RTEProperties['mutuallyExclusiveClasses.'] as $listName => $conf) { 1059 $classSet = GeneralUtility::trimExplode(',', $conf, TRUE); 1060 $classList = implode(',', $classSet); 1061 foreach ($classSet as $className) { 1062 $classesArray['XOR'][$className] = '/^(' . implode('|', GeneralUtility::trimExplode(',', GeneralUtility::rmFromList($className, $classList), TRUE)) . ')$/'; 1066 foreach ($classesArray as $key => $subArray) { 1067 $JSClassesArray .= 'HTMLArea.classes' . ucfirst($key) . ' = ' . $this->buildNestedJSArray($subArray) . ';' . LF; 1069 return $JSClassesArray; 1082 public function buildNestedJSArray($conf) { 1083 $convertedConf = GeneralUtility::removeDotsFromTS($conf); 1084 return str_replace(array(':"0
"', ':"\\/^(
', ')$\\/i
"', ':"\\/^(
', ')$\\/
"', '[]'), array(':false', ':/^(', ')$/i', ':/^(', ')$/', '{}'), json_encode($convertedConf)); 1093 public function buildJSMainLangArray() { 1094 $JSLanguageArray = 'HTMLArea.I18N = new Object();' . LF; 1095 $labelsArray = array('tooltips' => array(), 'msg' => array(), 'dialogs' => array()); 1096 foreach ($labelsArray as $labels => $subArray) { 1097 $LOCAL_LANG = GeneralUtility::readLLfile('EXT:' . $this->ID . '/htmlarea/locallang_' . $labels . '.xlf', $this->language, 'utf-8'); 1098 if (!empty($LOCAL_LANG[$this->language])) { 1099 $mergedLocalLang = $LOCAL_LANG['default']; 1100 \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($mergedLocalLang, $LOCAL_LANG[$this->language], TRUE, FALSE); 1101 $LOCAL_LANG[$this->language] = $mergedLocalLang; 1103 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default']; 1105 $labelsArray[$labels] = $LOCAL_LANG[$this->language]; 1107 $JSLanguageArray .= 'HTMLArea.I18N = ' . json_encode($labelsArray) . ';' . LF; 1108 return $JSLanguageArray; 1121 public function writeTemporaryFile($sourceFileName = '', $label, $fileExtension = 'js', $contents = '', $concatenate = FALSE) { 1122 if ($sourceFileName) { 1124 $source = GeneralUtility::getFileAbsFileName($sourceFileName); 1125 $output = file_get_contents($source); 1127 $output = $contents; 1129 $relativeFilename = 'typo3temp/' . $this->ID . '_' . str_replace('-', '_', $label) . '_' . GeneralUtility::shortMD5((TYPO3_version . $TYPO3_CONF_VARS['EXTCONF'][$this->ID]['version'] . ($sourceFileName ? $sourceFileName : $output)), 20) . '.' . $fileExtension; 1130 $destination = PATH_site . $relativeFilename; 1131 if (!file_exists($destination)) { 1132 $minifiedJavaScript = ''; 1133 if ($fileExtension == 'js' && $output != '') { 1134 $minifiedJavaScript = GeneralUtility::minifyJavaScript($output); 1136 $failure = GeneralUtility::writeFileToTypo3tempDir($destination, $minifiedJavaScript ? $minifiedJavaScript : $output); 1138 throw new \RuntimeException($failure, 1294585668); 1141 if ($this->is_FE()) { 1142 $filename = $relativeFilename; 1144 $filename = ($this->isFrontendEditActive() ? '' : $this->backPath . '../') . $relativeFilename; 1146 return GeneralUtility::resolveBackPath($filename); 1156 public function buildJSMainLangFile($RTEcounter) { 1157 $contents = $this->buildJSMainLangArray() . LF; 1158 foreach ($this->pluginEnabledCumulativeArray[$RTEcounter] as $pluginId) { 1159 $contents .= $this->buildJSLangArray($pluginId) . LF; 1161 return $this->writeTemporaryFile('', $this->language . '_' . $this->OutputCharset, 'js', $contents, TRUE); 1171 public function buildJSLangArray($plugin) { 1172 $extensionKey = is_object($this->registeredPlugins[$plugin]) ? $this->registeredPlugins[$plugin]->getExtensionKey() : $this->ID; 1173 $LOCAL_LANG = GeneralUtility::readLLfile('EXT:' . $extensionKey . '/htmlarea/plugins/' . $plugin . '/locallang.xlf', $this->language, 'utf-8', 1); 1174 $JSLanguageArray = 'HTMLArea.I18N["' . $plugin . '"] = new Object();' . LF; 1175 if (is_array($LOCAL_LANG)) { 1176 if (!empty($LOCAL_LANG[$this->language])) { 1177 $defaultLocalLang = $LOCAL_LANG['default']; 1178 \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($defaultLocalLang, $LOCAL_LANG[$this->language], TRUE, FALSE); 1179 $LOCAL_LANG[$this->language] = $defaultLocalLang; 1181 $LOCAL_LANG[$this->language] = $LOCAL_LANG['default']; 1183 $JSLanguageArray .= 'HTMLArea.I18N["' . $plugin . '"] = ' . json_encode($LOCAL_LANG[$this->language]) . ';' . LF; 1185 return $JSLanguageArray; 1193 protected function getJSToolbarArray() { 1194 // The toolbar array 1196 // The current row; a "linebreak
" ends the current row 1198 // The current group; each group is between "bar
"s; a "linebreak
" ends the current group 1200 // Process each toolbar item in the toolbar order list 1201 foreach ($this->toolbarOrderArray as $item) { 1204 // Add row to toolbar if not empty 1205 if (!empty($group)) { 1215 // Add group to row if not empty 1216 if (!empty($group)) { 1222 if (end($group) != $this->convertToolbarForHTMLArea($item)) { 1223 $group[] = $this->convertToolbarForHTMLArea($item); 1227 if (in_array($item, $this->toolbar)) { 1228 // Add the item to the group 1229 $convertedItem = $this->convertToolbarForHTMLArea($item); 1230 if ($convertedItem) { 1231 $group[] = $convertedItem; 1236 // Add the last group and last line, if not empty 1237 if (!empty($group)) { 1243 return json_encode($toolbar); 1252 public function getLLContent($string) { 1253 return GeneralUtility::quoteJSvalue($this->contentLanguageService->sL($string)); 1256 public function getPageConfigLabel($string, $JScharCode = 1) { 1257 global $LANG, $TSFE, $TYPO3_CONF_VARS; 1258 if ($this->is_FE()) { 1259 if (substr($string, 0, 4) !== 'LLL:') { 1260 // A pure string coming from Page TSConfig must be in utf-8 1261 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), 'utf-8', $this->OutputCharset); 1263 $label = $TSFE->csConvObj->conv($TSFE->sL(trim($string)), $this->charset, $this->OutputCharset); 1265 $label = str_replace('"', '\\
"', str_replace('\\\'', '\'', $label)); 1266 $label = $JScharCode ? $this->feJScharCode($label) : $label; 1268 if (substr($string, 0, 4) !== 'LLL:') { 1271 $label = $LANG->sL(trim($string)); 1273 $label = str_replace('"', '\\
"', str_replace('\\\'', '\'', $label)); 1274 $label = $JScharCode ? GeneralUtility::quoteJSvalue($label) : $label; 1282 public function feJScharCode($str) { 1283 // Convert string to UTF-8: 1284 if ($this->OutputCharset != 'utf-8') { 1285 $str = $GLOBALS['TSFE']->csConvObj->utf8_encode($str, $this->OutputCharset); 1287 // Convert the UTF-8 string into a 'JavaScript-safe' encoded string: 1288 return GeneralUtility::quoteJSvalue($str); 1297 public function getFullFileName($filename) { 1298 if (substr($filename, 0, 4) == 'EXT:') { 1300 list($extKey, $local) = explode('/', substr($filename, 4), 2); 1302 if ((string)$extKey !== '' && \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded($extKey) && (string)$local !== '') { 1303 $newFilename = ($this->is_FE() || $this->isFrontendEditActive() ? \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::siteRelPath($extKey) : $this->backPath . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($extKey)) . $local; 1306 $path = ($this->is_FE() || $this->isFrontendEditActive() ? '' : $this->backPath . '../'); 1307 $newFilename = $path . ($filename[0] === '/' ? substr($filename, 1) : $filename); 1309 return GeneralUtility::resolveBackPath($newFilename); 1323 public function setSaveRTE($RTEcounter, $formName, $textareaId, $textareaName) { 1324 return 'if (RTEarea[' . GeneralUtility::quoteJSvalue($textareaId) . ']) { document.' . $formName . '[' . GeneralUtility::quoteJSvalue($textareaName) . '].value = RTEarea[' . GeneralUtility::quoteJSvalue($textareaId) . '].editor.getHTML(); } else { OK = 0; };'; 1337 public function setDeleteRTE($RTEcounter, $formName, $textareaId) { 1338 return 'if (RTEarea[' . GeneralUtility::quoteJSvalue($textareaId) . ']) { RTEarea[' . GeneralUtility::quoteJSvalue($textareaId) . '].deleted = true;}'; 1347 public function is_FE() { 1348 return is_object($GLOBALS['TSFE']) && !$this->isFrontendEditActive() && TYPO3_MODE == 'FE'; 1356 public function isFrontendEditActive() { 1357 return is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->beUserLogin && $GLOBALS['BE_USER']->frontendEdit instanceof \TYPO3\CMS\Core\FrontendEditing\FrontendEditingController; 1367 public function clientInfo($userAgent = '') { 1369 $userAgent = GeneralUtility::getIndpEnv('HTTP_USER_AGENT'); 1371 $browserInfo = \TYPO3\CMS\Core\Utility\ClientUtility::getBrowserInfo($userAgent); 1372 // Known engines: order is not irrelevant! 1373 $knownEngines = array('opera', 'msie', 'edge', 'gecko', 'webkit'); 1374 if (is_array($browserInfo['all'])) { 1375 foreach ($knownEngines as $engine) { 1376 if ($browserInfo['all'][$engine]) { 1377 $browserInfo['browser'] = $engine; 1378 $browserInfo['version'] = \TYPO3\CMS\Core\Utility\ClientUtility::getVersion($browserInfo['all'][$engine]); 1383 return $browserInfo; 1394 public function logDeprecatedProperty($deprecatedProperty, $useProperty, $version) { 1395 if (!$this->thisConfig['logDeprecatedProperties.']['disabled']) { 1396 $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); 1397 GeneralUtility::deprecationLog($message); 1398 if (is_object($GLOBALS['BE_USER']) && $this->thisConfig['logDeprecatedProperties.']['logAlsoToBELog']) { 1399 $message = sprintf($GLOBALS['LANG']->getLL('deprecatedPropertyMessage'), $deprecatedProperty, $useProperty, $version, $this->thePid); 1400 $GLOBALS['BE_USER']->simplelog($message, $this->ID); 1405 /*************************** 1407 * OTHER FUNCTIONS: (from Classic RTE) 1409 ***************************/ 1415 public function RTEtsConfigParams() { 1416 if ($this->is_FE()) { 1419 $p = BackendUtility::getSpecConfParametersFromArray($this->specConf['rte_transform']['parameters']); 1420 return $this->elementParts[0] . ':' . $this->elementParts[1] . ':' . $this->elementParts[2] . ':' . $this->thePid . ':' . $this->typeVal . ':' . $this->tscPID . ':' . $p['imgpath']; 1424 public function cleanList($str) { 1425 if (strstr($str, '*')) { 1428 $str = implode(',', array_unique(GeneralUtility::trimExplode(',', $str, TRUE))); 1436 public function filterStyleEl($elValue, $matchList) { 1437 $matchParts = GeneralUtility::trimExplode(',', $matchList, TRUE); 1438 $styleParts = explode(';', $elValue); 1440 foreach ($styleParts as $k => $p) { 1441 $pp = GeneralUtility::trimExplode(':', $p); 1442 if ($pp[0] && $pp[1]) { 1443 foreach ($matchParts as $el) { 1444 $star = substr($el, -1) == '*'; 1445 if ($pp[0] === (string)$el || $star && GeneralUtility::isFirstPartOfStr($pp[0], substr($el, 0, -1))) { 1446 $nStyle[] = $pp[0] . ':' . $pp[1]; 1448 unset($styleParts[$k]); 1452 unset($styleParts[$k]); 1455 return implode('; ', $nStyle); 1458 // Hook on lorem_ipsum extension to insert text into the RTE in wysiwyg mode 1463 public function loremIpsumInsert($params) { 1464 GeneralUtility::logDeprecatedFunction(); 1466 if (typeof(lorem_ipsum) == \'function\' && ' . $params['element'] . '.tagName.toLowerCase() == \'textarea\' ) lorem_ipsum(' . $params['element'] . ', lipsum_temp_strings[lipsum_temp_pointer]);
$convertToolbarForHtmlAreaArray
$TYPO3_CONF_VARS['SYS']['contentTable']
getFullFileName($filename)
static formatForTextarea($content)
drawRTE(&$pObj, $table, $field, $row, $PA, $specConf, $thisConfig, $RTEtypeVal, $RTErelPath, $thePidValue)
$pluginEnabledCumulativeArray
buildJSMainLangFile($RTEcounter)
setSaveRTE($RTEcounter, $formName, $textareaId, $textareaName)
static getIndpEnv($getEnvName)
static getUserObj($classRef, $checkPrefix='', $silent=FALSE)
enableRegisteredPlugins()
static makeInstance($className)
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
static getTSCpid($table, $uid, $pid)
convertToolbarForHTMLArea($button)
isPluginEnabled($pluginId)
setDeleteRTE($RTEcounter, $formName, $textareaId)
addStyleSheet($key, $href, $title='', $relation='stylesheet')
static createVersionNumberedFilename($file, $forceQueryString=FALSE)
transformContent($dirRTE, $value, $table, $field, $row, $specConf, $thisConfig, $RTErelPath, $pid)
static isLoaded($key, $exitOnError=FALSE)
registerRTEinJS($RTEcounter, $table='', $uid='', $field='', $textAreaId='')
static convertVersionNumberToInteger($versionNumber)
addRteJsFiles($RTEcounter)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
clientInfo($userAgent='')
static inList($list, $item)
static getFileAbsFileName($filename, $onlyRelative=TRUE, $relToTYPO3_mainDir=FALSE)
static getPagesTSconfig($id, $rootLine=NULL, $returnPartArray=FALSE)
static BEenableFields($table, $inv=0)
static deleteClause($table, $tableAlias='')
initializeToolbarConfiguration()