Roo/form/HtmlEditor/ToolbarStandard.js
[roojs1] / Roo / form / HtmlEditor / ToolbarStandard.js
1 // <script type="text/javascript">
2 /*
3  * Based on
4  * Ext JS Library 1.1.1
5  * Copyright(c) 2006-2007, Ext JS, LLC.
6  *  
7  
8  */
9
10 /**
11  * @class Roo.form.HtmlEditorToolbar1
12  * Basic Toolbar
13  * 
14  * Usage:
15  *
16  new Roo.form.HtmlEditor({
17     ....
18     toolbars : [
19         new Roo.form.HtmlEditorToolbar1({
20             disable : { fonts: 1 , format: 1, ..., ... , ...],
21             btns : [ .... ]
22         })
23     }
24      
25  * 
26  * @cfg {Object} disable List of elements to disable..
27  * @cfg {Array} btns List of additional buttons.
28  * 
29  * 
30  * NEEDS Extra CSS? 
31  * .x-html-editor-tb .x-edit-none .x-btn-text { background: none; }
32  */
33  
34 Roo.form.HtmlEditor.ToolbarStandard = function(config)
35 {
36     
37     Roo.apply(this, config);
38     //Roo.form.HtmlEditorToolbar1.superclass.constructor.call(this, editor.wrap.dom.firstChild, [], config);
39     // dont call parent... till later.
40 }
41
42 Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
43     
44     tb: false,
45     
46     rendered: false,
47     
48     editor : false,
49     /**
50      * @cfg {Object} disable  List of toolbar elements to disable
51          
52      */
53     disable : false,
54       /**
55      * @cfg {Array} fontFamilies An array of available font families
56      */
57     fontFamilies : [
58         'Arial',
59         'Courier New',
60         'Tahoma',
61         'Times New Roman',
62         'Verdana'
63     ],
64     
65     specialChars : [
66            "&#169;",
67           "&#174;",     
68           "&#8482;",    
69           "&#163;" ,    
70          // "&#8212;",    
71           "&#8230;",    
72           "&#247;" ,    
73         //  "&#225;" ,     ?? a acute?
74            "&#8364;"    , //Euro
75        //   "&#8220;"    ,
76         //  "&#8221;"    ,
77         //  "&#8226;"    ,
78           "&#176;"  //   , // degrees
79
80          // "&#233;"     , // e ecute
81          // "&#250;"     , // u ecute?
82     ],
83     inputElements : [ 
84             "form", "input:text", "input:hidden", "input:checkbox", "input:radio", "input:password", 
85             "input:submit", "input:button", "select", "textarea", "label" ],
86     formats : [
87         ["p"] ,  
88         ["h1"],["h2"],["h3"],["h4"],["h5"],["h6"], 
89         ["pre"],[ "code"], 
90         ["abbr"],[ "acronym"],[ "address"],[ "cite"],[ "samp"],[ "var"]
91     ],
92      /**
93      * @cfg {String} defaultFont default font to use.
94      */
95     defaultFont: 'tahoma',
96    
97     fontSelect : false,
98     
99     
100     formatCombo : false,
101     
102     init : function(editor)
103     {
104         this.editor = editor;
105         
106         
107         var fid = editor.frameId;
108         var etb = this;
109         function btn(id, toggle, handler){
110             var xid = fid + '-'+ id ;
111             return {
112                 id : xid,
113                 cmd : id,
114                 cls : 'x-btn-icon x-edit-'+id,
115                 enableToggle:toggle !== false,
116                 scope: editor, // was editor...
117                 handler:handler||editor.relayBtnCmd,
118                 clickEvent:'mousedown',
119                 tooltip: etb.buttonTips[id] || undefined, ///tips ???
120                 tabIndex:-1
121             };
122         }
123         
124         
125         
126         var tb = new Roo.Toolbar(editor.wrap.dom.firstChild);
127         this.tb = tb;
128          // stop form submits
129         tb.el.on('click', function(e){
130             e.preventDefault(); // what does this do?
131         });
132
133         if(!this.disable.font && !Roo.isSafari){
134             /* why no safari for fonts
135             editor.fontSelect = tb.el.createChild({
136                 tag:'select',
137                 tabIndex: -1,
138                 cls:'x-font-select',
139                 html: editor.createFontOptions()
140             });
141             editor.fontSelect.on('change', function(){
142                 var font = editor.fontSelect.dom.value;
143                 editor.relayCmd('fontname', font);
144                 editor.deferFocus();
145             }, editor);
146             tb.add(
147                 editor.fontSelect.dom,
148                 '-'
149             );
150             */
151         };
152         if(!this.disable.formats){
153             this.formatCombo = new Roo.form.ComboBox({
154                 store: new Roo.data.SimpleStore({
155                     id : 'tag',
156                     fields: ['tag'],
157                     data : this.formats // from states.js
158                 }),
159                 blockFocus : true,
160                 //autoCreate : {tag: "div",  size: "20"},
161                 displayField:'tag',
162                 typeAhead: false,
163                 mode: 'local',
164                 editable : false,
165                 triggerAction: 'all',
166                 emptyText:'Add tag',
167                 selectOnFocus:true,
168                 width:135,
169                 listeners : {
170                     'select': function(c, r, i) {
171                         editor.insertTag(r.get('tag'));
172                         editor.focus();
173                     }
174                 }
175
176             });
177             tb.addField(this.formatCombo);
178             
179         }
180         
181         if(!this.disable.format){
182             tb.add(
183                 btn('bold'),
184                 btn('italic'),
185                 btn('underline')
186             );
187         };
188         if(!this.disable.fontSize){
189             tb.add(
190                 '-',
191                 
192                 
193                 btn('increasefontsize', false, editor.adjustFont),
194                 btn('decreasefontsize', false, editor.adjustFont)
195             );
196         };
197         
198         
199         if(this.disable.colors){
200             tb.add(
201                 '-', {
202                     id:editor.frameId +'-forecolor',
203                     cls:'x-btn-icon x-edit-forecolor',
204                     clickEvent:'mousedown',
205                     tooltip: this.buttonTips['forecolor'] || undefined,
206                     tabIndex:-1,
207                     menu : new Roo.menu.ColorMenu({
208                         allowReselect: true,
209                         focus: Roo.emptyFn,
210                         value:'000000',
211                         plain:true,
212                         selectHandler: function(cp, color){
213                             editor.execCmd('forecolor', Roo.isSafari || Roo.isIE ? '#'+color : color);
214                             editor.deferFocus();
215                         },
216                         scope: editor,
217                         clickEvent:'mousedown'
218                     })
219                 }, {
220                     id:editor.frameId +'backcolor',
221                     cls:'x-btn-icon x-edit-backcolor',
222                     clickEvent:'mousedown',
223                     tooltip: this.buttonTips['backcolor'] || undefined,
224                     tabIndex:-1,
225                     menu : new Roo.menu.ColorMenu({
226                         focus: Roo.emptyFn,
227                         value:'FFFFFF',
228                         plain:true,
229                         allowReselect: true,
230                         selectHandler: function(cp, color){
231                             if(Roo.isGecko){
232                                 editor.execCmd('useCSS', false);
233                                 editor.execCmd('hilitecolor', color);
234                                 editor.execCmd('useCSS', true);
235                                 editor.deferFocus();
236                             }else{
237                                 editor.execCmd(Roo.isOpera ? 'hilitecolor' : 'backcolor', 
238                                     Roo.isSafari || Roo.isIE ? '#'+color : color);
239                                 editor.deferFocus();
240                             }
241                         },
242                         scope:editor,
243                         clickEvent:'mousedown'
244                     })
245                 }
246             );
247         };
248         // now add all the items...
249         
250
251         if(!this.disable.alignments){
252             tb.add(
253                 '-',
254                 btn('justifyleft'),
255                 btn('justifycenter'),
256                 btn('justifyright')
257             );
258         };
259
260         //if(!Roo.isSafari){
261             if(!this.disable.links){
262                 tb.add(
263                     '-',
264                     btn('createlink', false, editor.createLink)    /// MOVE TO HERE?!!?!?!?!
265                 );
266             };
267
268             if(!this.disable.lists){
269                 tb.add(
270                     '-',
271                     btn('insertorderedlist'),
272                     btn('insertunorderedlist')
273                 );
274             }
275             if(!this.disable.sourceEdit){
276                 tb.add(
277                     '-',
278                     btn('sourceedit', true, function(btn){
279                         this.toggleSourceEdit(btn.pressed);
280                     })
281                 );
282             }
283         //}
284         
285         var smenu = { };
286         // special menu.. - needs to be tidied up..
287         if (!this.disable.special) {
288             smenu = {
289                 text: "&#169;",
290                 cls: 'x-edit-none',
291                 menu : {
292                     items : []
293                    }
294             };
295             for (var i =0; i < this.specialChars.length; i++) {
296                 smenu.menu.items.push({
297                     
298                     html: this.specialChars[i],
299                     handler: function(a,b) {
300                         //editor.insertAtCursor(String.fromCharCode(a.text.replace('&#','').replace(';', '')));
301                         editor.insertAtCursor(a.html.replace('&#','').replace(';', '')));
302                     },
303                     tabIndex:-1
304                 });
305             }
306             
307             
308             tb.add(smenu);
309             
310             
311         }
312         if (this.btns) {
313             for(var i =0; i< this.btns.length;i++) {
314                 var b = this.btns[i];
315                 b.cls =  'x-edit-none';
316                 b.scope = editor;
317                 tb.add(b);
318             }
319         
320         }
321         
322         
323         
324         // disable everything...
325         
326         this.tb.items.each(function(item){
327            if(item.id != editor.frameId+ '-sourceedit'){
328                 item.disable();
329             }
330         });
331         this.rendered = true;
332         
333         // the all the btns;
334         editor.on('editorevent', this.updateToolbar, this);
335         // other toolbars need to implement this..
336         //editor.on('editmodechange', this.updateToolbar, this);
337     },
338     
339     
340     
341     /**
342      * Protected method that will not generally be called directly. It triggers
343      * a toolbar update by reading the markup state of the current selection in the editor.
344      */
345     updateToolbar: function(){
346
347         if(!this.editor.activated){
348             this.editor.onFirstFocus();
349             return;
350         }
351
352         var btns = this.tb.items.map, 
353             doc = this.editor.doc,
354             frameId = this.editor.frameId;
355
356         if(!this.disable.font && !Roo.isSafari){
357             /*
358             var name = (doc.queryCommandValue('FontName')||this.editor.defaultFont).toLowerCase();
359             if(name != this.fontSelect.dom.value){
360                 this.fontSelect.dom.value = name;
361             }
362             */
363         }
364         if(!this.disable.format){
365             btns[frameId + '-bold'].toggle(doc.queryCommandState('bold'));
366             btns[frameId + '-italic'].toggle(doc.queryCommandState('italic'));
367             btns[frameId + '-underline'].toggle(doc.queryCommandState('underline'));
368         }
369         if(!this.disable.alignments){
370             btns[frameId + '-justifyleft'].toggle(doc.queryCommandState('justifyleft'));
371             btns[frameId + '-justifycenter'].toggle(doc.queryCommandState('justifycenter'));
372             btns[frameId + '-justifyright'].toggle(doc.queryCommandState('justifyright'));
373         }
374         if(!Roo.isSafari && !this.disable.lists){
375             btns[frameId + '-insertorderedlist'].toggle(doc.queryCommandState('insertorderedlist'));
376             btns[frameId + '-insertunorderedlist'].toggle(doc.queryCommandState('insertunorderedlist'));
377         }
378         
379         var ans = this.editor.getAllAncestors();
380         if (this.formatCombo) {
381             
382             
383             var store = this.formatCombo.store;
384             this.formatCombo.setValue("");
385             for (var i =0; i < ans.length;i++) {
386                 if (ans[i] && store.query('tag',ans[i].tagName.toLowerCase(), false).length) {
387                     // select it..
388                     this.formatCombo.setValue(ans[i].tagName.toLowerCase());
389                     break;
390                 }
391             }
392         }
393         
394         
395         
396         // hides menus... - so this cant be on a menu...
397         Roo.menu.MenuMgr.hideAll();
398
399         //this.editorsyncValue();
400     },
401    
402     
403     createFontOptions : function(){
404         var buf = [], fs = this.fontFamilies, ff, lc;
405         for(var i = 0, len = fs.length; i< len; i++){
406             ff = fs[i];
407             lc = ff.toLowerCase();
408             buf.push(
409                 '<option value="',lc,'" style="font-family:',ff,';"',
410                     (this.defaultFont == lc ? ' selected="true">' : '>'),
411                     ff,
412                 '</option>'
413             );
414         }
415         return buf.join('');
416     },
417     
418     toggleSourceEdit : function(sourceEditMode){
419         if(sourceEditMode === undefined){
420             sourceEditMode = !this.sourceEditMode;
421         }
422         this.sourceEditMode = sourceEditMode === true;
423         var btn = this.tb.items.get(this.editor.frameId +'-sourceedit');
424         // just toggle the button?
425         if(btn.pressed !== this.editor.sourceEditMode){
426             btn.toggle(this.editor.sourceEditMode);
427             return;
428         }
429         
430         if(this.sourceEditMode){
431             this.tb.items.each(function(item){
432                 if(item.cmd != 'sourceedit'){
433                     item.disable();
434                 }
435             });
436           
437         }else{
438             if(this.initialized){
439                 this.tb.items.each(function(item){
440                     item.enable();
441                 });
442             }
443             
444         }
445         // tell the editor that it's been pressed..
446         this.editor.toggleSourceEdit(sourceEditMode);
447        
448     },
449      /**
450      * Object collection of toolbar tooltips for the buttons in the editor. The key
451      * is the command id associated with that button and the value is a valid QuickTips object.
452      * For example:
453 <pre><code>
454 {
455     bold : {
456         title: 'Bold (Ctrl+B)',
457         text: 'Make the selected text bold.',
458         cls: 'x-html-editor-tip'
459     },
460     italic : {
461         title: 'Italic (Ctrl+I)',
462         text: 'Make the selected text italic.',
463         cls: 'x-html-editor-tip'
464     },
465     ...
466 </code></pre>
467     * @type Object
468      */
469     buttonTips : {
470         bold : {
471             title: 'Bold (Ctrl+B)',
472             text: 'Make the selected text bold.',
473             cls: 'x-html-editor-tip'
474         },
475         italic : {
476             title: 'Italic (Ctrl+I)',
477             text: 'Make the selected text italic.',
478             cls: 'x-html-editor-tip'
479         },
480         underline : {
481             title: 'Underline (Ctrl+U)',
482             text: 'Underline the selected text.',
483             cls: 'x-html-editor-tip'
484         },
485         increasefontsize : {
486             title: 'Grow Text',
487             text: 'Increase the font size.',
488             cls: 'x-html-editor-tip'
489         },
490         decreasefontsize : {
491             title: 'Shrink Text',
492             text: 'Decrease the font size.',
493             cls: 'x-html-editor-tip'
494         },
495         backcolor : {
496             title: 'Text Highlight Color',
497             text: 'Change the background color of the selected text.',
498             cls: 'x-html-editor-tip'
499         },
500         forecolor : {
501             title: 'Font Color',
502             text: 'Change the color of the selected text.',
503             cls: 'x-html-editor-tip'
504         },
505         justifyleft : {
506             title: 'Align Text Left',
507             text: 'Align text to the left.',
508             cls: 'x-html-editor-tip'
509         },
510         justifycenter : {
511             title: 'Center Text',
512             text: 'Center text in the editor.',
513             cls: 'x-html-editor-tip'
514         },
515         justifyright : {
516             title: 'Align Text Right',
517             text: 'Align text to the right.',
518             cls: 'x-html-editor-tip'
519         },
520         insertunorderedlist : {
521             title: 'Bullet List',
522             text: 'Start a bulleted list.',
523             cls: 'x-html-editor-tip'
524         },
525         insertorderedlist : {
526             title: 'Numbered List',
527             text: 'Start a numbered list.',
528             cls: 'x-html-editor-tip'
529         },
530         createlink : {
531             title: 'Hyperlink',
532             text: 'Make the selected text a hyperlink.',
533             cls: 'x-html-editor-tip'
534         },
535         sourceedit : {
536             title: 'Source Edit',
537             text: 'Switch to source editing mode.',
538             cls: 'x-html-editor-tip'
539         }
540     },
541     // private
542     onDestroy : function(){
543         if(this.rendered){
544             
545             this.tb.items.each(function(item){
546                 if(item.menu){
547                     item.menu.removeAll();
548                     if(item.menu.el){
549                         item.menu.el.destroy();
550                     }
551                 }
552                 item.destroy();
553             });
554              
555         }
556     },
557     onFirstFocus: function() {
558         this.tb.items.each(function(item){
559            item.enable();
560         });
561     }
562 });
563
564
565
566