Fixed HtmlEditorField.js editor instanciation

Wasn't parsing data-editor attrs correctly.
Using proper instances of the underlying editor now,
instead of relying on "active editor" states which get
wonky once they lose focus (e.g. when opening a dialog).
This commit is contained in:
Ingo Schommer 2013-06-14 11:25:06 +02:00
parent 975e09643f
commit a9bf7dfcce

View File

@ -14,6 +14,9 @@ var ss = ss || {};
*/ */
ss.editorWrappers = {}; ss.editorWrappers = {};
ss.editorWrappers.tinyMCE = (function() { ss.editorWrappers.tinyMCE = (function() {
var instance;
return { return {
init: function(config) { init: function(config) {
if(!ss.editorWrappers.tinyMCE.initialized) { if(!ss.editorWrappers.tinyMCE.initialized) {
@ -25,7 +28,7 @@ ss.editorWrappers.tinyMCE = (function() {
* @return Mixed Implementation specific object * @return Mixed Implementation specific object
*/ */
getInstance: function() { getInstance: function() {
return tinyMCE.activeEditor; return this.instance;
}, },
/** /**
* Invoked when a content-modifying UI is opened. * Invoked when a content-modifying UI is opened.
@ -55,10 +58,10 @@ ss.editorWrappers.tinyMCE = (function() {
* @param Function * @param Function
*/ */
create: function(domID, config) { create: function(domID, config) {
var ed = new tinymce.Editor(domID, config); this.instance = new tinymce.Editor(domID, config);
// Patch TinyMCE events into underlying textarea field. // Patch TinyMCE events into underlying textarea field.
ed.onInit.add(function(ed) { this.instance.onInit.add(function(ed) {
jQuery(ed.getElement()).trigger('editorinit'); jQuery(ed.getElement()).trigger('editorinit');
// Periodically check for inline changes when focused, // Periodically check for inline changes when focused,
@ -79,7 +82,7 @@ ss.editorWrappers.tinyMCE = (function() {
clearInterval(interval); clearInterval(interval);
}); });
}); });
ed.onChange.add(function(ed, l) { this.instance.onChange.add(function(ed, l) {
// Update underlying textarea on every change, so external handlers // Update underlying textarea on every change, so external handlers
// such as changetracker have a chance to trigger properly. // such as changetracker have a chance to trigger properly.
ed.save(); ed.save();
@ -87,7 +90,7 @@ ss.editorWrappers.tinyMCE = (function() {
}); });
// Add more events here as needed. // Add more events here as needed.
ed.render(); this.instance.render();
}, },
/** /**
* Redraw the editor contents * Redraw the editor contents
@ -252,7 +255,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
* Constructor: onmatch * Constructor: onmatch
*/ */
onadd: function() { onadd: function() {
var edClass = this.data('editor') || ss.editorWrappers['default'], ed = edClass(); var edClass = this.data('editor') || 'default', ed = ss.editorWrappers[edClass]();
this.setEditor(ed); this.setEditor(ed);
// Using a global config (generated through HTMLEditorConfig PHP logic). // Using a global config (generated through HTMLEditorConfig PHP logic).
@ -360,10 +363,11 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase(); return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
}; };
var url = $('#cms-editor-dialogs').data('url' + capitalize(type) + 'form'), var self = this, url = $('#cms-editor-dialogs').data('url' + capitalize(type) + 'form'),
dialog = $('.htmleditorfield-' + type + 'dialog'); dialog = $('.htmleditorfield-' + type + 'dialog');
if(dialog.length) { if(dialog.length) {
dialog.getForm().setElement(this);
dialog.open(); dialog.open();
} else { } else {
// Show a placeholder for instant feedback. Will be replaced with actual // Show a placeholder for instant feedback. Will be replaced with actual
@ -374,6 +378,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
url: url, url: url,
success: function(html) { success: function(html) {
dialog.html(html); dialog.html(html);
dialog.getForm().setElement(self);
dialog.trigger('dialogopen'); dialog.trigger('dialogopen');
} }
}); });
@ -414,15 +419,17 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
*/ */
$('form.htmleditorfield-form').entwine({ $('form.htmleditorfield-form').entwine({
Selection: null, Selection: null,
// Implementation-dependent serialization of the current editor selection state
Bookmark: null, Bookmark: null,
// DOMElement pointing to the currently active textarea
Element: null,
setSelection: function(node) { setSelection: function(node) {
return this._super($(node)); return this._super($(node));
}, },
// Wrapper for various HTML editors
Editor: null,
onadd: function() { onadd: function() {
// Move title from headline to (jQuery compatible) title attribute // Move title from headline to (jQuery compatible) title attribute
var titleEl = this.find(':header:first'); var titleEl = this.find(':header:first');
@ -433,7 +440,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
onremove: function() { onremove: function() {
this.setSelection(null); this.setSelection(null);
this.setBookmark(null); this.setBookmark(null);
this.setEditor(null); this.setElement(null);
this._super(); this._super();
}, },
@ -472,19 +479,11 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
} }
}, },
createEditor: function(){
return ss.editorWrappers['default']();
},
/** /**
* Get the tinyMCE editor * @return Object ss.editorWrapper instance
*/ */
getEditor: function(){ getEditor: function(){
var val = this._super(); return this.getElement().getEditor();
if(!val) {
this.setEditor(val = this.createEditor());
}
return val;
}, },
modifySelection: function(callback) { modifySelection: function(callback) {