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.

This commit is contained in:
Ingo Schommer 2011-12-13 14:56:35 +01:00
parent 483704c894
commit f2ec8b0d54
4 changed files with 73 additions and 59 deletions

View File

@ -13,7 +13,7 @@ CMSMenu::add_director_rules();
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 File

@ -133,9 +133,6 @@ class LeftAndMain extends Controller {
* @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 @@ class LeftAndMain extends Controller {
// 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 @@ class LeftAndMain extends Controller {
)
);
HTMLEditorField::include_js();
Requirements::combine_files(
'leftandmain.js',
array(
@ -265,37 +292,6 @@ class LeftAndMain extends Controller {
);
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]);

View File

@ -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,7 +179,9 @@
/**
* 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({
@ -197,23 +189,48 @@
* 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));

View File

@ -303,7 +303,8 @@ class HtmlEditorConfig {
return "
if((typeof tinyMCE != 'undefined')) {
$externalPluginsJS
tinyMCE.init(" . Convert::raw2json($config) . ");
var ssTinyMceConfig = " . Convert::raw2json($config) . ";
tinyMCE.init(ssTinyMceConfig);
}
";
}