3 * @class Roo.bootstrap.form.HtmlEditorToolbar.Context
4 * @parent Roo.bootstrap.form.HtmlEditor
5 * @extends Roo.bootstrap.nav.Simplebar
11 new Roo.bootstrap.form.HtmlEditor({
16 disable : { fonts: 1 , format: 1, ..., ... , ...],
29 Roo.bootstrap.form.HtmlEditorToolbar.Context = function(config)
32 Roo.apply(this, config);
35 Roo.bootstrap.form.HtmlEditorToolbar.Context.superclass.constructor.call(this, config);
37 this.editor = config.editor;
38 this.editorcore = config.editor.editorcore;
40 this.buttons = new Roo.util.MixedCollection(false, function(o) { return o.cmd; });
44 Roo.bootstrap.form.HtmlEditorToolbar.Context.types = {
59 opts : [ [""],[ "left"],[ "right"],[ "center"],[ "top"]],
150 name : 'selectoptions',
156 // should we really allow this??
157 // should this just be
174 Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Context, Roo.bootstrap.nav.Simplebar, {
180 button_groups : false, // subtoolbars... - buttson?
181 active_group : false,
183 selectedNode : false,
185 onRender : function(ct, position)
187 // Roo.log("Call onRender: " + this.xtype);
189 this.constructor.superclass.onRender.call(this, ct, position);
195 // disable everything...
196 var ty = this.constructor.types;
197 this.button_groups = {};
198 // block toolbars are built in updateToolbar when needed.
200 this.button_groups[i] = this.buildToolbarGroup(ty[i],i);
202 this.buildToolbarDelete();
205 this.editor.on('editorevent', this.updateToolbar, this);
208 onFirstFocus: function() {
213 buildToolbarGroup: function(tlist, key )
215 var editor = this.editor;
216 var editorcore = this.editorcore;
221 for (var i = 0; i < tlist.length; i++) {
223 // newer versions will use xtype cfg to create menus.
224 if (typeof(tlist[i].xtype) != 'undefined') {
225 tb[typeof(tlist[i].name)== 'undefined' ? 'add' : 'addField'](Roo.factory(tlist[i]));
234 cls : 'roo-htmleditor-context-label-' + key + '-' + item.name,
239 // add a text entry!?
243 xns : Roo.bootstrap.form,
244 cls : 'roo-htmleditor-context-entry-' + key + '-' + item.name,
245 name: '-roo-edit-' + item.name,
246 attrname : item.name,
251 'change' : function(f, nv, ov) {
252 tb.selectedNode.setAttribute(f.attrname, nv);
253 editorcore.syncValue();
261 ret.forEach(function(e) {
268 buildToolbarDelete : function()
274 cls : 'roo-htmleditor-fill'
277 this.deleteBtn = this.addxtypeChild({
283 click : this.onDelete.createDelegate(this)
286 this.deleteBtn.hide();
291 onDelete : function()
293 var range = this.editorcore.createRange();
294 var selection = this.editorcore.getSelection();
295 var sn = this.selectedNode;
296 range.setStart(sn,0);
300 if (sn.hasAttribute('data-block')) {
301 var block = Roo.htmleditor.Block.factory(tb.selectedNode);
304 selection.removeAllRanges();
305 selection.addRange(range);
306 this.updateToolbar(null, null, null);
311 return; // should not really happen..
313 if (sn && sn.tagName == 'BODY') {
316 var stn = sn.childNodes[0] || sn.nextSibling || sn.previousSibling || sn.parentNode;
318 // remove and keep parents.
319 a = new Roo.htmleditor.FilterKeepChildren({tag : false});
322 selection.removeAllRanges();
323 selection.addRange(range);
324 this.editorcore.fireEditorEvent(false);
329 * Protected method that will not generally be called directly. It triggers
330 * a toolbar update by reading the markup state of the current selection in the editor.
332 * Note you can force an update by calling on('editorevent', scope, false)
334 updateToolbar: function(editor ,ev, sel)
336 var ty = this.constructor.types;
340 ev.stopEvent(); // se if we can stop this looping with mutiple events.
344 // capture mouse up - this is handy for selecting images..
345 // perhaps should go somewhere else...
346 if(!this.editorcore.activated){
347 this.editor.onFirstFocus();
350 //Roo.log(ev ? ev.target : 'NOTARGET');
353 // http://developer.yahoo.com/yui/docs/simple-editor.js.html
354 // selectNode - might want to handle IE?
357 (ev.type == 'mouseup' || ev.type == 'click' ) &&
358 ev.target && ev.target.tagName != 'BODY' ) { // && ev.target.tagName == 'IMG') {
359 // they have click on an image...
360 // let's see if we can change the selection...
366 // this forces an id..
367 Array.from(this.editorcore.doc.body.querySelectorAll('.roo-ed-selection')).forEach(function(e) {
368 e.classList.remove('roo-ed-selection');
371 var ans = this.editorcore.getAllAncestors();
375 sel = ans.length ? (ans[0] ? ans[0] : ans[1]) : this.editorcore.doc.body;
376 sel = sel ? sel : this.editorcore.doc.body;
377 sel = sel.tagName.length ? sel : this.editorcore.doc.body;
381 var tn = sel.tagName.toUpperCase();
382 var lastSel = this.selectedNode;
383 this.selectedNode = sel;
385 // ok see if we are editing a block?
388 // you are not actually selecting the block.
389 if (sel && sel.hasAttribute('data-block')) {
391 } else if (sel && sel.closest('[data-block]')) {
393 db = sel.closest('[data-block]');
399 if (db && this.editorcore.enableBlocks) {
400 block = Roo.htmleditor.Block.factory(db);
405 db.classList.length > 0 ? db.className + ' ' : ''
406 ) + 'roo-ed-selection';
408 // since we removed it earlier... its not there..
409 tn = 'BLOCK.' + db.getAttribute('data-block');
411 //this.editorcore.selectNode(db);
412 if (typeof(this.button_groups[tn]) == 'undefined') {
413 this.button_groups[tn] = this.buildBlockToolbar( block );
415 this.selectedNode = db;
424 if ( this.active_group !== false && this.active_group.name == tn && lastSel == this.selectedNode && ev !== false) {
425 return; // no change?
429 this.deleteBtn.hide();
431 this.hideActiveGroup();
437 if (this.active_group) {
438 this.hideActiveGroup();
440 this.showActiveGroup(tn);
442 this.deleteBtn.show();
445 hideActiveGroup : function()
448 if (this.active_group === false) {
451 this.active_group.forEach(function(e) {
454 this.active_group = false;
456 showActiveGroup : function(tn)
459 if (typeof(this.button_groups[tn]) == 'undefined') {
464 this.active_group = this.button_groups[tn];
466 this.active_group.forEach(function(e) {
471 if (this.selectedNode.hasAttribute('data-block') ) {
472 var block = Roo.htmleditor.Block.factory(this.selectedNode);
473 this.active_group.forEach(function(e) {
474 e.setValue(this.selectedNode.getAttribute(block[e.name]));
480 // based on attributes...
481 this.active_group.forEach(function(e) {
482 if (typeof(e.attrname) == 'undefined') {
485 e.setValue(this.selectedNode.getAttribute(e.attrname));