问题
My goal is to create a custom control to be used in the dialog's body opened width editor.windowManager.open
.
I found the standard controls source class on github, but I can't find a way to add a new control through a plugin.
https://github.com/tinymce/tinymce/tree/master/js/tinymce/classes/ui
After hours of searching I couldn't find any documentation, tutorial or stackoverflow response. I then tried to include the control declaration in the plugin but I get a ReferenceError: define is not defined
.
tinymce.PluginManager.add('my_plugin',function(editor,url){
// My custom control declaration following standard control found in source file
define("tinymce/ui/MyControl", [ "tinymce/ui/Widget" ],
function(Widget) {
"use strict";
return Widget.extend({
/**
* Renders the control as a HTML string.
*/
renderHtml: function() {
return '<div class="my-control">'+ this.state.get('text') +'</div>';
}
});
});
// Toolbar button to open the dialog
editor.addButton('my_plugin',{
title: 'My Plugin button',
text: 'My Plugin button',
onclick: function(){
// Dialog declaration
editor.windowManager.open({
title: 'My dialog',
body: [
{ type: 'textbox', name: 'textbox', label: 'My textbox' },
{ type: 'mycontrol', name: 'mycontrol', label: 'My Control' },
],
onsubmit: function( e ){
editor.insertContent( e.data.textbox );
}
});
},
});
});
// Init tinyMCE
tinymce.init({
selector: '#mytextarea',
plugins: 'my_plugin',
toolbar: 'my_plugin'
});
It is possible to add a custom control, if yes how to achieve it ?
Find two jsfiddle, the first with standard controls and second with my attempt and the error in the browser console
Thanks for your help
回答1:
I've been struggling with this a long time too...
After defining my Control with
tinymce.ui.MyControl = tinymce.ui.Widget.extend({...})
I had to add the constructor function to 'tinymce.ui.Factory`:
tinymce.ui.Factory.add( 'mycontrol', tinymce.ui.MyControl );
A working example:
// Stolen from tinymce.ui.TextBox:
// https://github.com/tinymce/tinymce/blob/master/src/ui/src/main/js/TextBox.js
tinymce.ui.MyControl = tinymce.ui.Widget.extend({
/**
* Constructs a instance with the specified settings.
*
* @constructor
* @param {Object} settings Name/value object with settings.
* @setting {String} format
*/
init: function(settings) {
var self = this;
self._super(settings);
self.classes.add('mycontrol');
},
/**
* Repaints the control after a layout operation.
*
* @method repaint
*/
repaint: function() {
var self = this, style, rect, borderBox, borderW = 0, borderH = 0, lastRepaintRect;
style = self.getEl().style;
rect = self._layoutRect;
lastRepaintRect = self._lastRepaintRect || {};
// Detect old IE 7+8 add lineHeight to align caret vertically in the middle
var doc = document;
if (!self.settings.multiline && doc.all && (!doc.documentMode || doc.documentMode <= 8)) {
style.lineHeight = (rect.h - borderH) + 'px';
}
borderBox = self.borderBox;
borderW = borderBox.left + borderBox.right + 8;
borderH = borderBox.top + borderBox.bottom + (self.settings.multiline ? 8 : 0);
if (rect.x !== lastRepaintRect.x) {
style.left = rect.x + 'px';
lastRepaintRect.x = rect.x;
}
if (rect.y !== lastRepaintRect.y) {
style.top = rect.y + 'px';
lastRepaintRect.y = rect.y;
}
if (rect.w !== lastRepaintRect.w) {
style.width = (rect.w - borderW) + 'px';
lastRepaintRect.w = rect.w;
}
if (rect.h !== lastRepaintRect.h) {
style.height = (rect.h - borderH) + 'px';
lastRepaintRect.h = rect.h;
}
self._lastRepaintRect = lastRepaintRect;
self.fire('repaint', {}, false);
return self;
},
/**
* Renders the control as a HTML string.
*
* @method renderHtml
* @return {String} HTML representing the control.
*/
renderHtml: function() {
var self = this, id = self._id, settings = self.settings, value = self.encode(self.state.get('value'), false), extraAttrs = '';
if (self.disabled()) {
extraAttrs += ' disabled="disabled"';
}
return '<input type="range" id="' + id + '" class="' + self.classes + '" value="' + value + '" hidefocus="1"' + extraAttrs + ' />';
},
value: function(value) {
if (arguments.length) {
this.state.set('value', value);
return this;
}
// Make sure the real state is in sync
if (this.state.get('rendered')) {
this.state.set('value', this.getEl().value);
}
return this.state.get('value');
},
/**
* Called after the control has been rendered.
*
* @method postRender
*/
postRender: function() {
var self = this;
self._super();
self.$el.on('change', function(e) {
self.state.set('value', e.target.value);
self.fire('change', e);
});
},
bindStates: function() {
var self = this;
self.state.on('change:value', function(e) {
if (self.getEl().value != e.value) {
self.getEl().value = e.value;
}
});
self.state.on('change:disabled', function(e) {
self.getEl().disabled = e.value;
});
return self._super();
},
remove: function() {
this.$el.off();
this._super();
}
});
tinymce.ui.Factory.add( 'mycontrol', tinymce.ui.MyControl );
// `mycontrol` is now available.
I've updated your Fiddle accordingly.
来源:https://stackoverflow.com/questions/38124482/tinymce-add-custom-control-for-windowmanager