* If you return Json { data: [] , success: false, .... } then this will be thrown with the following args
*
* @param {Proxy}
- * @param {Object} return from JsonData.reader() - success, totalRecords, records
- * @param {Object} load options
+ * @param {Object} ret return data from JsonData.reader() - success, totalRecords, records
+ * @param {Object} opts - load Options
* @param {Object} jsonData from your request (normally this contains the Exception)
*/
loadexception : true
// thse are take from connection...
/**
- * @cfg {String} url (Optional) The default URL to be used for requests to the server. (defaults to undefined)
+ * @cfg {String} url The default URL to be used for requests to the server. (defaults to undefined)
*/
/**
- * @cfg {Object} extraParams (Optional) An object containing properties which are used as
+ * @cfg {Object} extraParams An object containing properties which are used as
* extra parameters to each request made by this object. (defaults to undefined)
*/
/**
- * @cfg {Object} defaultHeaders (Optional) An object containing request headers which are added
+ * @cfg {Object} defaultHeaders An object containing request headers which are added
* to each request made by this object. (defaults to undefined)
*/
/**
- * @cfg {String} method (Optional) The default HTTP method to be used for requests. (defaults to undefined; if not set but parms are present will use POST, otherwise GET)
+ * @cfg {String} method (GET|POST) The default HTTP method to be used for requests. (defaults to undefined; if not set but parms are present will use POST, otherwise GET)
*/
/**
- * @cfg {Number} timeout (Optional) The timeout in milliseconds to be used for requests. (defaults to 30000)
+ * @cfg {Number} timeout The timeout in milliseconds to be used for requests. (defaults to 30000)
*/
/**
- * @cfg {Boolean} autoAbort (Optional) Whether this request should abort any pending requests. (defaults to false)
+ * @cfg {Boolean} autoAbort Whether this request should abort any pending requests. (defaults to false)
* @type Boolean
*/
return;
}
if (this.toolbars === true) {
- this.toolbars = [
- new Roo.bootstrap.form.HtmlEditorToolbar.Standard({editor: this} )
- ];
+ this.toolbars = [ 'Standard' ];
}
var ar = Array.from(this.toolbars);
this.toolbars = [];
ar.forEach(function(t,i) {
if (typeof(t) == 'string') {
- t = new Roo.bootstrap.form.HtmlEditorToolbar[t]({editor : this});
+ t = {
+ xtype : t
+ };
}
if (typeof(t) == 'object' && typeof(t.xtype) == 'string') {
t.editor = this;
t.xns = t.xns || Roo.bootstrap.form.HtmlEditorToolbar;
t = Roo.factory(t);
}
+ this.toolbars[i] = t;
this.toolbars[i].render(this.toolbarContainer());
}, this);
this.editor = config.editor;
this.editorcore = config.editor.editorcore;
- this.buttons = new Roo.util.MixedCollection(false, function(o) { return o.cmd; });
+ this.buttons = new Roo.util.MixedCollection(false, function(o) { return o.btnid; });
//Roo.form.HtmlEditorToolbar1.superclass.constructor.call(this, editor.wrap.dom.firstChild, [], config);
// dont call parent... till later.
'div','span'
],
+
+ deleteBtn: false,
+
onRender : function(ct, position)
{
// Roo.log("Call onRender: " + this.xtype);
var editor= this.editor;
var children = [];
- var btn = function(id,cmd , toggle, handler, html){
+ var btn = function(id, cmd , toggle, handler, html){
var event = toggle ? 'toggle' : 'click';
xtype: 'Button',
xns: Roo.bootstrap,
//glyphicon : id,
+ btnid : id,
fa: id,
- cmd : id || cmd,
- enableToggle:toggle !== false,
+ cmd : cmd, // why id || cmd
+ enableToggle: toggle !== false,
html : html || '',
pressed : toggle ? false : null,
listeners : {}
});
children.push(style);
- btn('bold',false,true);
- btn('italic',false,true);
- btn('align-left', 'justifyleft',true);
+ btn('bold', false,true);
+ btn('italic', false,true);
+ btn('align-left', 'justifyleft',true);
btn('align-center', 'justifycenter',true);
btn('align-right' , 'justifyright',true);
- btn('link', false, false, function(btn) {
- //Roo.log("create link?");
+ btn('link', false, true, function(btn) {
+
var url = prompt(this.createLinkText, this.defaultLinkValue);
if(url && url != 'http:/'+'/'){
this.editorcore.relayCmd('createlink', url);
}
}
- /*
- var cog = {
- xtype: 'Button',
- size : 'sm',
- xns: Roo.bootstrap,
- glyphicon : 'cog',
- //html : 'submit'
- menu : {
- xtype: 'Menu',
- xns: Roo.bootstrap,
- items: []
- }
- };
-
- cog.menu.items.push({
- xtype :'MenuItem',
- xns: Roo.bootstrap,
- html : Clean styles,
- tagname : f,
- listeners : {
- click : function()
- {
- editorcore.insertTag(this.tagname);
- editor.focus();
- }
- }
-
- });
- */
- this.xtype = 'NavSimplebar';
+ this.xtype = 'NavSimplebar'; // why?
for(var i=0;i< children.length;i++) {
this.buttons.add(this.addxtypeChild(children[i]));
}
-
+ this.buildToolbarDelete();
+
editor.on('editorevent', this.updateToolbar, this);
},
+
+ buildToolbarDelete : function()
+ {
+
+ /* this.addxtypeChild({
+ xtype : 'Element',
+ xns : Roo.bootstrap,
+ cls : 'roo-htmleditor-fill'
+ });
+ */
+ this.deleteBtn = this.addxtypeChild({
+ size : 'sm',
+ xtype: 'Button',
+ xns: Roo.bootstrap,
+ fa: 'trash',
+ listeners : {
+ click : this.onDelete.createDelegate(this)
+ }
+ });
+ this.deleteBtn.hide();
+
+ },
+
+
onBtnClick : function(id)
{
this.editorcore.relayCmd(id);
* Protected method that will not generally be called directly. It triggers
* a toolbar update by reading the markup state of the current selection in the editor.
*/
- updateToolbar: function(){
+ updateToolbar: function(editor ,ev, sel){
if(!this.editorcore.activated){
this.editor.onFirstFocus(); // is this neeed?
var btns = this.buttons;
var doc = this.editorcore.doc;
- btns.get('bold').setActive(doc.queryCommandState('bold'));
- btns.get('italic').setActive(doc.queryCommandState('italic'));
- //btns.get('underline').setActive(doc.queryCommandState('underline'));
-
- btns.get('align-left').setActive(doc.queryCommandState('justifyleft'));
- btns.get('align-center').setActive(doc.queryCommandState('justifycenter'));
- btns.get('align-right').setActive(doc.queryCommandState('justifyright'));
+ var hasToggle = false;
+ btns.each(function(e) {
+ if (e.enableToggle && e.cmd) {
+ hasToggle = hasToggle || doc.queryCommandState(e.cmd);
+ e.setActive(doc.queryCommandState(e.cmd));
+ }
+ }, this);
- //btns[frameId + '-insertorderedlist').setActive(doc.queryCommandState('insertorderedlist'));
- btns.get('list').setActive(doc.queryCommandState('insertunorderedlist'));
- /*
- var ans = this.editorcore.getAllAncestors();
- if (this.formatCombo) {
-
+ if (ev &&
+ (ev.type == 'mouseup' || ev.type == 'click' ) &&
+ ev.target && ev.target.tagName != 'BODY' ) { // && ev.target.tagName == 'IMG') {
+ // they have click on an image...
+ // let's see if we can change the selection...
+ sel = ev.target;
- var store = this.formatCombo.store;
- this.formatCombo.setValue("");
- for (var i =0; i < ans.length;i++) {
- if (ans[i] && store.query('tag',ans[i].tagName.toLowerCase(), false).length) {
- // select it..
- this.formatCombo.setValue(ans[i].tagName.toLowerCase());
- break;
- }
+ }
+ var tn = sel && sel.tagName.toUpperCase() || '';
+ if (sel && tn != 'A') {
+ var asel = sel.closest('A');
+ if (asel) {
+ sel = asel;
}
}
+
+ btns.get('link').setActive(tn == 'A');
+
+ Roo.bootstrap.menu.Manager.hideAll();
+
+ // handle delete button..
+ if (hasToggle || (tn.length && tn == 'BODY')) {
+ this.deleteBtn.hide();
+ return;
+
+ }
+ this.deleteBtn.show();
- // hides menus... - so this cant be on a menu...
- Roo.bootstrap.MenuMgr.hideAll();
- */
- Roo.bootstrap.menu.Manager.hideAll();
//this.editorsyncValue();
},
onFirstFocus: function() {
item.enable();
});
},
+
+ onDelete : function()
+ {
+ var range = this.editorcore.createRange();
+ var selection = this.editorcore.getSelection();
+ var sn = this.selectedNode;
+ range.setStart(sn,0);
+ range.setEnd(sn,0);
+
+
+ if (sn.hasAttribute('data-block')) {
+ var block = Roo.htmleditor.Block.factory(tb.selectedNode);
+ if (block) {
+ block.removeNode();
+ selection.removeAllRanges();
+ selection.addRange(range);
+ this.updateToolbar(null, null, null);
+ }
+
+ }
+ if (!sn) {
+ return; // should not really happen..
+ }
+ if (sn && sn.tagName == 'BODY') {
+ return;
+ }
+ var stn = sn.childNodes[0] || sn.nextSibling || sn.previousSibling || sn.parentNode;
+
+ // remove and keep parents.
+ a = new Roo.htmleditor.FilterKeepChildren({tag : false});
+ a.replaceTag(sn);
+
+ selection.removeAllRanges();
+ selection.addRange(range);
+ this.editorcore.fireEditorEvent(false);
+
+
+ },
+
+
toggleSourceEdit : function(sourceEditMode){
+
+/**
+ * @class Roo.bootstrap.form.HtmlEditorToolbar.Context
+ * @parent Roo.bootstrap.form.HtmlEditor
+ * @extends Roo.bootstrap.nav.Simplebar
+ * Basic Toolbar
+ *
+ * @example
+ * Usage:
+ *
+ new Roo.bootstrap.form.HtmlEditor({
+ ....
+ toolbars : [
+ {
+ xtyle: 'Standard',
+ disable : { fonts: 1 , format: 1, ..., ... , ...],
+ btns : [ .... ]
+ },
+ {
+ xtyle : 'Context',
+ ....
+ }
+ }
+
+ *
+ *
+ */
+Roo.bootstrap.form.HtmlEditorToolbar.Context = function(config)
+{
+
+ Roo.apply(this, config);
+
+
+ Roo.bootstrap.form.HtmlEditorToolbar.Context.superclass.constructor.call(this, config);
+
+ this.editor = config.editor;
+ this.editorcore = config.editor.editorcore;
+
+ this.buttons = new Roo.util.MixedCollection(false, function(o) { return o.cmd; });
+
+}
+
+Roo.bootstrap.form.HtmlEditorToolbar.Context.types = {
+ 'IMG' : [
+ {
+ name : 'width',
+ title: "Width",
+ width: 40
+ },
+ {
+ name : 'height',
+ title: "Height",
+ width: 40
+ },
+ {
+ name : 'align',
+ title: "Align",
+ opts : [ [""],[ "left"],[ "right"],[ "center"],[ "top"]],
+ width : 80
+
+ },
+ {
+ name : 'border',
+ title: "Border",
+ width: 40
+ },
+ {
+ name : 'alt',
+ title: "Alt",
+ width: 120
+ },
+ {
+ name : 'src',
+ title: "Src",
+ width: 220
+ }
+
+ ],
+
+ /*
+ 'A' : [
+ {
+ name : 'name',
+ title: "Name",
+ width: 50
+ },
+ {
+ name : 'target',
+ title: "Target",
+ width: 120
+ },
+ {
+ name : 'href',
+ title: "Href",
+ width: 220
+ } // border?
+
+ ],
+ */
+ /*
+ 'INPUT' : [
+ {
+ name : 'name',
+ title: "name",
+ width: 120
+ },
+ {
+ name : 'value',
+ title: "Value",
+ width: 120
+ },
+ {
+ name : 'width',
+ title: "Width",
+ width: 40
+ }
+ ],
+ 'LABEL' : [
+ {
+ name : 'for',
+ title: "For",
+ width: 120
+ }
+ ],
+ 'TEXTAREA' : [
+ {
+ name : 'name',
+ title: "name",
+ width: 120
+ },
+ {
+ name : 'rows',
+ title: "Rows",
+ width: 20
+ },
+ {
+ name : 'cols',
+ title: "Cols",
+ width: 20
+ }
+ ],
+ 'SELECT' : [
+ {
+ name : 'name',
+ title: "name",
+ width: 120
+ },
+ {
+ name : 'selectoptions',
+ title: "Options",
+ width: 200
+ }
+ ],
+
+ // should we really allow this??
+ // should this just be
+ 'BODY' : [
+
+ {
+ name : 'title',
+ title: "Title",
+ width: 200,
+ disabled : true
+ }
+ ],
+ */
+ '*' : [
+ // empty.
+ ]
+
+};
+
+Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Context, Roo.bootstrap.nav.Simplebar, {
+
+ editor : false,
+ editorcore : false,
+ buttons : false,
+
+ button_groups : false, // subtoolbars... - buttson?
+ active_group : false,
+
+ selectedNode : false,
+
+ onRender : function(ct, position)
+ {
+ // Roo.log("Call onRender: " + this.xtype);
+
+ this.constructor.superclass.onRender.call(this, ct, position);
+
+
+
+
+
+ // disable everything...
+ var ty = this.constructor.types;
+ this.button_groups = {};
+ // block toolbars are built in updateToolbar when needed.
+ for (var i in ty) {
+ this.button_groups[i] = this.buildToolbarGroup(ty[i],i);
+ }
+ this.buildToolbarDelete();
+ this.hide();
+ // the all the btns;
+ this.editor.on('editorevent', this.updateToolbar, this);
+
+ },
+ onFirstFocus: function() {
+
+ },
+
+
+ buildToolbarGroup: function(tlist, key )
+ {
+ var editor = this.editor;
+ var editorcore = this.editorcore;
+ var tb = this;
+
+ var ret = [];
+
+ for (var i = 0; i < tlist.length; i++) {
+
+ // newer versions will use xtype cfg to create menus.
+ if (typeof(tlist[i].xtype) != 'undefined') {
+ tb[typeof(tlist[i].name)== 'undefined' ? 'add' : 'addField'](Roo.factory(tlist[i]));
+ continue;
+ }
+
+ var item = tlist[i];
+ ret.push(
+ this.addxtypeChild({
+ xtype : 'Element',
+ xns : Roo.bootstrap,
+ cls : 'roo-htmleditor-context-label-' + key + '-' + item.name,
+ html : item.title
+ })
+ );
+
+ // add a text entry!?
+ ret.push(
+ this.addxtypeChild({
+ xtype : 'Input',
+ xns : Roo.bootstrap.form,
+ cls : 'roo-htmleditor-context-entry-' + key + '-' + item.name,
+ name: '-roo-edit-' + item.name,
+ attrname : item.name,
+ width: item.width,
+ //allowBlank:true,
+ value: '',
+ listeners: {
+ 'change' : function(f, nv, ov) {
+ tb.selectedNode.setAttribute(f.attrname, nv);
+ editorcore.syncValue();
+ }
+ }
+ })
+ );
+
+ }
+ // hide them all..
+ ret.forEach(function(e) {
+ e.hide();
+ });
+ ret.name = key;
+
+ return ret;
+ },
+ buildToolbarDelete : function()
+ {
+
+ this.addxtypeChild({
+ xtype : 'Element',
+ xns : Roo.bootstrap,
+ cls : 'roo-htmleditor-fill'
+ });
+
+ this.deleteBtn = this.addxtypeChild({
+ size : 'sm',
+ xtype: 'Button',
+ xns: Roo.bootstrap,
+ fa: 'trash',
+ listeners : {
+ click : this.onDelete.createDelegate(this)
+ }
+ });
+ this.deleteBtn.hide();
+
+ },
+
+
+ onDelete : function()
+ {
+ var range = this.editorcore.createRange();
+ var selection = this.editorcore.getSelection();
+ var sn = this.selectedNode;
+ range.setStart(sn,0);
+ range.setEnd(sn,0);
+
+
+ if (sn.hasAttribute('data-block')) {
+ var block = Roo.htmleditor.Block.factory(tb.selectedNode);
+ if (block) {
+ block.removeNode();
+ selection.removeAllRanges();
+ selection.addRange(range);
+ this.updateToolbar(null, null, null);
+ }
+
+ }
+ if (!sn) {
+ return; // should not really happen..
+ }
+ if (sn && sn.tagName == 'BODY') {
+ return;
+ }
+ var stn = sn.childNodes[0] || sn.nextSibling || sn.previousSibling || sn.parentNode;
+
+ // remove and keep parents.
+ a = new Roo.htmleditor.FilterKeepChildren({tag : false});
+ a.replaceTag(sn);
+
+ selection.removeAllRanges();
+ selection.addRange(range);
+ this.editorcore.fireEditorEvent(false);
+
+
+ },
+ /**
+ * Protected method that will not generally be called directly. It triggers
+ * a toolbar update by reading the markup state of the current selection in the editor.
+ *
+ * Note you can force an update by calling on('editorevent', scope, false)
+ */
+ updateToolbar: function(editor ,ev, sel)
+ {
+ var ty = this.constructor.types;
+
+
+ if (ev) {
+ ev.stopEvent(); // se if we can stop this looping with mutiple events.
+ }
+
+
+ // capture mouse up - this is handy for selecting images..
+ // perhaps should go somewhere else...
+ if(!this.editorcore.activated){
+ this.editor.onFirstFocus();
+ return;
+ }
+ //Roo.log(ev ? ev.target : 'NOTARGET');
+
+
+ // http://developer.yahoo.com/yui/docs/simple-editor.js.html
+ // selectNode - might want to handle IE?
+
+ if (ev &&
+ (ev.type == 'mouseup' || ev.type == 'click' ) &&
+ ev.target && ev.target.tagName != 'BODY' ) { // && ev.target.tagName == 'IMG') {
+ // they have click on an image...
+ // let's see if we can change the selection...
+ sel = ev.target;
+
+
+ }
+
+ // this forces an id..
+ Array.from(this.editorcore.doc.body.querySelectorAll('.roo-ed-selection')).forEach(function(e) {
+ e.classList.remove('roo-ed-selection');
+ });
+
+ var ans = this.editorcore.getAllAncestors();
+
+
+ if (!sel) {
+ sel = ans.length ? (ans[0] ? ans[0] : ans[1]) : this.editorcore.doc.body;
+ sel = sel ? sel : this.editorcore.doc.body;
+ sel = sel.tagName.length ? sel : this.editorcore.doc.body;
+
+ }
+
+ var tn = sel.tagName.toUpperCase();
+ var lastSel = this.selectedNode;
+ this.selectedNode = sel;
+ var left_label = tn;
+
+ // ok see if we are editing a block?
+
+ var db = false;
+ // you are not actually selecting the block.
+ if (sel && sel.hasAttribute('data-block')) {
+ db = sel;
+ } else if (sel && sel.closest('[data-block]')) {
+
+ db = sel.closest('[data-block]');
+
+ }
+
+
+ var block = false;
+ if (db && this.editorcore.enableBlocks) {
+ block = Roo.htmleditor.Block.factory(db);
+
+
+ if (block) {
+ db.className = (
+ db.classList.length > 0 ? db.className + ' ' : ''
+ ) + 'roo-ed-selection';
+
+ // since we removed it earlier... its not there..
+ tn = 'BLOCK.' + db.getAttribute('data-block');
+
+ //this.editorcore.selectNode(db);
+ if (typeof(this.button_groups[tn]) == 'undefined') {
+ this.button_groups[tn] = this.buildBlockToolbar( block );
+ }
+ this.selectedNode = db;
+ left_label = block.friendly_name;
+ ans = this.editorcore.getAllAncestors();
+ }
+
+
+ }
+
+
+ if ( this.active_group !== false && this.active_group.name == tn && lastSel == this.selectedNode && ev !== false) {
+ return; // no change?
+ }
+
+ if (tn == 'BODY') {
+ this.deleteBtn.hide();
+ this.hide();
+ this.hideActiveGroup();
+ return;
+
+ }
+
+
+ if (this.active_group) {
+ this.hideActiveGroup();
+ }
+ this.showActiveGroup(tn);
+ this.show();
+ this.deleteBtn.show();
+
+ },
+ hideActiveGroup : function()
+ {
+ this.hide();
+ if (this.active_group === false) {
+ return;
+ }
+ this.active_group.forEach(function(e) {
+ e.hide();
+ });
+ this.active_group = false;
+ },
+ showActiveGroup : function(tn)
+ {
+
+ if (typeof(this.button_groups[tn]) == 'undefined') {
+
+ return;
+ }
+
+ this.active_group = this.button_groups[tn];
+
+ this.active_group.forEach(function(e) {
+ e.show();
+ });
+
+ // update attributes
+ if (this.selectedNode.hasAttribute('data-block') ) {
+ var block = Roo.htmleditor.Block.factory(this.selectedNode);
+ this.active_group.forEach(function(e) {
+ e.setValue(this.selectedNode.getAttribute(block[e.name]));
+ }, this);
+
+ return;
+
+ }
+ // based on attributes...
+ this.active_group.forEach(function(e) {
+ if (typeof(e.attrname) == 'undefined') {
+ return;
+ }
+ e.setValue(this.selectedNode.getAttribute(e.attrname));
+ }, this);
+
+
+ }
+
+});
/*
* - LGPL
*/
// Roo/bootstrap/form/HtmlEditor.js
Roo.bootstrap.form.HtmlEditor=function(A){Roo.bootstrap.form.HtmlEditor.superclass.constructor.call(this,A);if(!this.toolbars){this.toolbars=[];}this.editorcore=new Roo.HtmlEditorCore(Roo.apply({owner:this},A));this.addEvents({initialize:true,activate:true,beforesync:true,beforepush:true,sync:true,push:true,editmodechange:true,editorevent:true,firstfocus:true,autosave:true,savedpreview:true}
);};Roo.extend(Roo.bootstrap.form.HtmlEditor,Roo.bootstrap.form.TextArea,{toolbars:true,btns:[],resize:false,height:300,width:false,stylesheets:false,frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',tbContainer:false,bodyCls:'',toolbarContainer:function(){return this.wrap.select('.x-html-editor-tb',true).first();
-},createToolbar:function(){if(this.toolbars===false){return;}if(this.toolbars===true){this.toolbars=[new Roo.bootstrap.form.HtmlEditorToolbar.Standard({editor:this})];}var ar=Array.from(this.toolbars);this.toolbars=[];ar.forEach(function(t,i){if(typeof(t)=='string'){t=new Roo.bootstrap.form.HtmlEditorToolbar[t]({editor:this}
-);}if(typeof(t)=='object'&&typeof(t.xtype)=='string'){t.editor=this;t.xns=t.xns||Roo.bootstrap.form.HtmlEditorToolbar;t=Roo.factory(t);}this.toolbars[i].render(this.toolbarContainer());},this);},onRender:function(ct,A){var _t=this;Roo.bootstrap.form.HtmlEditor.superclass.onRender.call(this,ct,A);
-this.wrap=this.inputEl().wrap({cls:'x-html-editor-wrap',cn:{cls:'x-html-editor-tb'}});this.editorcore.onRender(ct,A);this.createToolbar(this);},onResize:function(w,h){Roo.log('resize: '+w+','+h);Roo.bootstrap.form.HtmlEditor.superclass.onResize.apply(this,arguments);
-var ew=false;var eh=false;if(this.inputEl()){if(typeof w=='number'){var aw=w-this.wrap.getFrameWidth('lr');this.inputEl().setWidth(this.adjustWidth('textarea',aw));ew=aw;}if(typeof h=='number'){var A=-11;for(var i=0;i<this.toolbars.length;i++){A+=this.toolbars[i].el.getHeight();
-}var ah=h-this.wrap.getFrameWidth('tb')-A;ah-=5;this.inputEl().setHeight(this.adjustWidth('textarea',ah));var eh=ah;}}Roo.log('onResize:'+[w,h,ew,eh].join(','));this.editorcore.onResize(ew,eh);},toggleSourceEdit:function(A){this.editorcore.toggleSourceEdit(A);
-if(this.editorcore.sourceEditMode){Roo.log('editor - showing textarea');this.syncValue();this.inputEl().removeClass(['hide','x-hidden']);this.inputEl().dom.removeAttribute('tabIndex');this.inputEl().focus();}else{Roo.log('editor - hiding textarea');this.pushValue();
-this.inputEl().addClass(['hide','x-hidden']);this.inputEl().dom.setAttribute('tabIndex',-1);}this.fireEvent('editmodechange',this,this.editorcore.sourceEditMode);},adjustSize:Roo.BoxComponent.prototype.adjustSize,getResizeEl:function(){return this.wrap;},getPositionEl:function(){return this.wrap;
-},initEvents:function(){this.originalValue=this.getValue();},setValue:function(v){Roo.bootstrap.form.HtmlEditor.superclass.setValue.call(this,v);this.editorcore.pushValue();},deferFocus:function(){this.focus.defer(10,this);},focus:function(){this.editorcore.focus();
-},onDestroy:function(){if(this.rendered){for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onDestroy();}this.wrap.dom.innerHTML='';this.wrap.remove();}},onFirstFocus:function(){this.editorcore.onFirstFocus();for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onFirstFocus();
-}},syncValue:function(){this.editorcore.syncValue();},pushValue:function(){this.editorcore.pushValue();}});
+},createToolbar:function(){if(this.toolbars===false){return;}if(this.toolbars===true){this.toolbars=['Standard'];}var ar=Array.from(this.toolbars);this.toolbars=[];ar.forEach(function(t,i){if(typeof(t)=='string'){t={xtype:t};}if(typeof(t)=='object'&&typeof(t.xtype)=='string'){t.editor=this;
+t.xns=t.xns||Roo.bootstrap.form.HtmlEditorToolbar;t=Roo.factory(t);}this.toolbars[i]=t;this.toolbars[i].render(this.toolbarContainer());},this);},onRender:function(ct,A){var _t=this;Roo.bootstrap.form.HtmlEditor.superclass.onRender.call(this,ct,A);this.wrap=this.inputEl().wrap({cls:'x-html-editor-wrap',cn:{cls:'x-html-editor-tb'}
+});this.editorcore.onRender(ct,A);this.createToolbar(this);},onResize:function(w,h){Roo.log('resize: '+w+','+h);Roo.bootstrap.form.HtmlEditor.superclass.onResize.apply(this,arguments);var ew=false;var eh=false;if(this.inputEl()){if(typeof w=='number'){var aw=w-this.wrap.getFrameWidth('lr');
+this.inputEl().setWidth(this.adjustWidth('textarea',aw));ew=aw;}if(typeof h=='number'){var A=-11;for(var i=0;i<this.toolbars.length;i++){A+=this.toolbars[i].el.getHeight();}var ah=h-this.wrap.getFrameWidth('tb')-A;ah-=5;this.inputEl().setHeight(this.adjustWidth('textarea',ah));
+var eh=ah;}}Roo.log('onResize:'+[w,h,ew,eh].join(','));this.editorcore.onResize(ew,eh);},toggleSourceEdit:function(A){this.editorcore.toggleSourceEdit(A);if(this.editorcore.sourceEditMode){Roo.log('editor - showing textarea');this.syncValue();this.inputEl().removeClass(['hide','x-hidden']);
+this.inputEl().dom.removeAttribute('tabIndex');this.inputEl().focus();}else{Roo.log('editor - hiding textarea');this.pushValue();this.inputEl().addClass(['hide','x-hidden']);this.inputEl().dom.setAttribute('tabIndex',-1);}this.fireEvent('editmodechange',this,this.editorcore.sourceEditMode);
+},adjustSize:Roo.BoxComponent.prototype.adjustSize,getResizeEl:function(){return this.wrap;},getPositionEl:function(){return this.wrap;},initEvents:function(){this.originalValue=this.getValue();},setValue:function(v){Roo.bootstrap.form.HtmlEditor.superclass.setValue.call(this,v);
+this.editorcore.pushValue();},deferFocus:function(){this.focus.defer(10,this);},focus:function(){this.editorcore.focus();},onDestroy:function(){if(this.rendered){for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onDestroy();}this.wrap.dom.innerHTML='';
+this.wrap.remove();}},onFirstFocus:function(){this.editorcore.onFirstFocus();for(var i=0;i<this.toolbars.length;i++){this.toolbars[i].onFirstFocus();}},syncValue:function(){this.editorcore.syncValue();},pushValue:function(){this.editorcore.pushValue();}});
+
// Roo/bootstrap/form/HtmlEditorToolbar/Standard.js
Roo.bootstrap.form.HtmlEditorToolbar.Standard=function(A){Roo.apply(this,A);this.disable=this.disable||{};Roo.applyIf(this.disable,{fontSize:true,colors:true,specialElements:true});Roo.bootstrap.form.HtmlEditorToolbar.Standard.superclass.constructor.call(this,A);
-this.editor=A.editor;this.editorcore=A.editor.editorcore;this.buttons=new Roo.util.MixedCollection(false,function(o){return o.cmd;});};Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard,Roo.bootstrap.nav.Simplebar,{bar:true,editor:false,editorcore:false,formats:["p","h1","h2","h3","h4","h5","h6","pre","code","abbr","acronym","address","cite","samp","var",'div','span'],onRender:function(ct,A){Roo.bootstrap.form.HtmlEditorToolbar.Standard.superclass.onRender.call(this,ct,A);
-Roo.log(this.el);this.el.dom.style.marginBottom='0';var B=this;var C=this.editorcore;var D=this.editor;var E=[];var F=function(id,G,H,I,J){var K=H?'toggle':'click';var a={size:'sm',xtype:'Button',xns:Roo.bootstrap,fa:id,cmd:id||G,enableToggle:H!==false,html:J||'',pressed:H?false:null,listeners:{}
+this.editor=A.editor;this.editorcore=A.editor.editorcore;this.buttons=new Roo.util.MixedCollection(false,function(o){return o.btnid;});};Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard,Roo.bootstrap.nav.Simplebar,{bar:true,editor:false,editorcore:false,formats:["p","h1","h2","h3","h4","h5","h6","pre","code","abbr","acronym","address","cite","samp","var",'div','span'],deleteBtn:false,onRender:function(ct,A){Roo.bootstrap.form.HtmlEditorToolbar.Standard.superclass.onRender.call(this,ct,A);
+Roo.log(this.el);this.el.dom.style.marginBottom='0';var B=this;var C=this.editorcore;var D=this.editor;var E=[];var F=function(id,G,H,I,J){var K=H?'toggle':'click';var a={size:'sm',xtype:'Button',xns:Roo.bootstrap,btnid:id,fa:id,cmd:G,enableToggle:H!==false,html:J||'',pressed:H?false:null,listeners:{}
};a.listeners[H?'toggle':'click']=function(){I?I.call(B,this):B.onBtnClick.call(B,G||id);};E.push(a);return a;};var style={xtype:'Button',size:'sm',xns:Roo.bootstrap,fa:'font',menu:{xtype:'Menu',xns:Roo.bootstrap,items:[]}};Roo.each(this.formats,function(f){style.menu.items.push({xtype:'MenuItem',xns:Roo.bootstrap,html:'<'+f+' style="margin:2px">'+f+'</'+f+'>',tagname:f,listeners:{click:function(){C.insertTag(this.tagname);
-D.focus();}}});});E.push(style);F('bold',false,true);F('italic',false,true);F('align-left','justifyleft',true);F('align-center','justifycenter',true);F('align-right','justifyright',true);F('link',false,false,function(G){var H=prompt(this.createLinkText,this.defaultLinkValue);
+D.focus();}}});});E.push(style);F('bold',false,true);F('italic',false,true);F('align-left','justifyleft',true);F('align-center','justifycenter',true);F('align-right','justifyright',true);F('link',false,true,function(G){var H=prompt(this.createLinkText,this.defaultLinkValue);
if(H&&H!='http:/'+'/'){this.editorcore.relayCmd('createlink',H);}}),F('list','insertunorderedlist',true);F('list-ol','insertorderedlist',true);F('pencil',false,true,function(G){Roo.log(this);this.toggleSourceEdit(G.pressed);});if(this.editor.btns.length>0){for(var i=0;
-i<this.editor.btns.length;i++){E.push(this.editor.btns[i]);}}this.xtype='NavSimplebar';for(var i=0;i<E.length;i++){this.buttons.add(this.addxtypeChild(E[i]));}D.on('editorevent',this.updateToolbar,this);},onBtnClick:function(id){this.editorcore.relayCmd(id);
-this.editorcore.focus();},updateToolbar:function(){if(!this.editorcore.activated){this.editor.onFirstFocus();return;}var A=this.buttons;var B=this.editorcore.doc;A.get('bold').setActive(B.queryCommandState('bold'));A.get('italic').setActive(B.queryCommandState('italic'));
-A.get('align-left').setActive(B.queryCommandState('justifyleft'));A.get('align-center').setActive(B.queryCommandState('justifycenter'));A.get('align-right').setActive(B.queryCommandState('justifyright'));A.get('list').setActive(B.queryCommandState('insertunorderedlist'));
-Roo.bootstrap.menu.Manager.hideAll();},onFirstFocus:function(){this.buttons.each(function(A){A.enable();});},toggleSourceEdit:function(A){if(A){Roo.log("disabling buttons");this.buttons.each(function(B){if(B.cmd!='pencil'){B.disable();}});}else{Roo.log("enabling buttons");
-if(this.editorcore.initialized){this.buttons.each(function(B){B.enable();});}}Roo.log("calling toggole on editor");this.editor.toggleSourceEdit(A);}});
+i<this.editor.btns.length;i++){E.push(this.editor.btns[i]);}}this.xtype='NavSimplebar';for(var i=0;i<E.length;i++){this.buttons.add(this.addxtypeChild(E[i]));}this.buildToolbarDelete();D.on('editorevent',this.updateToolbar,this);},buildToolbarDelete:function(){this.deleteBtn=this.addxtypeChild({size:'sm',xtype:'Button',xns:Roo.bootstrap,fa:'trash',listeners:{click:this.onDelete.createDelegate(this)}
+});this.deleteBtn.hide();},onBtnClick:function(id){this.editorcore.relayCmd(id);this.editorcore.focus();},updateToolbar:function(A,ev,B){if(!this.editorcore.activated){this.editor.onFirstFocus();return;}var C=this.buttons;var D=this.editorcore.doc;var E=false;
+C.each(function(e){if(e.enableToggle&&e.cmd){E=E||D.queryCommandState(e.cmd);e.setActive(D.queryCommandState(e.cmd));}},this);if(ev&&(ev.type=='mouseup'||ev.type=='click')&&ev.target&&ev.target.tagName!='BODY'){B=ev.target;}var tn=B&&B.tagName.toUpperCase()||'';
+if(B&&tn!='A'){var F=B.closest('A');if(F){B=F;}}C.get('link').setActive(tn=='A');Roo.bootstrap.menu.Manager.hideAll();if(E||(tn.length&&tn=='BODY')){this.deleteBtn.hide();return;}this.deleteBtn.show();},onFirstFocus:function(){this.buttons.each(function(A){A.enable();
+});},onDelete:function(){var A=this.editorcore.createRange();var B=this.editorcore.getSelection();var sn=this.selectedNode;A.setStart(sn,0);A.setEnd(sn,0);if(sn.hasAttribute('data-block')){var C=Roo.htmleditor.Block.factory(tb.selectedNode);if(C){C.removeNode();
+B.removeAllRanges();B.addRange(A);this.updateToolbar(null,null,null);}}if(!sn){return;}if(sn&&sn.tagName=='BODY'){return;}var D=sn.childNodes[0]||sn.nextSibling||sn.previousSibling||sn.parentNode;a=new Roo.htmleditor.FilterKeepChildren({tag:false});a.replaceTag(sn);
+B.removeAllRanges();B.addRange(A);this.editorcore.fireEditorEvent(false);},toggleSourceEdit:function(A){if(A){Roo.log("disabling buttons");this.buttons.each(function(B){if(B.cmd!='pencil'){B.disable();}});}else{Roo.log("enabling buttons");if(this.editorcore.initialized){this.buttons.each(function(B){B.enable();
+});}}Roo.log("calling toggole on editor");this.editor.toggleSourceEdit(A);}});
+// Roo/bootstrap/form/HtmlEditorToolbar/Context.js
+Roo.bootstrap.form.HtmlEditorToolbar.Context=function(A){Roo.apply(this,A);Roo.bootstrap.form.HtmlEditorToolbar.Context.superclass.constructor.call(this,A);this.editor=A.editor;this.editorcore=A.editor.editorcore;this.buttons=new Roo.util.MixedCollection(false,function(o){return o.cmd;
+});};Roo.bootstrap.form.HtmlEditorToolbar.Context.types={'IMG':[{name:'width',title:"Width",width:40},{name:'height',title:"Height",width:40},{name:'align',title:"Align",opts:[[""],["left"],["right"],["center"],["top"]],width:80},{name:'border',title:"Border",width:40}
+,{name:'alt',title:"Alt",width:120},{name:'src',title:"Src",width:220}],'*':[]};Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Context,Roo.bootstrap.nav.Simplebar,{editor:false,editorcore:false,buttons:false,button_groups:false,active_group:false,selectedNode:false,onRender:function(ct,A){this.constructor.superclass.onRender.call(this,ct,A);
+var ty=this.constructor.types;this.button_groups={};for(var i in ty){this.button_groups[i]=this.buildToolbarGroup(ty[i],i);}this.buildToolbarDelete();this.hide();this.editor.on('editorevent',this.updateToolbar,this);},onFirstFocus:function(){},buildToolbarGroup:function(A,B){var C=this.editor;
+var D=this.editorcore;var tb=this;var E=[];for(var i=0;i<A.length;i++){if(typeof(A[i].xtype)!='undefined'){tb[typeof(A[i].name)=='undefined'?'add':'addField'](Roo.factory(A[i]));continue;}var F=A[i];E.push(this.addxtypeChild({xtype:'Element',xns:Roo.bootstrap,cls:'roo-htmleditor-context-label-'+B+'-'+F.name,html:F.title}
+));E.push(this.addxtypeChild({xtype:'Input',xns:Roo.bootstrap.form,cls:'roo-htmleditor-context-entry-'+B+'-'+F.name,name:'-roo-edit-'+F.name,attrname:F.name,width:F.width,value:'',listeners:{'change':function(f,nv,ov){tb.selectedNode.setAttribute(f.attrname,nv);
+D.syncValue();}}}));}E.forEach(function(e){e.hide();});E.name=B;return E;},buildToolbarDelete:function(){this.addxtypeChild({xtype:'Element',xns:Roo.bootstrap,cls:'roo-htmleditor-fill'});this.deleteBtn=this.addxtypeChild({size:'sm',xtype:'Button',xns:Roo.bootstrap,fa:'trash',listeners:{click:this.onDelete.createDelegate(this)}
+});this.deleteBtn.hide();},onDelete:function(){var A=this.editorcore.createRange();var B=this.editorcore.getSelection();var sn=this.selectedNode;A.setStart(sn,0);A.setEnd(sn,0);if(sn.hasAttribute('data-block')){var C=Roo.htmleditor.Block.factory(tb.selectedNode);
+if(C){C.removeNode();B.removeAllRanges();B.addRange(A);this.updateToolbar(null,null,null);}}if(!sn){return;}if(sn&&sn.tagName=='BODY'){return;}var D=sn.childNodes[0]||sn.nextSibling||sn.previousSibling||sn.parentNode;a=new Roo.htmleditor.FilterKeepChildren({tag:false}
+);a.replaceTag(sn);B.removeAllRanges();B.addRange(A);this.editorcore.fireEditorEvent(false);},updateToolbar:function(A,ev,B){var ty=this.constructor.types;if(ev){ev.stopEvent();}if(!this.editorcore.activated){this.editor.onFirstFocus();return;}if(ev&&(ev.type=='mouseup'||ev.type=='click')&&ev.target&&ev.target.tagName!='BODY'){B=ev.target;
+}Array.from(this.editorcore.doc.body.querySelectorAll('.roo-ed-selection')).forEach(function(e){e.classList.remove('roo-ed-selection');});var C=this.editorcore.getAllAncestors();if(!B){B=C.length?(C[0]?C[0]:C[1]):this.editorcore.doc.body;B=B?B:this.editorcore.doc.body;
+B=B.tagName.length?B:this.editorcore.doc.body;}var tn=B.tagName.toUpperCase();var D=this.selectedNode;this.selectedNode=B;var E=tn;var db=false;if(B&&B.hasAttribute('data-block')){db=B;}else if(B&&B.closest('[data-block]')){db=B.closest('[data-block]');}var F=false;
+if(db&&this.editorcore.enableBlocks){F=Roo.htmleditor.Block.factory(db);if(F){db.className=(db.classList.length>0?db.className+' ':'')+'roo-ed-selection';tn='BLOCK.'+db.getAttribute('data-block');if(typeof(this.button_groups[tn])=='undefined'){this.button_groups[tn]=this.buildBlockToolbar(F);
+}this.selectedNode=db;E=F.friendly_name;C=this.editorcore.getAllAncestors();}}if(this.active_group!==false&&this.active_group.name==tn&&D==this.selectedNode&&ev!==false){return;}if(tn=='BODY'){this.deleteBtn.hide();this.hide();this.hideActiveGroup();return;
+}if(this.active_group){this.hideActiveGroup();}this.showActiveGroup(tn);this.show();this.deleteBtn.show();},hideActiveGroup:function(){this.hide();if(this.active_group===false){return;}this.active_group.forEach(function(e){e.hide();});this.active_group=false;
+},showActiveGroup:function(tn){if(typeof(this.button_groups[tn])=='undefined'){return;}this.active_group=this.button_groups[tn];this.active_group.forEach(function(e){e.show();});if(this.selectedNode.hasAttribute('data-block')){var A=Roo.htmleditor.Block.factory(this.selectedNode);
+this.active_group.forEach(function(e){e.setValue(this.selectedNode.getAttribute(A[e.name]));},this);return;}this.active_group.forEach(function(e){if(typeof(e.attrname)=='undefined'){return;}e.setValue(this.selectedNode.getAttribute(e.attrname));},this);}}
+);
// Roo/bootstrap/form/Markdown.js
Roo.bootstrap.form.Markdown=function(A){Roo.bootstrap.form.Markdown.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.form.Markdown,Roo.bootstrap.form.TextArea,{editing:false,initEvents:function(){Roo.bootstrap.form.TextArea.prototype.initEvents.call(this);
this.markdownEl=this.el.createChild({cls:'roo-markdown-area'});this.inputEl().addClass('d-none');if(this.getValue()==''){this.markdownEl.dom.innerHTML=String.format('<span class="roo-placeholder">{0}</span>',this.placeholder||'');}else{this.markdownEl.dom.innerHTML=Roo.Markdown.toHtml(Roo.util.Format.htmlEncode(this.getValue()));