From 640691f544d21ca86b8c995892fbb3dda45f6bdf Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Mon, 4 Apr 2016 09:59:31 +1200 Subject: [PATCH] BUG fix missing language on non-global configs BUG Prevent external plugins from being passed to the minifier API Change TinyMCEConfig::requireJS to getScriptURL() for testabilitiy --- forms/htmleditor/TinyMCEConfig.php | 56 +++++++++++++++++----------- tests/forms/HtmlEditorConfigTest.php | 21 +++++++++++ 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/forms/htmleditor/TinyMCEConfig.php b/forms/htmleditor/TinyMCEConfig.php index 6cf06fc48..2873f6dbb 100644 --- a/forms/htmleditor/TinyMCEConfig.php +++ b/forms/htmleditor/TinyMCEConfig.php @@ -34,6 +34,7 @@ class TinyMCEConfig extends HtmlEditorConfig { 'remove_script_host' => true, 'convert_urls' => false, // Prevent site-root images being rewritten to base relative 'menubar' => false, + 'language' => 'en', ); /** @@ -198,6 +199,24 @@ class TinyMCEConfig extends HtmlEditorConfig { return $this->plugins; } + /** + * Get list of plugins without custom locations, which is the set of + * plugins which can be loaded via the standard plugin path, and could + * potentially be minified + * + * @return array + */ + public function getInternalPlugins() { + // Return only plugins with no custom url + $plugins = []; + foreach($this->getPlugins() as $name => $url) { + if(empty($url)) { + $plugins[] = $name; + } + } + return $plugins; + } + /** * Get all button rows, skipping empty rows * @@ -416,31 +435,26 @@ class TinyMCEConfig extends HtmlEditorConfig { * Generate gzipped TinyMCE configuration including plugins and languages. * This ends up "pre-loading" TinyMCE bundled with the required plugins * so that multiple HTTP requests on the client don't need to be made. + * + * @return string */ - public function requireJS() { - require_once THIRDPARTY_PATH . '/tinymce/tiny_mce_gzip.php'; - + public function getScriptURL() { + // If gzip is disabled just return core script url $useGzip = Config::inst()->get('HtmlEditorField', 'use_gzip'); - $languages = array(); - - foreach(self::$configs as $configID => $config) { - $languages[] = $config->getOption('language'); + if(!$useGzip) { + return THIRDPARTY_DIR . '/tinymce/tinymce.min.js'; } // tinyMCE JS requirement - if($useGzip) { - $tag = TinyMCE_Compressor::renderTag(array( - 'url' => THIRDPARTY_DIR . '/tinymce/tiny_mce_gzip.php', - 'plugins' => implode(',', array_keys($this->getPlugins())), - 'themes' => $this->getTheme(), - 'languages' => implode(',', array_filter($languages)) - ), true); - preg_match('/src="([^"]*)"/', $tag, $matches); - - Requirements::javascript(html_entity_decode($matches[1])); - } else { - Requirements::javascript(THIRDPARTY_DIR . '/tinymce/tinymce.min.js'); - } + require_once THIRDPARTY_PATH . '/tinymce/tiny_mce_gzip.php'; + $tag = TinyMCE_Compressor::renderTag(array( + 'url' => THIRDPARTY_DIR . '/tinymce/tiny_mce_gzip.php', + 'plugins' => implode(',', $this->getInternalPlugins()), + 'themes' => $this->getTheme(), + 'languages' => $this->getOption('language') + ), true); + preg_match('/src="([^"]*)"/', $tag, $matches); + return html_entity_decode($matches[1]); } public function init() { @@ -451,7 +465,7 @@ class TinyMCEConfig extends HtmlEditorConfig { Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/javascript/dist/ssui.core.js'); // include TinyMCE Javascript - $this->requireJS(); + Requirements::javascript($this->getScriptURL()); Requirements::javascript(FRAMEWORK_DIR ."/javascript/dist/HtmlEditorField.js"); Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css'); diff --git a/tests/forms/HtmlEditorConfigTest.php b/tests/forms/HtmlEditorConfigTest.php index eb5eef7f3..8223b535c 100644 --- a/tests/forms/HtmlEditorConfigTest.php +++ b/tests/forms/HtmlEditorConfigTest.php @@ -28,11 +28,15 @@ class HtmlEditorConfigTest extends SapphireTest { public function testEnablePluginsByArrayWithPaths() { Config::inst()->update('Director', 'alternate_base_url', 'http://mysite.com/subdir'); $c = new TinyMCEConfig(); + $c->setTheme('modern'); + $c->setOption('language', 'es'); + $c->disablePlugins('table', 'emoticons', 'paste', 'code', 'link', 'importcss'); $c->enablePlugins(array( 'plugin1' => 'mypath/plugin1.js', 'plugin2' => '/anotherbase/mypath/plugin2.js', 'plugin3' => 'https://www.google.com/plugin.js', 'plugin4' => null, + 'plugin5' => null, )); $attributes = $c->getAttributes(); $config = Convert::json2array($attributes['data-config']); @@ -66,6 +70,23 @@ class HtmlEditorConfigTest extends SapphireTest { 'http://mysite.com/subdir/framework/thirdparty/tinymce/plugins/plugin4/plugin.min.js', $plugins['plugin4'] ); + + // Check that internal plugins are extractable separately + $this->assertEquals(['plugin4', 'plugin5'], $c->getInternalPlugins()); + + // Test plugins included via gzip compresser + Config::inst()->update('HtmlEditorField', 'use_gzip', true); + $this->assertEquals( + 'framework/thirdparty/tinymce/tiny_mce_gzip.php?js=1&plugins=plugin4,plugin5&themes=modern&languages=es&diskcache=true&src=true', + $c->getScriptURL() + ); + + // If gzip is disabled only the core plugin is loaded + Config::inst()->remove('HtmlEditorField', 'use_gzip'); + $this->assertEquals( + 'framework/thirdparty/tinymce/tinymce.min.js', + $c->getScriptURL() + ); } public function testDisablePluginsByString() {