/** * @author Shea Frederick - http://www.vinylfox.com * @contributor Ronald van Raaphorst - Twensoc * @class Ext.ux.form.HtmlEditor.FindReplace * @extends Ext.util.Observable *

A plugin that provides search and replace functionality in source edit mode. Incomplete.

*/ Ext.ux.form.HtmlEditor.FindAndReplace = Ext.extend(Ext.util.Observable, { // Find and Replace language text langTitle: 'Find/Replace', langFind: 'Find', langReplace: 'Replace', langReplaceWith: 'Replace with', langClose: 'Close', // private cmd: 'findandreplace', // private init: function(cmp){ this.cmp = cmp; this.cmp.on({ 'render': this.onRender, 'editmodechange': this.editModeChange, scope: this }); this.lastSelectionStart=-1; }, editModeChange: function(t, m){ if (this.btn && m){ this.btn.setDisabled(false); } }, // private onRender: function(){ this.btn = this.cmp.getToolbar().addButton({ iconCls: 'x-edit-findandreplace', sourceEditEnabled:true, handler: function(){ if (!this.farWindow){ this.farWindow = new Ext.Window({ title: this.langTitle, closeAction: 'hide', width: 270, items: [{ itemId: 'findandreplace', xtype: 'form', border: false, plain: true, bodyStyle: 'padding: 10px;', labelWidth: 80, labelAlign: 'right', items: [{ xtype: 'textfield', allowBlank: false, fieldLabel: this.langFind, name: 'find', width: 145 }, { xtype: 'textfield', allowBlank: true, fieldLabel: this.langReplaceWith, name: 'replace', width: 145 }] }], buttons: [{ text: this.langFind, handler: this.doFind, scope: this }, { text: this.langReplace, handler: this.doReplace, scope: this }, { text: this.langClose, handler: function(){ this.farWindow.hide(); }, scope: this }] }); }else{ this.farWindow.getEl().frame(); } this.farWindow.show(); }, scope: this, tooltip: { title: this.langTitle }, overflowText: this.langTitle }); }, doFind: function(){ var frm = this.farWindow.getComponent('findandreplace').getForm(); if (!frm.isValid()) { return ''; } var findValue = frm.findField('find').getValue(); var replaceValue = frm.findField('replace').getValue(); if(this.cmp.sourceEditMode) { // source edit mode var textarea = this.cmp.el.dom; var startPos = textarea.selectionStart===this.lastSelectionStart ? textarea.selectionStart+1 : textarea.selectionStart; var txt = textarea.value.substring(startPos); var regexp = new RegExp(findValue); var r = txt.search(regexp); if(r==-1) { return; } this.lastSelectionStart = startPos + r; if(Ext.isGecko) { textarea.setSelectionRange(this.lastSelectionStart , this.lastSelectionStart + findValue.length); this.cmp.scrollIntoView(startPos); this.cmp.focus(false, true); } return; } // design mode //var doc = this.cmp.getEditorBody(); //var txt = doc.innerHTML; // Should we search/replace in the source, and push the result back to the design? }, doReplace: function(){ var frm = this.farWindow.getComponent('findandreplace').getForm(); if (!frm.isValid()) { return ''; } var findValue = frm.findField('find').getValue(); var replaceValue = frm.findField('replace').getValue(); if(this.cmp.sourceEditMode) { var textarea = this.cmp.el.dom; var startPos = textarea.selectionStart; var endPos = textarea.selectionEnd; var txt = textarea.value; //cmp.execCmd('delete', null); //cmp.focus(false, false); //cmp.insertAtCursor(replaceValue); if(Ext.isGecko) { // TODO: Scroll into view var scrollPosition = textarea.scrollTop; textarea.value = txt.substring(0,startPos) + replaceValue + txt.substring(endPos); textarea.setSelectionRange(startPos,startPos + replaceValue.length); textarea.scrollTop = scrollPosition; this.cmp.focus(false, true); } return; } return; } });