support resize on bootstrap html editor
[roojs1] / Roo / bootstrap / form / HtmlEditor.js
1 /*
2  * - LGPL
3  *
4  * HtmlEditor
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.form.HtmlEditor
10  * @extends Roo.bootstrap.form.TextArea
11  * Bootstrap HtmlEditor class
12
13  * @constructor
14  * Create a new HtmlEditor
15  * @param {Object} config The config object
16  */
17
18 Roo.bootstrap.form.HtmlEditor = function(config){
19     Roo.bootstrap.form.HtmlEditor.superclass.constructor.call(this, config);
20     if (!this.toolbars) {
21         this.toolbars = [];
22     }
23     
24     this.editorcore = new Roo.HtmlEditorCore(Roo.apply({ owner : this} , config));
25     this.addEvents({
26             /**
27              * @event initialize
28              * Fires when the editor is fully initialized (including the iframe)
29              * @param {HtmlEditor} this
30              */
31             initialize: true,
32             /**
33              * @event activate
34              * Fires when the editor is first receives the focus. Any insertion must wait
35              * until after this event.
36              * @param {HtmlEditor} this
37              */
38             activate: true,
39              /**
40              * @event beforesync
41              * Fires before the textarea is updated with content from the editor iframe. Return false
42              * to cancel the sync.
43              * @param {HtmlEditor} this
44              * @param {String} html
45              */
46             beforesync: true,
47              /**
48              * @event beforepush
49              * Fires before the iframe editor is updated with content from the textarea. Return false
50              * to cancel the push.
51              * @param {HtmlEditor} this
52              * @param {String} html
53              */
54             beforepush: true,
55              /**
56              * @event sync
57              * Fires when the textarea is updated with content from the editor iframe.
58              * @param {HtmlEditor} this
59              * @param {String} html
60              */
61             sync: true,
62              /**
63              * @event push
64              * Fires when the iframe editor is updated with content from the textarea.
65              * @param {HtmlEditor} this
66              * @param {String} html
67              */
68             push: true,
69              /**
70              * @event editmodechange
71              * Fires when the editor switches edit modes
72              * @param {HtmlEditor} this
73              * @param {Boolean} sourceEdit True if source edit, false if standard editing.
74              */
75             editmodechange: true,
76             /**
77              * @event editorevent
78              * Fires when on any editor (mouse up/down cursor movement etc.) - used for toolbar hooks.
79              * @param {HtmlEditor} this
80              */
81             editorevent: true,
82             /**
83              * @event firstfocus
84              * Fires when on first focus - needed by toolbars..
85              * @param {HtmlEditor} this
86              */
87             firstfocus: true,
88             /**
89              * @event autosave
90              * Auto save the htmlEditor value as a file into Events
91              * @param {HtmlEditor} this
92              */
93             autosave: true,
94             /**
95              * @event savedpreview
96              * preview the saved version of htmlEditor
97              * @param {HtmlEditor} this
98              */
99             savedpreview: true
100         });
101 };
102
103
104 Roo.extend(Roo.bootstrap.form.HtmlEditor, Roo.bootstrap.form.TextArea,  {
105     
106     
107       /**
108      * @cfg {Array} toolbars Array of toolbars. - defaults to just the Standard one
109      */
110     toolbars : false,
111     
112      /**
113     * @cfg {Array} buttons Array of toolbar's buttons. - defaults to empty
114     */
115     btns : [],
116    
117      /**
118      * @cfg {String} resize  (none|both|horizontal|vertical) - css resize of element
119      */
120     resize : false,
121      /**
122      * @cfg {Number} height (in pixels)
123      */   
124     height: 300,
125    /**
126      * @cfg {Number} width (in pixels)
127      */   
128     width: false,
129     
130     /**
131      * @cfg {Array} stylesheets url of stylesheets. set to [] to disable stylesheets.
132      * 
133      */
134     stylesheets: false,
135     
136     // id of frame..
137     frameId: false,
138     
139     // private properties
140     validationEvent : false,
141     deferHeight: true,
142     initialized : false,
143     activated : false,
144     
145     onFocus : Roo.emptyFn,
146     iframePad:3,
147     hideMode:'offsets',
148     
149     tbContainer : false,
150     
151     bodyCls : '',
152     
153     toolbarContainer :function() {
154         return this.wrap.select('.x-html-editor-tb',true).first();
155     },
156
157     /**
158      * Protected method that will not generally be called directly. It
159      * is called when the editor creates its toolbar. Override this method if you need to
160      * add custom toolbar buttons.
161      * @param {HtmlEditor} editor
162      */
163     createToolbar : function(){
164         Roo.log('renewing');
165         Roo.log("create toolbars");
166         
167         this.toolbars = [ new Roo.bootstrap.form.HtmlEditorToolbarStandard({editor: this} ) ];
168         this.toolbars[0].render(this.toolbarContainer());
169         
170         return;
171         
172 //        if (!editor.toolbars || !editor.toolbars.length) {
173 //            editor.toolbars = [ new Roo.bootstrap.form.HtmlEditorToolbarStandard() ]; // can be empty?
174 //        }
175 //        
176 //        for (var i =0 ; i < editor.toolbars.length;i++) {
177 //            editor.toolbars[i] = Roo.factory(
178 //                    typeof(editor.toolbars[i]) == 'string' ?
179 //                        { xtype: editor.toolbars[i]} : editor.toolbars[i],
180 //                Roo.bootstrap.form.HtmlEditor);
181 //            editor.toolbars[i].init(editor);
182 //        }
183     },
184
185      
186     // private
187     onRender : function(ct, position)
188     {
189        // Roo.log("Call onRender: " + this.xtype);
190         var _t = this;
191         Roo.bootstrap.form.HtmlEditor.superclass.onRender.call(this, ct, position);
192       
193         this.wrap = this.inputEl().wrap({
194             cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
195         });
196         
197         this.editorcore.onRender(ct, position);
198          
199          
200         this.createToolbar(this);
201        
202         
203           
204         
205     },
206
207     // private
208     onResize : function(w, h)
209     {
210         Roo.log('resize: ' +w + ',' + h );
211         Roo.bootstrap.form.HtmlEditor.superclass.onResize.apply(this, arguments);
212         var ew = false;
213         var eh = false;
214         
215         if(this.inputEl() ){
216             if(typeof w == 'number'){
217                 var aw = w - this.wrap.getFrameWidth('lr');
218                 this.inputEl().setWidth(this.adjustWidth('textarea', aw));
219                 ew = aw;
220             }
221             if(typeof h == 'number'){
222                  var tbh = -11;  // fixme it needs to tool bar size!
223                 for (var i =0; i < this.toolbars.length;i++) {
224                     // fixme - ask toolbars for heights?
225                     tbh += this.toolbars[i].el.getHeight();
226                     //if (this.toolbars[i].footer) {
227                     //    tbh += this.toolbars[i].footer.el.getHeight();
228                     //}
229                 }
230               
231                 
232                 
233                 
234                 
235                 var ah = h - this.wrap.getFrameWidth('tb') - tbh;// this.tb.el.getHeight();
236                 ah -= 5; // knock a few pixes off for look..
237                 this.inputEl().setHeight(this.adjustWidth('textarea', ah));
238                 var eh = ah;
239             }
240         }
241         Roo.log('onResize:' + [w,h,ew,eh].join(',') );
242         this.editorcore.onResize(ew,eh);
243         
244     },
245
246     /**
247      * Toggles the editor between standard and source edit mode.
248      * @param {Boolean} sourceEdit (optional) True for source edit, false for standard
249      */
250     toggleSourceEdit : function(sourceEditMode)
251     {
252         this.editorcore.toggleSourceEdit(sourceEditMode);
253         
254         if(this.editorcore.sourceEditMode){
255             Roo.log('editor - showing textarea');
256             
257 //            Roo.log('in');
258 //            Roo.log(this.syncValue());
259             this.syncValue();
260             this.inputEl().removeClass(['hide', 'x-hidden']);
261             this.inputEl().dom.removeAttribute('tabIndex');
262             this.inputEl().focus();
263         }else{
264             Roo.log('editor - hiding textarea');
265 //            Roo.log('out')
266 //            Roo.log(this.pushValue()); 
267             this.pushValue();
268             
269             this.inputEl().addClass(['hide', 'x-hidden']);
270             this.inputEl().dom.setAttribute('tabIndex', -1);
271             //this.deferFocus();
272         }
273          
274         //if(this.resizable){
275         //    this.setSize(this.wrap.getSize());
276         //}
277         
278         this.fireEvent('editmodechange', this, this.editorcore.sourceEditMode);
279     },
280  
281     // private (for BoxComponent)
282     adjustSize : Roo.BoxComponent.prototype.adjustSize,
283
284     // private (for BoxComponent)
285     getResizeEl : function(){
286         return this.wrap;
287     },
288
289     // private (for BoxComponent)
290     getPositionEl : function(){
291         return this.wrap;
292     },
293
294     // private
295     initEvents : function(){
296         this.originalValue = this.getValue();
297     },
298
299 //    /**
300 //     * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
301 //     * @method
302 //     */
303 //    markInvalid : Roo.emptyFn,
304 //    /**
305 //     * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
306 //     * @method
307 //     */
308 //    clearInvalid : Roo.emptyFn,
309
310     setValue : function(v){
311         Roo.bootstrap.form.HtmlEditor.superclass.setValue.call(this, v);
312         this.editorcore.pushValue();
313     },
314
315      
316     // private
317     deferFocus : function(){
318         this.focus.defer(10, this);
319     },
320
321     // doc'ed in Field
322     focus : function(){
323         this.editorcore.focus();
324         
325     },
326       
327
328     // private
329     onDestroy : function(){
330         
331         
332         
333         if(this.rendered){
334             
335             for (var i =0; i < this.toolbars.length;i++) {
336                 // fixme - ask toolbars for heights?
337                 this.toolbars[i].onDestroy();
338             }
339             
340             this.wrap.dom.innerHTML = '';
341             this.wrap.remove();
342         }
343     },
344
345     // private
346     onFirstFocus : function(){
347         //Roo.log("onFirstFocus");
348         this.editorcore.onFirstFocus();
349          for (var i =0; i < this.toolbars.length;i++) {
350             this.toolbars[i].onFirstFocus();
351         }
352         
353     },
354     
355     // private
356     syncValue : function()
357     {   
358         this.editorcore.syncValue();
359     },
360     
361     pushValue : function()
362     {   
363         this.editorcore.pushValue();
364     }
365      
366     
367     // hide stuff that is not compatible
368     /**
369      * @event blur
370      * @hide
371      */
372     /**
373      * @event change
374      * @hide
375      */
376     /**
377      * @event focus
378      * @hide
379      */
380     /**
381      * @event specialkey
382      * @hide
383      */
384     /**
385      * @cfg {String} fieldClass @hide
386      */
387     /**
388      * @cfg {String} focusClass @hide
389      */
390     /**
391      * @cfg {String} autoCreate @hide
392      */
393     /**
394      * @cfg {String} inputType @hide
395      */
396      
397     /**
398      * @cfg {String} invalidText @hide
399      */
400     /**
401      * @cfg {String} msgFx @hide
402      */
403     /**
404      * @cfg {String} validateOnBlur @hide
405      */
406 });
407  
408     
409    
410    
411    
412