[FEATURE] Allow adding multiple CSS files in RTE 23/24523/10
authorStanislas Rolland <typo3@sjbr.ca>
Thu, 23 Oct 2014 01:54:46 +0000 (21:54 -0400)
committerStanislas Rolland <typo3@sjbr.ca>
Thu, 23 Oct 2014 12:48:43 +0000 (14:48 +0200)
Allow to add more than one CSS file in the RTE header.

The new syntax is like this:
    RTE.default.contentCSS {
        file1 = fileadmin/myStylesheet1.css
        file2 = fileadmin/myStylesheet2.css
    }

If no CSS files are set, the RTE default CSS file is still added.

Releases: master
Resolves: #50039
Change-Id: I4b8545982a59382ca4e01abc4440f0b94693ccdc
Reviewed-on: http://review.typo3.org/24523
Reviewed-by: Stanislas Rolland <typo3@sjbr.ca>
Tested-by: Stanislas Rolland <typo3@sjbr.ca>
typo3/sysext/core/Documentation/Changelog/master/Feature-50039-MultipleCssFilesInRte.rst [new file with mode: 0644]
typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaBase.php
typo3/sysext/rtehtmlarea/Documentation/Configuration/PageTsconfig/interfaceConfiguration/Index.rst
typo3/sysext/rtehtmlarea/htmlarea/CSS/HTMLArea.CSS.Parser.js
typo3/sysext/rtehtmlarea/htmlarea/Configuration/HTMLArea.Config.js
typo3/sysext/rtehtmlarea/htmlarea/Editor/HTMLArea.Iframe.js

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-50039-MultipleCssFilesInRte.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-50039-MultipleCssFilesInRte.rst
new file mode 100644 (file)
index 0000000..8d39a07
--- /dev/null
@@ -0,0 +1,22 @@
+========================================================
+Feature: #50039 - Multiple CSS Files in Rich Text Editor
+========================================================
+
+Description
+===========
+
+It is now possible to import more than one CSS file for the Rich Text Editor.
+
+New syntax is::
+
+       RTE.default.contentCSS {
+               file1 = fileadmin/myStylesheet1.css
+               file2 = fileadmin/myStylesheet2.css
+       }
+
+
+Impact
+======
+
+The old syntax may still be used. If no CSS files are set, the RTE default CSS
+file is used as before.
index 81d1049..e6f5d5b 100644 (file)
@@ -502,31 +502,46 @@ class RteHtmlAreaBase extends \TYPO3\CMS\Backend\Rte\AbstractRte {
        }
 
        /**
-        * Add link to content style sheet to document header
+        * Add links to content style sheets to document header
         *
         * @return      void
         */
        protected function addPageStyle() {
-               $this->addStyleSheet('rtehtmlarea-page-style', $this->getContentCssFileName(), 'htmlArea RTE Content CSS', 'alternate stylesheet');
+               $contentCssFileNames = $this->getContentCssFileNames();
+               foreach ($contentCssFileNames as $contentCssKey => $contentCssFile) {
+                       $this->addStyleSheet($contentCssKey, $contentCssFile, 'htmlArea RTE Content CSS', 'alternate stylesheet');
+               }
        }
 
        /**
-        * Get the name of the contentCSS file to use
+        * Get the name of the contentCSS files to use
         *
-        * @return      the full file name of the content css file to use
+        * @return array An array of full file name of the content css files to use
         */
-       protected function getContentCssFileName() {
-               // Get stylesheet file name from Page TSConfig if any
-               $fileName = trim($this->thisConfig['contentCSS']);
-               if ($fileName) {
-                       $fileName = $this->getFullFileName($fileName);
+       protected function getContentCssFileNames() {
+               $contentCss = is_array($this->thisConfig['contentCSS.']) ? $this->thisConfig['contentCSS.'] : array();
+
+               if (isset($this->thisConfig['contentCSS'])) {
+                       $contentCss[] = trim($this->thisConfig['contentCSS']);
+               }
+
+               $contentCssFiles = array();
+
+               if (count($contentCss)) {
+                       foreach ($contentCss as $contentCssKey => $contentCssfile) {
+                               $fileName = $this->getFullFileName($contentCssfile);
+                               $absolutePath = $fileName ? GeneralUtility::resolveBackPath(PATH_site . ($this->is_FE() || $this->isFrontendEditActive() ? '' : TYPO3_mainDir) . $fileName) : '';
+                               if (file_exists($absolutePath) && filesize($absolutePath)) {
+                                       $contentCssFiles[$contentCssKey] = $fileName;
+                               }
+                       }
                }
-               $absolutePath = $fileName ? GeneralUtility::resolveBackPath(PATH_site . ($this->is_FE() || $this->isFrontendEditActive() ? '' : TYPO3_mainDir) . $fileName) : '';
-               // Fallback to default content css file if configured file does not exists or is of zero size
-               if (!$fileName || !file_exists($absolutePath) || !filesize($absolutePath)) {
-                       $fileName = $this->getFullFileName('EXT:' . $this->ID . '/res/contentcss/default.css');
+
+               if (count($contentCssFiles) === 0) {
+                       $contentCssFiles['default'] = $this->getFullFileName('EXT:' . $this->ID . '/res/contentcss/default.css');
                }
-               return $fileName;
+
+               return array_unique($contentCssFiles);
        }
 
        /**
@@ -970,9 +985,14 @@ class RteHtmlAreaBase extends \TYPO3\CMS\Backend\Rte\AbstractRte {
                                RTEarea[editornumber].customTags= ' . json_encode($customTags) . ';';
                        }
                }
-               // Setting the pageStyle
+               // Setting array of content css files if specified in the RTE config
+               $versionNumberedFileNames = array();
+               $contentCssFileNames = $this->getContentCssFileNames();
+               foreach ($contentCssFileNames as $contentCssFileName) {
+                       $versionNumberedFileNames[] = GeneralUtility::createVersionNumberedFilename($contentCssFileName);
+               }
                $configureRTEInJavascriptString .= '
-                       RTEarea[editornumber].pageStyle = "' . GeneralUtility::createVersionNumberedFilename($this->getContentCssFileName()) . '";';
+                       RTEarea[editornumber].pageStyle = ["' . implode('","', $versionNumberedFileNames) . '"];';
                // Process classes configuration
                $classesConfigurationRequired = FALSE;
                foreach ($this->registeredPlugins as $pluginId => $plugin) {
index fda6ae0..933a53f 100644 (file)
@@ -2516,9 +2516,10 @@ contentCSS
 
    Property
          contentCSS
+         contentCSS.[id-string]
    
    Data type
-         resource
+         resource(s)
    
    Description
          The CSS file that contains the style definitions that should be
@@ -2531,6 +2532,13 @@ contentCSS
          
          For example, this default could be overridden with:
          fileadmin/styles/my\_contentCSS.css
+         
+         Multiple files may be specified by using contentCSS.[id-string].
+         For example: 
+         contentCSS {
+               file1 = fileadmin/myStylesheet1.css
+               file2 = fileadmin/myStylesheet2.css
+         }
 
 
 
index d022c99..b0ec459 100644 (file)
@@ -147,7 +147,7 @@ HTMLArea.CSS.Parser = Ext.extend(Ext.util.Observable, {
                        }
                }
                if (this.cssLoaded) {
-                               // Expecting 2 stylesheets...
+                               // Expecting at least 2 stylesheets...
                        if (this.editor.document.styleSheets.length > 1) {
                                var styleSheets = this.editor.document.styleSheets;
                                for (var index = 0, n = styleSheets.length; index < n; index++) {
index 12711b6..a3089fa 100644 (file)
@@ -13,8 +13,8 @@ HTMLArea.Config = function (editorId) {
        this.removeTrailingBR = true;
                // style included in the iframe document
        this.editedContentStyle = HTMLArea.editedContentCSS;
-               // content style
-       this.pageStyle = "";
+               // Array of content styles
+       this.pageStyle = [];
                // Maximum attempts at accessing the stylesheets
        this.styleSheetsMaximumAttempts = 20;
                // Remove tags (must be a regular expression)
index c7039d4..77c87be 100644 (file)
@@ -212,17 +212,16 @@ HTMLArea.Iframe = Ext.extend(Ext.BoxComponent, {
                        head.appendChild(link0);
                        this.getEditor().appendToLog('HTMLArea.Iframe', 'createHead', 'Skin CSS set to: ' + link0.href, 'info');
                }
-               if (this.config.pageStyle) {
-                       var link = this.document.getElementsByTagName('link')[1];
-                       if (!link) {
-                               link = this.document.createElement('link');
-                               link.rel = 'stylesheet';
-                               link.type = 'text/css';
-                               link.href = ((Ext.isGecko && navigator.productSub < 2010072200 && !/^https?:\/{2}/.test(this.config.pageStyle)) ? this.config.baseURL : '') + this.config.pageStyle;
-                               head.appendChild(link);
-                       }
-                       this.getEditor().appendToLog('HTMLArea.Iframe', 'createHead', 'Content CSS set to: ' + link.href, 'info');
-               }
+               var pageStyle;
+               for (var i = 0, n = this.config.pageStyle.length; i < n; i++) {
+                       pageStyle = this.config.pageStyle[i];
+                       var link = this.document.createElement('link');
+                       link.rel = 'stylesheet';
+                       link.type = 'text/css';
+                       link.href = ((Ext.isGecko && navigator.productSub < 2010072200 && !/^https?:\/{2}/.test(pageStyle)) ? this.config.baseURL : '') + pageStyle;
+                       head.appendChild(link);
+                       this.getEditor().appendToLog('HTMLArea.Iframe', 'createHead', 'Content CSS set to: ' + link.href, 'info');
+               }
        },
        /*
         * Focus on the iframe