initial import
[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                     text: this.specialChars[i],
299                     handler: function(a,b) {
300                         editor.insertAtCursor(String.fromCharCode(a.text.replace('&#','').replace(';', '')));
301                     },
302                     tabIndex:-1
303                 });
304             }
305             
306             
307             tb.add(smenu);
308             
309             
310         }
311         if (this.btns) {
312             for(var i =0; i< this.btns.length;i++) {
313                 var b = this.btns[i];
314                 b.cls =  'x-edit-none';
315                 b.scope = editor;
316                 tb.add(b);
317             }
318         
319         }
320         
321         
322         
323         // disable everything...
324         
325         this.tb.items.each(function(item){
326            if(item.id != editor.frameId+ '-sourceedit'){
327                 item.disable();
328             }
329         });
330         this.rendered = true;
331         
332         // the all the btns;
333         editor.on('editorevent', this.updateToolbar, this);
334         // other toolbars need to implement this..
335         //editor.on('editmodechange', this.updateToolbar, this);
336     },
337     
338     
339     
340     /**
341      * Protected method that will not generally be called directly. It triggers
342      * a toolbar update by reading the markup state of the current selection in the editor.
343      */
344     updateToolbar: function(){
345
346         if(!this.editor.activated){
347             this.editor.onFirstFocus();
348             return;
349         }
350
351         var btns = this.tb.items.map, 
352             doc = this.editor.doc,
353             frameId = this.editor.frameId;
354
355         if(!this.disable.font && !Roo.isSafari){
356             /*
357             var name = (doc.queryCommandValue('FontName')||this.editor.defaultFont).toLowerCase();
358             if(name != this.fontSelect.dom.value){
359                 this.fontSelect.dom.value = name;
360             }
361             */
362         }
363         if(!this.disable.format){
364             btns[frameId + '-bold'].toggle(doc.queryCommandState('bold'));
365             btns[frameId + '-italic'].toggle(doc.queryCommandState('italic'));
366             btns[frameId + '-underline'].toggle(doc.queryCommandState('underline'));
367         }
368         if(!this.disable.alignments){
369             btns[frameId + '-justifyleft'].toggle(doc.queryCommandState('justifyleft'));
370             btns[frameId + '-justifycenter'].toggle(doc.queryCommandState('justifycenter'));
371             btns[frameId + '-justifyright'].toggle(doc.queryCommandState('justifyright'));
372         }
373         if(!Roo.isSafari && !this.disable.lists){
374             btns[frameId + '-insertorderedlist'].toggle(doc.queryCommandState('insertorderedlist'));
375             btns[frameId + '-insertunorderedlist'].toggle(doc.queryCommandState('insertunorderedlist'));
376         }
377         
378         var ans = this.editor.getAllAncestors();
379         if (this.formatCombo) {
380             
381             
382             var store = this.formatCombo.store;
383             this.formatCombo.setValue("");
384             for (var i =0; i < ans.length;i++) {
385                 if (ans[i] && store.query('tag',ans[i].tagName.toLowerCase(), true).length) {
386                     // select it..
387                     this.formatCombo.setValue(ans[i].tagName.toLowerCase());
388                     break;
389                 }
390             }
391         }
392         
393         
394         
395         // hides menus... - so this cant be on a menu...
396         Roo.menu.MenuMgr.hideAll();
397
398         //this.editorsyncValue();
399     },
400    
401     
402     createFontOptions : function(){
403         var buf = [], fs = this.fontFamilies, ff, lc;
404         for(var i = 0, len = fs.length; i< len; i++){
405             ff = fs[i];
406             lc = ff.toLowerCase();
407             buf.push(
408                 '<option value="',lc,'" style="font-family:',ff,';"',
409                     (this.defaultFont == lc ? ' selected="true">' : '>'),
410                     ff,
411                 '</option>'
412             );
413         }
414         return buf.join('');
415     },
416     
417     toggleSourceEdit : function(sourceEditMode){
418         if(sourceEditMode === undefined){
419             sourceEditMode = !this.sourceEditMode;
420         }
421         this.sourceEditMode = sourceEditMode === true;
422         var btn = this.tb.items.get(this.editor.frameId +'-sourceedit');
423         // just toggle the button?
424         if(btn.pressed !== this.editor.sourceEditMode){
425             btn.toggle(this.editor.sourceEditMode);
426             return;
427         }
428         
429         if(this.sourceEditMode){
430             this.tb.items.each(function(item){
431                 if(item.cmd != 'sourceedit'){
432                     item.disable();
433                 }
434             });
435           
436         }else{
437             if(this.initialized){
438                 this.tb.items.each(function(item){
439                     item.enable();
440                 });
441             }
442             
443         }
444         // tell the editor that it's been pressed..
445         this.editor.toggleSourceEdit(sourceEditMode);
446        
447     },
448      /**
449      * Object collection of toolbar tooltips for the buttons in the editor. The key
450      * is the command id associated with that button and the value is a valid QuickTips object.
451      * For example:
452 <pre><code>
453 {
454     bold : {
455         title: 'Bold (Ctrl+B)',
456         text: 'Make the selected text bold.',
457         cls: 'x-html-editor-tip'
458     },
459     italic : {
460         title: 'Italic (Ctrl+I)',
461         text: 'Make the selected text italic.',
462         cls: 'x-html-editor-tip'
463     },
464     ...
465 </code></pre>
466     * @type Object
467      */
468     buttonTips : {
469         bold : {
470             title: 'Bold (Ctrl+B)',
471             text: 'Make the selected text bold.',
472             cls: 'x-html-editor-tip'
473         },
474         italic : {
475             title: 'Italic (Ctrl+I)',
476             text: 'Make the selected text italic.',
477             cls: 'x-html-editor-tip'
478         },
479         underline : {
480             title: 'Underline (Ctrl+U)',
481             text: 'Underline the selected text.',
482             cls: 'x-html-editor-tip'
483         },
484         increasefontsize : {
485             title: 'Grow Text',
486             text: 'Increase the font size.',
487             cls: 'x-html-editor-tip'
488         },
489         decreasefontsize : {
490             title: 'Shrink Text',
491             text: 'Decrease the font size.',
492             cls: 'x-html-editor-tip'
493         },
494         backcolor : {
495             title: 'Text Highlight Color',
496             text: 'Change the background color of the selected text.',
497             cls: 'x-html-editor-tip'
498         },
499         forecolor : {
500             title: 'Font Color',
501             text: 'Change the color of the selected text.',
502             cls: 'x-html-editor-tip'
503         },
504         justifyleft : {
505             title: 'Align Text Left',
506             text: 'Align text to the left.',
507             cls: 'x-html-editor-tip'
508         },
509         justifycenter : {
510             title: 'Center Text',
511             text: 'Center text in the editor.',
512             cls: 'x-html-editor-tip'
513         },
514         justifyright : {
515             title: 'Align Text Right',
516             text: 'Align text to the right.',
517             cls: 'x-html-editor-tip'
518         },
519         insertunorderedlist : {
520             title: 'Bullet List',
521             text: 'Start a bulleted list.',
522             cls: 'x-html-editor-tip'
523         },
524         insertorderedlist : {
525             title: 'Numbered List',
526             text: 'Start a numbered list.',
527             cls: 'x-html-editor-tip'
528         },
529         createlink : {
530             title: 'Hyperlink',
531             text: 'Make the selected text a hyperlink.',
532             cls: 'x-html-editor-tip'
533         },
534         sourceedit : {
535             title: 'Source Edit',
536             text: 'Switch to source editing mode.',
537             cls: 'x-html-editor-tip'
538         }
539     },
540     // private
541     onDestroy : function(){
542         if(this.rendered){
543             
544             this.tb.items.each(function(item){
545                 if(item.menu){
546                     item.menu.removeAll();
547                     if(item.menu.el){
548                         item.menu.el.destroy();
549                     }
550                 }
551                 item.destroy();
552             });
553              
554         }
555     },
556     onFirstFocus: function() {
557         this.tb.items.each(function(item){
558            item.enable();
559         });
560     }
561 });
562
563
564
565