3 <title>The source code</title>
4 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
5 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 <body onload="prettyPrint();">
8 <pre class="prettyprint lang-js">/*!
10 * Copyright(c) 2006-2009 Ext JS, LLC
12 * http://www.extjs.com/license
14 <div id="cls-Ext.form.HtmlEditor"></div>/**
\r
15 * @class Ext.form.HtmlEditor
\r
16 * @extends Ext.form.Field
\r
17 * Provides a lightweight HTML Editor component. Some toolbar features are not supported by Safari and will be
\r
18 * automatically hidden when needed. These are noted in the config options where appropriate.
\r
19 * <br><br>The editor's toolbar buttons have tooltips defined in the {@link #buttonTips} property, but they are not
\r
20 * enabled by default unless the global {@link Ext.QuickTips} singleton is {@link Ext.QuickTips#init initialized}.
\r
21 * <br><br><b>Note: The focus/blur and validation marking functionality inherited from Ext.form.Field is NOT
\r
22 * supported by this editor.</b>
\r
23 * <br><br>An Editor is a sensitive component that can't be used in all spots standard fields can be used. Putting an Editor within
\r
24 * any element that has display set to 'none' can cause problems in Safari and Firefox due to their default iframe reloading bugs.
\r
25 * <br><br>Example usage:
\r
27 // Simple example rendered with default options:
\r
28 Ext.QuickTips.init(); // enable tooltips
\r
29 new Ext.form.HtmlEditor({
\r
30 renderTo: Ext.getBody(),
\r
35 // Passed via xtype into a container and with custom options:
\r
36 Ext.QuickTips.init(); // enable tooltips
\r
38 title: 'HTML Editor',
\r
39 renderTo: Ext.getBody(),
\r
45 xtype: 'htmleditor',
\r
46 enableColors: false,
\r
47 enableAlignments: false
\r
52 * Create a new HtmlEditor
\r
53 * @param {Object} config
\r
57 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
\r
58 <div id="cfg-Ext.form.HtmlEditor-enableFormat"></div>/**
\r
59 * @cfg {Boolean} enableFormat Enable the bold, italic and underline buttons (defaults to true)
\r
61 enableFormat : true,
\r
62 <div id="cfg-Ext.form.HtmlEditor-enableFontSize"></div>/**
\r
63 * @cfg {Boolean} enableFontSize Enable the increase/decrease font size buttons (defaults to true)
\r
65 enableFontSize : true,
\r
66 <div id="cfg-Ext.form.HtmlEditor-enableColors"></div>/**
\r
67 * @cfg {Boolean} enableColors Enable the fore/highlight color buttons (defaults to true)
\r
69 enableColors : true,
\r
70 <div id="cfg-Ext.form.HtmlEditor-enableAlignments"></div>/**
\r
71 * @cfg {Boolean} enableAlignments Enable the left, center, right alignment buttons (defaults to true)
\r
73 enableAlignments : true,
\r
74 <div id="cfg-Ext.form.HtmlEditor-enableLists"></div>/**
\r
75 * @cfg {Boolean} enableLists Enable the bullet and numbered list buttons. Not available in Safari. (defaults to true)
\r
78 <div id="cfg-Ext.form.HtmlEditor-enableSourceEdit"></div>/**
\r
79 * @cfg {Boolean} enableSourceEdit Enable the switch to source edit button. Not available in Safari. (defaults to true)
\r
81 enableSourceEdit : true,
\r
82 <div id="cfg-Ext.form.HtmlEditor-enableLinks"></div>/**
\r
83 * @cfg {Boolean} enableLinks Enable the create link button. Not available in Safari. (defaults to true)
\r
86 <div id="cfg-Ext.form.HtmlEditor-enableFont"></div>/**
\r
87 * @cfg {Boolean} enableFont Enable font selection. Not available in Safari. (defaults to true)
\r
90 <div id="cfg-Ext.form.HtmlEditor-createLinkText"></div>/**
\r
91 * @cfg {String} createLinkText The default text for the create link prompt
\r
93 createLinkText : 'Please enter the URL for the link:',
\r
94 <div id="cfg-Ext.form.HtmlEditor-defaultLinkValue"></div>/**
\r
95 * @cfg {String} defaultLinkValue The default value for the create link prompt (defaults to http:/ /)
\r
97 defaultLinkValue : 'http:/'+'/',
\r
98 <div id="cfg-Ext.form.HtmlEditor-fontFamilies"></div>/**
\r
99 * @cfg {Array} fontFamilies An array of available font families
\r
108 defaultFont: 'tahoma',
\r
109 <div id="cfg-Ext.form.HtmlEditor-defaultValue"></div>/**
\r
110 * @cfg {String} defaultValue A default value to be put into the editor to resolve focus issues (defaults to ​ (Zero-width space), (Non-breaking space) in Opera and IE6).
\r
112 defaultValue: (Ext.isOpera || Ext.isIE6) ? ' ' : '​',
\r
114 // private properties
\r
115 actionMode: 'wrap',
\r
116 validationEvent : false,
\r
118 initialized : false,
\r
120 sourceEditMode : false,
\r
121 onFocus : Ext.emptyFn,
\r
123 hideMode:'offsets',
\r
124 defaultAutoCreate : {
\r
126 style:"width:500px;height:300px;",
\r
127 autocomplete: "off"
\r
131 initComponent : function(){
\r
133 <div id="event-Ext.form.HtmlEditor-initialize"></div>/**
\r
134 * @event initialize
\r
135 * Fires when the editor is fully initialized (including the iframe)
\r
136 * @param {HtmlEditor} this
\r
139 <div id="event-Ext.form.HtmlEditor-activate"></div>/**
\r
141 * Fires when the editor is first receives the focus. Any insertion must wait
\r
142 * until after this event.
\r
143 * @param {HtmlEditor} this
\r
146 <div id="event-Ext.form.HtmlEditor-beforesync"></div>/**
\r
147 * @event beforesync
\r
148 * Fires before the textarea is updated with content from the editor iframe. Return false
\r
149 * to cancel the sync.
\r
150 * @param {HtmlEditor} this
\r
151 * @param {String} html
\r
154 <div id="event-Ext.form.HtmlEditor-beforepush"></div>/**
\r
155 * @event beforepush
\r
156 * Fires before the iframe editor is updated with content from the textarea. Return false
\r
157 * to cancel the push.
\r
158 * @param {HtmlEditor} this
\r
159 * @param {String} html
\r
162 <div id="event-Ext.form.HtmlEditor-sync"></div>/**
\r
164 * Fires when the textarea is updated with content from the editor iframe.
\r
165 * @param {HtmlEditor} this
\r
166 * @param {String} html
\r
169 <div id="event-Ext.form.HtmlEditor-push"></div>/**
\r
171 * Fires when the iframe editor is updated with content from the textarea.
\r
172 * @param {HtmlEditor} this
\r
173 * @param {String} html
\r
176 <div id="event-Ext.form.HtmlEditor-editmodechange"></div>/**
\r
177 * @event editmodechange
\r
178 * Fires when the editor switches edit modes
\r
179 * @param {HtmlEditor} this
\r
180 * @param {Boolean} sourceEdit True if source edit, false if standard editing.
\r
187 createFontOptions : function(){
\r
188 var buf = [], fs = this.fontFamilies, ff, lc;
\r
189 for(var i = 0, len = fs.length; i< len; i++){
\r
191 lc = ff.toLowerCase();
\r
193 '<option value="',lc,'" style="font-family:',ff,';"',
\r
194 (this.defaultFont == lc ? ' selected="true">' : '>'),
\r
199 return buf.join('');
\r
203 * Protected method that will not generally be called directly. It
\r
204 * is called when the editor creates its toolbar. Override this method if you need to
\r
205 * add custom toolbar buttons.
\r
206 * @param {HtmlEditor} editor
\r
208 createToolbar : function(editor){
\r
210 var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
\r
212 function btn(id, toggle, handler){
\r
215 cls : 'x-btn-icon',
\r
216 iconCls: 'x-edit-'+id,
\r
217 enableToggle:toggle !== false,
\r
219 handler:handler||editor.relayBtnCmd,
\r
220 clickEvent:'mousedown',
\r
221 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
\r
222 overflowText: editor.buttonTips[id].title || undefined,
\r
227 // build the toolbar
\r
228 var tb = new Ext.Toolbar({
\r
229 renderTo:this.wrap.dom.firstChild
\r
232 // stop form submits
\r
233 this.mon(tb.el, 'click', function(e){
\r
234 e.preventDefault();
\r
237 if(this.enableFont && !Ext.isSafari2){
\r
238 this.fontSelect = tb.el.createChild({
\r
240 cls:'x-font-select',
\r
241 html: this.createFontOptions()
\r
243 this.mon(this.fontSelect, 'change', function(){
\r
244 var font = this.fontSelect.dom.value;
\r
245 this.relayCmd('fontname', font);
\r
250 this.fontSelect.dom,
\r
255 if(this.enableFormat){
\r
263 if(this.enableFontSize){
\r
266 btn('increasefontsize', false, this.adjustFont),
\r
267 btn('decreasefontsize', false, this.adjustFont)
\r
271 if(this.enableColors){
\r
274 itemId:'forecolor',
\r
276 iconCls: 'x-edit-forecolor',
\r
277 clickEvent:'mousedown',
\r
278 tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
\r
280 menu : new Ext.menu.ColorMenu({
\r
281 allowReselect: true,
\r
282 focus: Ext.emptyFn,
\r
287 select: function(cp, color){
\r
288 this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
\r
292 clickEvent:'mousedown'
\r
295 itemId:'backcolor',
\r
297 iconCls: 'x-edit-backcolor',
\r
298 clickEvent:'mousedown',
\r
299 tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
\r
301 menu : new Ext.menu.ColorMenu({
\r
302 focus: Ext.emptyFn,
\r
305 allowReselect: true,
\r
308 select: function(cp, color){
\r
310 this.execCmd('useCSS', false);
\r
311 this.execCmd('hilitecolor', color);
\r
312 this.execCmd('useCSS', true);
\r
315 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
\r
320 clickEvent:'mousedown'
\r
326 if(this.enableAlignments){
\r
329 btn('justifyleft'),
\r
330 btn('justifycenter'),
\r
331 btn('justifyright')
\r
335 if(!Ext.isSafari2){
\r
336 if(this.enableLinks){
\r
339 btn('createlink', false, this.createLink)
\r
343 if(this.enableLists){
\r
346 btn('insertorderedlist'),
\r
347 btn('insertunorderedlist')
\r
350 if(this.enableSourceEdit){
\r
353 btn('sourceedit', true, function(btn){
\r
354 this.toggleSourceEdit(!this.sourceEditMode);
\r
363 <div id="method-Ext.form.HtmlEditor-getDocMarkup"></div>/**
\r
364 * Protected method that will not generally be called directly. It
\r
365 * is called when the editor initializes the iframe with HTML contents. Override this method if you
\r
366 * want to change the initialization markup of the iframe (e.g. to add stylesheets).
\r
368 getDocMarkup : function(){
\r
369 return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
\r
373 getEditorBody : function(){
\r
374 return this.doc.body || this.doc.documentElement;
\r
378 getDoc : function(){
\r
379 return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
\r
383 getWin : function(){
\r
384 return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
\r
388 onRender : function(ct, position){
\r
389 Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
\r
390 this.el.dom.style.border = '0 none';
\r
391 this.el.dom.setAttribute('tabIndex', -1);
\r
392 this.el.addClass('x-hidden');
\r
393 if(Ext.isIE){ // fix IE 1px bogus margin
\r
394 this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
\r
396 this.wrap = this.el.wrap({
\r
397 cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
\r
400 this.createToolbar(this);
\r
402 this.disableItems(true);
\r
404 // this.tb.doLayout();
\r
406 this.createIFrame();
\r
409 var sz = this.el.getSize();
\r
410 this.setSize(sz.width, this.height || sz.height);
\r
412 this.resizeEl = this.positionEl = this.wrap;
\r
415 createIFrame: function(){
\r
416 var iframe = document.createElement('iframe');
\r
417 iframe.name = Ext.id();
\r
418 iframe.frameBorder = '0';
\r
419 iframe.src = Ext.SSL_SECURE_URL;
\r
420 this.wrap.dom.appendChild(iframe);
\r
422 this.iframe = iframe;
\r
424 this.monitorTask = Ext.TaskMgr.start({
\r
425 run: this.checkDesignMode,
\r
431 initFrame : function(){
\r
432 Ext.TaskMgr.stop(this.monitorTask);
\r
433 this.doc = this.getDoc();
\r
434 this.win = this.getWin();
\r
437 this.doc.write(this.getDocMarkup());
\r
440 var task = { // must defer to wait for browser to be ready
\r
442 if(this.doc.body || this.doc.readyState == 'complete'){
\r
443 Ext.TaskMgr.stop(task);
\r
444 this.doc.designMode="on";
\r
445 this.initEditor.defer(10, this);
\r
452 Ext.TaskMgr.start(task);
\r
456 checkDesignMode : function(){
\r
457 if(this.wrap && this.wrap.dom.offsetWidth){
\r
458 var doc = this.getDoc();
\r
462 if(!doc.editorInitialized || String(doc.designMode).toLowerCase() != 'on'){
\r
468 disableItems: function(disabled){
\r
469 if(this.fontSelect){
\r
470 this.fontSelect.dom.disabled = disabled;
\r
472 this.tb.items.each(function(item){
\r
473 if(item.getItemId() != 'sourceedit'){
\r
474 item.setDisabled(disabled);
\r
480 onResize : function(w, h){
\r
481 Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
\r
482 if(this.el && this.iframe){
\r
483 if(Ext.isNumber(w)){
\r
484 var aw = w - this.wrap.getFrameWidth('lr');
\r
485 this.el.setWidth(aw);
\r
486 this.tb.setWidth(aw);
\r
487 this.iframe.style.width = Math.max(aw, 0) + 'px';
\r
489 if(Ext.isNumber(h)){
\r
490 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
\r
491 this.el.setHeight(ah);
\r
492 this.iframe.style.height = Math.max(ah, 0) + 'px';
\r
494 this.getEditorBody().style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
\r
500 <div id="method-Ext.form.HtmlEditor-toggleSourceEdit"></div>/**
\r
501 * Toggles the editor between standard and source edit mode.
\r
502 * @param {Boolean} sourceEdit (optional) True for source edit, false for standard
\r
504 toggleSourceEdit : function(sourceEditMode){
\r
505 if(sourceEditMode === undefined){
\r
506 sourceEditMode = !this.sourceEditMode;
\r
508 this.sourceEditMode = sourceEditMode === true;
\r
509 var btn = this.tb.items.get('sourceedit');
\r
510 if(btn.pressed !== this.sourceEditMode){
\r
511 btn.toggle(this.sourceEditMode);
\r
512 if(!btn.xtbHidden){
\r
516 if(this.sourceEditMode){
\r
517 this.disableItems(true);
\r
519 this.iframe.className = 'x-hidden';
\r
520 this.el.removeClass('x-hidden');
\r
521 this.el.dom.removeAttribute('tabIndex');
\r
524 if(this.initialized){
\r
525 this.disableItems(false);
\r
528 this.iframe.className = '';
\r
529 this.el.addClass('x-hidden');
\r
530 this.el.dom.setAttribute('tabIndex', -1);
\r
533 var lastSize = this.lastSize;
\r
535 delete this.lastSize;
\r
536 this.setSize(lastSize);
\r
538 this.fireEvent('editmodechange', this, this.sourceEditMode);
\r
541 // private used internally
\r
542 createLink : function(){
\r
543 var url = prompt(this.createLinkText, this.defaultLinkValue);
\r
544 if(url && url != 'http:/'+'/'){
\r
545 this.relayCmd('createlink', url);
\r
550 initEvents : function(){
\r
551 this.originalValue = this.getValue();
\r
554 <div id="method-Ext.form.HtmlEditor-markInvalid"></div>/**
\r
555 * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
\r
558 markInvalid : Ext.emptyFn,
\r
560 <div id="method-Ext.form.HtmlEditor-clearInvalid"></div>/**
\r
561 * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
\r
564 clearInvalid : Ext.emptyFn,
\r
566 // docs inherit from Field
\r
567 setValue : function(v){
\r
568 Ext.form.HtmlEditor.superclass.setValue.call(this, v);
\r
573 <div id="method-Ext.form.HtmlEditor-cleanHtml"></div>/**
\r
574 * Protected method that will not generally be called directly. If you need/want
\r
575 * custom HTML cleanup, this is the method you should override.
\r
576 * @param {String} html The HTML to be cleaned
\r
577 * @return {String} The cleaned HTML
\r
579 cleanHtml: function(html) {
\r
580 html = String(html);
\r
581 if(Ext.isWebKit){ // strip safari nonsense
\r
582 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
\r
586 * Neat little hack. Strips out all the non-digit characters from the default
\r
587 * value and compares it to the character code of the first character in the string
\r
588 * because it can cause encoding issues when posted to the server.
\r
590 if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){
\r
591 html = html.substring(1);
\r
596 <div id="method-Ext.form.HtmlEditor-syncValue"></div>/**
\r
597 * Protected method that will not generally be called directly. Syncs the contents
\r
598 * of the editor iframe with the textarea.
\r
600 syncValue : function(){
\r
601 if(this.initialized){
\r
602 var bd = this.getEditorBody();
\r
603 var html = bd.innerHTML;
\r
605 var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
\r
606 var m = bs.match(/text-align:(.*?);/i);
\r
608 html = '<div style="'+m[0]+'">' + html + '</div>';
\r
611 html = this.cleanHtml(html);
\r
612 if(this.fireEvent('beforesync', this, html) !== false){
\r
613 this.el.dom.value = html;
\r
614 this.fireEvent('sync', this, html);
\r
619 //docs inherit from Field
\r
620 getValue : function() {
\r
621 this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
\r
622 return Ext.form.HtmlEditor.superclass.getValue.call(this);
\r
625 <div id="method-Ext.form.HtmlEditor-pushValue"></div>/**
\r
626 * Protected method that will not generally be called directly. Pushes the value of the textarea
\r
627 * into the iframe editor.
\r
629 pushValue : function(){
\r
630 if(this.initialized){
\r
631 var v = this.el.dom.value;
\r
632 if(!this.activated && v.length < 1){
\r
633 v = this.defaultValue;
\r
635 if(this.fireEvent('beforepush', this, v) !== false){
\r
636 this.getEditorBody().innerHTML = v;
\r
638 // Gecko hack, see: https://bugzilla.mozilla.org/show_bug.cgi?id=232791#c8
\r
640 mode = d.designMode.toLowerCase();
\r
642 d.designMode = mode.toggle('on', 'off');
\r
643 d.designMode = mode;
\r
645 this.fireEvent('push', this, v);
\r
651 deferFocus : function(){
\r
652 this.focus.defer(10, this);
\r
655 // docs inherit from Field
\r
656 focus : function(){
\r
657 if(this.win && !this.sourceEditMode){
\r
665 initEditor : function(){
\r
666 //Destroying the component during/before initEditor can cause issues.
\r
668 var dbody = this.getEditorBody();
\r
669 var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
\r
670 ss['background-attachment'] = 'fixed'; // w3c
\r
671 dbody.bgProperties = 'fixed'; // ie
\r
673 Ext.DomHelper.applyStyles(dbody, ss);
\r
677 Ext.EventManager.removeAll(this.doc);
\r
681 this.doc = this.getDoc();
\r
683 Ext.EventManager.on(this.doc, {
\r
684 'mousedown': this.onEditorEvent,
\r
685 'dblclick': this.onEditorEvent,
\r
686 'click': this.onEditorEvent,
\r
687 'keyup': this.onEditorEvent,
\r
693 Ext.EventManager.on(this.doc, 'keypress', this.applyCommand, this);
\r
695 if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
\r
696 Ext.EventManager.on(this.doc, 'keydown', this.fixKeys, this);
\r
698 this.initialized = true;
\r
699 this.fireEvent('initialize', this);
\r
700 this.doc.editorInitialized = true;
\r
706 onDestroy : function(){
\r
707 if(this.monitorTask){
\r
708 Ext.TaskMgr.stop(this.monitorTask);
\r
711 Ext.destroy(this.tb);
\r
713 this.wrap.dom.innerHTML = '';
\r
714 this.wrap.remove();
\r
718 this.el.removeAllListeners();
\r
724 Ext.EventManager.removeAll(this.doc);
\r
725 for (var prop in this.doc){
\r
726 delete this.doc[prop];
\r
730 this.purgeListeners();
\r
734 onFirstFocus : function(){
\r
735 this.activated = true;
\r
736 this.disableItems(false);
\r
737 if(Ext.isGecko){ // prevent silly gecko errors
\r
739 var s = this.win.getSelection();
\r
740 if(!s.focusNode || s.focusNode.nodeType != 3){
\r
741 var r = s.getRangeAt(0);
\r
742 r.selectNodeContents(this.getEditorBody());
\r
747 this.execCmd('useCSS', true);
\r
748 this.execCmd('styleWithCSS', false);
\r
751 this.fireEvent('activate', this);
\r
755 adjustFont: function(btn){
\r
756 var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1;
\r
758 var v = parseInt(this.doc.queryCommandValue('FontSize') || 2, 10);
\r
759 if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
\r
761 // 1 = 10px, 2 = 13px, 3 = 16px, 4 = 18px, 5 = 24px, 6 = 32px
\r
775 v = v.constrain(1, 6);
\r
777 if(Ext.isSafari){ // safari
\r
780 v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
\r
782 this.execCmd('FontSize', v);
\r
786 onEditorEvent : function(e){
\r
787 this.updateToolbar();
\r
791 <div id="method-Ext.form.HtmlEditor-updateToolbar"></div>/**
\r
792 * Protected method that will not generally be called directly. It triggers
\r
793 * a toolbar update by reading the markup state of the current selection in the editor.
\r
795 updateToolbar: function(){
\r
797 if(!this.activated){
\r
798 this.onFirstFocus();
\r
802 var btns = this.tb.items.map, doc = this.doc;
\r
804 if(this.enableFont && !Ext.isSafari2){
\r
805 var name = (this.doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
\r
806 if(name != this.fontSelect.dom.value){
\r
807 this.fontSelect.dom.value = name;
\r
810 if(this.enableFormat){
\r
811 btns.bold.toggle(doc.queryCommandState('bold'));
\r
812 btns.italic.toggle(doc.queryCommandState('italic'));
\r
813 btns.underline.toggle(doc.queryCommandState('underline'));
\r
815 if(this.enableAlignments){
\r
816 btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
\r
817 btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
\r
818 btns.justifyright.toggle(doc.queryCommandState('justifyright'));
\r
820 if(!Ext.isSafari2 && this.enableLists){
\r
821 btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
\r
822 btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
\r
825 Ext.menu.MenuMgr.hideAll();
\r
831 relayBtnCmd : function(btn){
\r
832 this.relayCmd(btn.getItemId());
\r
835 <div id="method-Ext.form.HtmlEditor-relayCmd"></div>/**
\r
836 * Executes a Midas editor command on the editor document and performs necessary focus and
\r
837 * toolbar updates. <b>This should only be called after the editor is initialized.</b>
\r
838 * @param {String} cmd The Midas command
\r
839 * @param {String/Boolean} value (optional) The value to pass to the command (defaults to null)
\r
841 relayCmd : function(cmd, value){
\r
844 this.execCmd(cmd, value);
\r
845 this.updateToolbar();
\r
846 }).defer(10, this);
\r
849 <div id="method-Ext.form.HtmlEditor-execCmd"></div>/**
\r
850 * Executes a Midas editor command directly on the editor document.
\r
851 * For visual commands, you should use {@link #relayCmd} instead.
\r
852 * <b>This should only be called after the editor is initialized.</b>
\r
853 * @param {String} cmd The Midas command
\r
854 * @param {String/Boolean} value (optional) The value to pass to the command (defaults to null)
\r
856 execCmd : function(cmd, value){
\r
857 this.doc.execCommand(cmd, false, value === undefined ? null : value);
\r
862 applyCommand : function(e){
\r
864 var c = e.getCharCode(), cmd;
\r
866 c = String.fromCharCode(c);
\r
882 e.preventDefault();
\r
888 <div id="method-Ext.form.HtmlEditor-insertAtCursor"></div>/**
\r
889 * Inserts the passed text at the current cursor position. Note: the editor must be initialized and activated
\r
891 * @param {String} text
\r
893 insertAtCursor : function(text){
\r
894 if(!this.activated){
\r
899 var r = this.doc.selection.createRange();
\r
908 this.execCmd('InsertHTML', text);
\r
914 fixKeys : function(){ // load time branching for fastest keydown performance
\r
916 return function(e){
\r
917 var k = e.getKey(), r;
\r
920 r = this.doc.selection.createRange();
\r
923 r.pasteHTML(' ');
\r
926 }else if(k == e.ENTER){
\r
927 r = this.doc.selection.createRange();
\r
929 var target = r.parentElement();
\r
930 if(!target || target.tagName.toLowerCase() != 'li'){
\r
932 r.pasteHTML('<br />');
\r
939 }else if(Ext.isOpera){
\r
940 return function(e){
\r
941 var k = e.getKey();
\r
945 this.execCmd('InsertHTML',' ');
\r
949 }else if(Ext.isWebKit){
\r
950 return function(e){
\r
951 var k = e.getKey();
\r
954 this.execCmd('InsertText','\t');
\r
956 }else if(k == e.ENTER){
\r
958 this.execCmd('InsertHtml','<br /><br />');
\r
965 <div id="method-Ext.form.HtmlEditor-getToolbar"></div>/**
\r
966 * Returns the editor's toolbar. <b>This is only available after the editor has been rendered.</b>
\r
967 * @return {Ext.Toolbar}
\r
969 getToolbar : function(){
\r
973 <div id="prop-Ext.form.HtmlEditor-buttonTips"></div>/**
\r
974 * Object collection of toolbar tooltips for the buttons in the editor. The key
\r
975 * is the command id associated with that button and the value is a valid QuickTips object.
\r
980 title: 'Bold (Ctrl+B)',
\r
981 text: 'Make the selected text bold.',
\r
982 cls: 'x-html-editor-tip'
\r
985 title: 'Italic (Ctrl+I)',
\r
986 text: 'Make the selected text italic.',
\r
987 cls: 'x-html-editor-tip'
\r
995 title: 'Bold (Ctrl+B)',
\r
996 text: 'Make the selected text bold.',
\r
997 cls: 'x-html-editor-tip'
\r
1000 title: 'Italic (Ctrl+I)',
\r
1001 text: 'Make the selected text italic.',
\r
1002 cls: 'x-html-editor-tip'
\r
1005 title: 'Underline (Ctrl+U)',
\r
1006 text: 'Underline the selected text.',
\r
1007 cls: 'x-html-editor-tip'
\r
1009 increasefontsize : {
\r
1010 title: 'Grow Text',
\r
1011 text: 'Increase the font size.',
\r
1012 cls: 'x-html-editor-tip'
\r
1014 decreasefontsize : {
\r
1015 title: 'Shrink Text',
\r
1016 text: 'Decrease the font size.',
\r
1017 cls: 'x-html-editor-tip'
\r
1020 title: 'Text Highlight Color',
\r
1021 text: 'Change the background color of the selected text.',
\r
1022 cls: 'x-html-editor-tip'
\r
1025 title: 'Font Color',
\r
1026 text: 'Change the color of the selected text.',
\r
1027 cls: 'x-html-editor-tip'
\r
1030 title: 'Align Text Left',
\r
1031 text: 'Align text to the left.',
\r
1032 cls: 'x-html-editor-tip'
\r
1035 title: 'Center Text',
\r
1036 text: 'Center text in the editor.',
\r
1037 cls: 'x-html-editor-tip'
\r
1040 title: 'Align Text Right',
\r
1041 text: 'Align text to the right.',
\r
1042 cls: 'x-html-editor-tip'
\r
1044 insertunorderedlist : {
\r
1045 title: 'Bullet List',
\r
1046 text: 'Start a bulleted list.',
\r
1047 cls: 'x-html-editor-tip'
\r
1049 insertorderedlist : {
\r
1050 title: 'Numbered List',
\r
1051 text: 'Start a numbered list.',
\r
1052 cls: 'x-html-editor-tip'
\r
1055 title: 'Hyperlink',
\r
1056 text: 'Make the selected text a hyperlink.',
\r
1057 cls: 'x-html-editor-tip'
\r
1060 title: 'Source Edit',
\r
1061 text: 'Switch to source editing mode.',
\r
1062 cls: 'x-html-editor-tip'
\r
1066 // hide stuff that is not compatible
\r
1067 <div id="event-Ext.form.HtmlEditor-blur"></div>/**
\r
1071 <div id="event-Ext.form.HtmlEditor-change"></div>/**
\r
1075 <div id="event-Ext.form.HtmlEditor-focus"></div>/**
\r
1079 <div id="event-Ext.form.HtmlEditor-specialkey"></div>/**
\r
1080 * @event specialkey
\r
1083 <div id="cfg-Ext.form.HtmlEditor-fieldClass"></div>/**
\r
1084 * @cfg {String} fieldClass @hide
\r
1086 <div id="cfg-Ext.form.HtmlEditor-focusClass"></div>/**
\r
1087 * @cfg {String} focusClass @hide
\r
1089 <div id="cfg-Ext.form.HtmlEditor-autoCreate"></div>/**
\r
1090 * @cfg {String} autoCreate @hide
\r
1092 <div id="cfg-Ext.form.HtmlEditor-inputType"></div>/**
\r
1093 * @cfg {String} inputType @hide
\r
1095 <div id="cfg-Ext.form.HtmlEditor-invalidClass"></div>/**
\r
1096 * @cfg {String} invalidClass @hide
\r
1098 <div id="cfg-Ext.form.HtmlEditor-invalidText"></div>/**
\r
1099 * @cfg {String} invalidText @hide
\r
1101 <div id="cfg-Ext.form.HtmlEditor-msgFx"></div>/**
\r
1102 * @cfg {String} msgFx @hide
\r
1104 <div id="cfg-Ext.form.HtmlEditor-validateOnBlur"></div>/**
\r
1105 * @cfg {String} validateOnBlur @hide
\r
1107 <div id="cfg-Ext.form.HtmlEditor-allowDomMove"></div>/**
\r
1108 * @cfg {Boolean} allowDomMove @hide
\r
1110 <div id="cfg-Ext.form.HtmlEditor-applyTo"></div>/**
\r
1111 * @cfg {String} applyTo @hide
\r
1113 <div id="cfg-Ext.form.HtmlEditor-autoHeight"></div>/**
\r
1114 * @cfg {String} autoHeight @hide
\r
1116 <div id="cfg-Ext.form.HtmlEditor-autoWidth"></div>/**
\r
1117 * @cfg {String} autoWidth @hide
\r
1119 <div id="cfg-Ext.form.HtmlEditor-cls"></div>/**
\r
1120 * @cfg {String} cls @hide
\r
1122 <div id="cfg-Ext.form.HtmlEditor-disabled"></div>/**
\r
1123 * @cfg {String} disabled @hide
\r
1125 <div id="cfg-Ext.form.HtmlEditor-disabledClass"></div>/**
\r
1126 * @cfg {String} disabledClass @hide
\r
1128 <div id="cfg-Ext.form.HtmlEditor-msgTarget"></div>/**
\r
1129 * @cfg {String} msgTarget @hide
\r
1131 <div id="cfg-Ext.form.HtmlEditor-readOnly"></div>/**
\r
1132 * @cfg {String} readOnly @hide
\r
1134 <div id="cfg-Ext.form.HtmlEditor-style"></div>/**
\r
1135 * @cfg {String} style @hide
\r
1137 <div id="cfg-Ext.form.HtmlEditor-validationDelay"></div>/**
\r
1138 * @cfg {String} validationDelay @hide
\r
1140 <div id="cfg-Ext.form.HtmlEditor-validationEvent"></div>/**
\r
1141 * @cfg {String} validationEvent @hide
\r
1143 <div id="cfg-Ext.form.HtmlEditor-tabIndex"></div>/**
\r
1144 * @cfg {String} tabIndex @hide
\r
1146 <div id="prop-Ext.form.HtmlEditor-disabled"></div>/**
\r
1147 * @property disabled
\r
1150 <div id="method-Ext.form.HtmlEditor-applyToMarkup"></div>/**
\r
1151 * @method applyToMarkup
\r
1154 <div id="method-Ext.form.HtmlEditor-disable"></div>/**
\r
1158 <div id="method-Ext.form.HtmlEditor-enable"></div>/**
\r
1162 <div id="method-Ext.form.HtmlEditor-validate"></div>/**
\r
1163 * @method validate
\r
1166 <div id="event-Ext.form.HtmlEditor-valid"></div>/**
\r
1170 <div id="method-Ext.form.HtmlEditor-setDisabled"></div>/**
\r
1171 * @method setDisabled
\r
1174 <div id="cfg-Ext.form.HtmlEditor-null"></div>/**
\r
1179 Ext.reg('htmleditor', Ext.form.HtmlEditor);</pre>