Permalink
Browse files

BUGFIX Enforcing TinyMCE textarea call on window.load in addition to …

…entwine/DOMReady to ensure TinyMCE.init() has been called and all plugins are loaded.
  • Loading branch information...
1 parent 483704c commit f2ec8b0d54b344d6347c8f7f36bbd743b8878840 @chillu chillu committed Dec 13, 2011
Showing with 73 additions and 59 deletions.
  1. +1 −1 admin/_config.php
  2. +30 −34 admin/code/LeftAndMain.php
  3. +40 −23 admin/javascript/LeftAndMain.EditForm.js
  4. +2 −1 forms/HtmlEditorConfig.php
View
@@ -13,7 +13,7 @@
HtmlEditorConfig::get('cms')->setOptions(array(
'friendly_name' => 'Default CMS',
'priority' => '50',
- 'mode' => 'none',
+ 'mode' => 'none', // initialized through LeftAndMain.EditFor.js logic
'body_class' => 'typography',
'document_base_url' => Director::absoluteBaseURL(),
View
@@ -133,9 +133,6 @@ function canView($member = null) {
* @uses CMSMenu
*/
function init() {
- // Suppress behaviour/prototype validation instructions in CMS, not compatible with ajax loading of forms.
- Validator::set_javascript_validation_handler('none');
-
parent::init();
SSViewer::setOption('rewriteHashlinks', false);
@@ -197,6 +194,34 @@ function init() {
// Set the members html editor config
HtmlEditorConfig::set_active(Member::currentUser()->getHtmlEditorConfigForCMS());
+ // Set default values in the config if missing. These things can't be defined in the config
+ // file because insufficient information exists when that is being processed
+ $htmlEditorConfig = HtmlEditorConfig::get_active();
+ $htmlEditorConfig->setOption('language', i18n::get_tinymce_lang());
+ if(!$htmlEditorConfig->getOption('content_css')) {
+ $cssFiles = array();
+ $cssFiles[] = 'sapphire/admin/css/editor.css';
+
+ // Use theme from the site config
+ if(class_exists('SiteConfig') && ($config = SiteConfig::current_site_config()) && $config->Theme) {
+ $theme = $config->Theme;
+ } elseif(SSViewer::current_theme()) {
+ $theme = SSViewer::current_theme();
+ } else {
+ $theme = false;
+ }
+
+ if($theme) $cssFiles[] = THEMES_DIR . "/{$theme}/css/editor.css";
+ else if(project()) $cssFiles[] = project() . '/css/editor.css';
+
+ // Remove files that don't exist
+ foreach($cssFiles as $k => $cssFile) {
+ if(!file_exists(BASE_PATH . '/' . $cssFile)) unset($cssFiles[$k]);
+ }
+
+ $htmlEditorConfig->setOption('content_css', implode(',', $cssFiles));
+ }
+
Requirements::combine_files(
'lib.js',
array(
@@ -234,6 +259,8 @@ function init() {
)
);
+ HTMLEditorField::include_js();
+
Requirements::combine_files(
'leftandmain.js',
array(
@@ -265,37 +292,6 @@ function init() {
);
Requirements::css(SAPPHIRE_ADMIN_DIR . '/css/screen.css');
-
- // Set the members html editor config
- HtmlEditorConfig::set_active(Member::currentUser()->getHtmlEditorConfigForCMS());
-
- // Set default values in the config if missing. These things can't be defined in the config
- // file because insufficient information exists when that is being processed
- $htmlEditorConfig = HtmlEditorConfig::get_active();
- $htmlEditorConfig->setOption('language', i18n::get_tinymce_lang());
- if(!$htmlEditorConfig->getOption('content_css')) {
- $cssFiles = array();
- $cssFiles[] = 'sapphire/admin/css/editor.css';
-
- // Use theme from the site config
- if(class_exists('SiteConfig') && ($config = SiteConfig::current_site_config()) && $config->Theme) {
- $theme = $config->Theme;
- } elseif(SSViewer::current_theme()) {
- $theme = SSViewer::current_theme();
- } else {
- $theme = false;
- }
-
- if($theme) $cssFiles[] = THEMES_DIR . "/{$theme}/css/editor.css";
- else if(project()) $cssFiles[] = project() . '/css/editor.css';
-
- // Remove files that don't exist
- foreach($cssFiles as $k => $cssFile) {
- if(!file_exists(BASE_PATH . '/' . $cssFile)) unset($cssFiles[$k]);
- }
-
- $htmlEditorConfig->setOption('content_css', implode(',', $cssFiles));
- }
foreach (self::$extra_requirements['javascript'] as $file) {
Requirements::javascript($file[0]);
@@ -79,17 +79,7 @@
this._super();
},
-
- onunmatch: function() {
- // Prepare iframes for removal, otherwise we get loading bugs
- this.find('iframe').each(function() {
- $(this).attr('src', 'about:blank');
- $(this).remove();
- });
-
- this._super();
- },
-
+
redraw: function() {
// TODO Manually set container height before resizing - shouldn't be necessary'
this.find('.cms-content-actions').height(this.find('.cms-content-actions .Actions').height());
@@ -189,31 +179,58 @@
/**
* Class: .cms-edit-form textarea.htmleditor
*
- * Add tinymce to HtmlEditorFields within the CMS.
+ * Add tinymce to HtmlEditorFields within the CMS. Works in combination
+ * with a TinyMCE.init() call which is prepopulated with the used HTMLEditorConfig settings,
+ * and included in the page as an inline <script> tag.
*/
$('.cms-edit-form textarea.htmleditor').entwine({
/**
* Constructor: onmatch
*/
onmatch : function() {
- tinyMCE.execCommand("mceAddControl", true, this.attr('id'));
- this.isChanged = function() {
- return tinyMCE.getInstanceById(this.attr('id')).isDirty();
- };
- this.resetChanged = function() {
- var inst = tinyMCE.getInstanceById(this.attr('id'));
- if (inst) inst.startContent = tinymce.trim(inst.getContent({format : 'raw', no_events : 1}));
- };
+ // Only works after TinyMCE.init() has been invoked, see $(window).bind() call below for details.
+ this.redraw();
this._super();
},
-
+
+ redraw: function() {
+ // Using a global config (generated through HTMLEditorConfig PHP logic)
+ var config = ssTinyMceConfig, self = this;
+
+ // Avoid flicker (also set in CSS to apply as early as possible)
+ self.css('visibility', '');
+
+ // Create editor instance and render it.
+ // Similar logic to adapter/jquery/jquery.tinymce.js, but doesn't rely on monkey-patching
+ // jQuery methods, and avoids replicate the script lazyloading which is already in place with jQuery.ondemand.
+ var ed = new tinymce.Editor(this.attr('id'), config);
+ ed.onInit.add(function() {
+ self.css('visibility', 'visible');
+ });
+ ed.render();
+
+ this._super();
+ },
+
+ isChanged: function() {
+ return tinyMCE.getInstanceById(this.attr('id')).isDirty();
+ },
+
+ resetChanged: function() {
+ var inst = tinyMCE.getInstanceById(this.attr('id'));
+ if (inst) inst.startContent = tinymce.trim(inst.getContent({format : 'raw', no_events : 1}));
+ },
+
onunmatch: function() {
- tinyMCE.execCommand("mceRemoveControl", true, this.attr('id'));
-
+ // TODO Throws exceptions in Firefox, most likely due to the element being removed from the DOM at this point
+ // var ed = tinyMCE.get(this.attr('id'));
+ // if(ed) ed.remove();
+
this._super();
}
});
});
+
}(jQuery));
@@ -303,7 +303,8 @@ function generateJS() {
return "
if((typeof tinyMCE != 'undefined')) {
$externalPluginsJS
- tinyMCE.init(" . Convert::raw2json($config) . ");
+ var ssTinyMceConfig = " . Convert::raw2json($config) . ";
+ tinyMCE.init(ssTinyMceConfig);
}
";
}

0 comments on commit f2ec8b0

Please sign in to comment.