Index: dialog.html
===================================================================
--- dialog.html	(revision 0)
+++ dialog.html	(revision 0)
@@ -0,0 +1,58 @@
+<h1 id="[h1]"><l10n>Find and Replace</l10n></h1>
+<!--
+/*---------------------------------------*\
+ Find and Replace Plugin for HTMLArea-3.0
+ -----------------------------------------
+ author: Cau guanabara 
+ e-mail: caugb@ibest.com.br
+\*---------------------------------------*/
+-->
+
+<form action="" method="get" id="[inputs]">
+  <table border="0" style="width: 100%; padding: 2px;"><!---->
+    <tbody>
+      <tr> 
+        <td width="29%" style="text-align: right; vertical-align: bottom;"><l10n>Search for:</l10n></td>
+        <td width="71%" colspan="2" style="vertical-align: bottom;"> 
+          <input id="fr_pattern" type="text" style="width: 200px" onFocus="this.select();"> 
+        </td>
+      </tr>
+      <tr> 
+        <td style="text-align: right;"><l10n>Replace with:</l10n></td>
+        <td colspan="2"> 
+          <input id="fr_replacement" type="text" style="width: 200px" onFocus="this.select();"> 
+        </td>
+      </tr>
+      <tr> 
+        <td colspan="3"><table width="100%" border="0" cellpadding="1" cellspacing="0">
+            <tr> 
+              <td width="78%" style="padding: 2px">
+		<FIELDSET style="width:90%; padding: 5px">
+                  <LEGEND><span><l10n>Options</l10n></span></LEGEND>
+                  <input id="fr_words" type="checkbox" checked>
+                  <span id="fr_words_span" style="cursor:default"> 
+                    <span><l10n>Whole words only</l10n></span></span><br />
+                  <input id="fr_matchcase" type="checkbox">
+                  <span id="fr_matchcase_span" style="cursor:default"> 
+                    <span><l10n>Case sensitive search</l10n></span></span><br />
+                  <input id="fr_replaceall" type="checkbox" />
+                  <span id="fr_replaceall_span" style="cursor:default"> 
+                    <span><l10n>Substitute all occurrences</l10n></span></span>
+              </FIELDSET></td>
+	      <td width="22%" style="vertical-align: bottom; text-align: right; padding: 4px"> 
+		<input type="button" id="fr_clear" value="_(Clear)" style="margin:3px;" />
+		<div class="space"></div>
+		<input type="button" id="fr_hiliteall"value="_(Highlight)" style="margin:3px;" />
+		<div class="space"></div>
+		<input type="button" id="fr_undo" value="_(Undo)" style="margin:3px;" />
+	      </td>
+            </tr>
+        </table></td>
+      </tr>
+    </tbody>
+  </table>
+  <div class="buttons" id="[buttons]"> 
+    <input  type="button" id="fr_go" name="[next]" value="_(Next)" />
+    <input  type="button" id="[done]" value="_(Done)" />
+  </div>
+</form>
Index: find-replace.js
===================================================================
--- find-replace.js	(revision 1015)
+++ find-replace.js	(working copy)
@@ -6,24 +6,50 @@
 \*---------------------------------------*/
 
 function FindReplace(editor) {
-this.editor = editor;
-var cfg = editor.config;
-var self = this;
-cfg.registerButton("FR-findreplace", this._lc("Find and Replace"),
-                   editor.imgURL("ed_find.gif", "FindReplace"), false,
-                   function(editor) { self.buttonPress(editor); });
-cfg.addToolbarElement(["FR-findreplace","separator"], ["formatblock","fontsize","fontname"], -1);
+  this.editor = editor;
+  var cfg = editor.config;
+  var self = this;
+
+  this.tosearch = '';
+  this.pater = null;
+  this.matches = 0;
+  this.replaces = 0;
+  this.fr_spans = new Array();
+
+  cfg.registerButton("FR-findreplace", this._lc("Find and Replace"),
+                     editor.imgURL("ed_find.gif", "FindReplace"), false,
+                     function(editor) { self.buttonPress();});
+  cfg.addToolbarElement(["FR-findreplace","separator"], ["formatblock","fontsize","fontname"], -1);
 }
 
+FindReplace.prototype.onGenerateOnce = function(editor) {
+  var self = FindReplace;
+
+  this.accepted = {
+    'fr_pattern'       : true,
+    'fr_replacement'   : true,
+    'fr_words'         : true,
+    'fr_matchcase'     : true,
+    'fr_replaceall'    : true
+  };
+
+  Xinha._getback(Xinha.getPluginDir("FindReplace") + '/fr_engine.js', function(getback) { eval(getback); self.methodsReady = true; });
+  Xinha._getback(Xinha.getPluginDir("FindReplace") + "/dialog.html", function(getback) { self.html = getback; });
+}
+
 FindReplace.prototype.buttonPress = function(editor) { 
-FindReplace.editor = editor;
-var sel = editor.getSelectedHTML();
+  if (!this.dialog) this.prepareDialog();
+  var editor = this.editor;
+  var sel = editor.getSelectedHTML();
   if(/\w/.test(sel)) {
-  sel = sel.replace(/<[^>]*>/g,"");
-  sel = sel.replace(/&nbsp;/g,"");
+    sel = sel.replace(/<[^>]*>/g,"");
+    sel = sel.replace(/&nbsp;/g,"");
   }
-var param = /\w/.test(sel) ? {fr_pattern: sel} : null;
-editor._popupDialog("plugin://FindReplace/find_replace", null, param);
+  this.params = /\w/.test(sel) ? {fr_pattern: sel} : null;
+  this.buffer = null;
+  
+  this.dialog.show();  
+  this.disab("fr_undo,fr_clear,fr_hiliteall",true);
 };
 
 FindReplace._pluginInfo = {
@@ -37,6 +63,85 @@
   license       : "htmlArea"
 };
 
+FindReplace.prototype.prepareDialog = function(editor) {
+  var editor = this.editor
+  var self = this;
+
+  this.dialog = new Xinha.Dialog(editor, FindReplace.html, 'FindReplace');
+  
+  this.dialog.getElementById('fr_words').onclick = function() {self.clearDoc();}
+  this.dialog.getElementById('fr_words_span').onclick = function() {
+    e = self.dialog.getElementById('fr_words');
+    e.click();
+    e.focus();
+  }
+  this.dialog.getElementById('fr_matchcase').onclick = function() {self.clearDoc();}
+  this.dialog.getElementById('fr_matchcase_span').onclick = function() {
+    e = self.dialog.getElementById('fr_matchcase');
+    e.click();
+    e.focus();
+  }
+  this.dialog.getElementById('fr_replaceall').onclick = function() {
+    if(self.dialog.getElementById('fr_replacement').value == '') {
+      alert(self._lc('You must enter a replacement word'));
+      return false;
+    }
+    self.clearDoc();
+  }
+  this.dialog.getElementById('fr_replaceall_span').onclick = function() {
+    e = self.dialog.getElementById('fr_replaceall'); 
+    e.click(); 
+    e.focus();
+  }
+  this.dialog.getElementById('fr_clear').onclick = function() {self.clearMarks();}
+  this.dialog.getElementById('fr_hiliteall').onclick = function() {self.hiliteAll();}
+  this.dialog.getElementById('fr_undo').onclick = function() {self.resetContents();}
+  this.dialog.getElementById('done').onclick = function() {self.clearDoc(); self.dialog.hide();}
+  this.dialog.getElementById('fr_go').onclick = function() {self.findNext();}
+  this.dialog.getElementById('inputs').onkeypress = function(ev) {
+    ev || (ev = window.event);
+    switch(ev.keyCode) {
+    case 13: // enter
+      self.dialog.getElementById('fr_go').click();
+      self.dialog.getElementById('fr_pattern').focus();
+      break;
+    case 27: // ESC
+      self.dialog.getElementById('done').click();
+      return false;
+    }
+    return true;
+  }
+
+  if (this.params) {
+    this.dialog.getElementById('fr_pattern').value = this.params["fr_pattern"];
+    this.dialog.getElementById('fr_replacement').focus();
+  } else {
+    self.dialog.getElementById('fr_pattern').focus();
+  }
+}
+
+FindReplace.prototype.findNext = function(editor) {
+  var dialog = this.dialog;
+  var required = {'fr_pattern' : this._lc("Enter the text you want to find")};
+  for (var i in required) {
+    var el = dialog.getElementById(i);
+      if (!el.value) {
+        alert(required[i]);
+        el.focus();
+        return false;
+      }
+  }
+
+  var param = {};
+  for (var i in this.accepted) {
+    var el = dialog.getElementById(i);
+    param[i] = el.type == 'checkbox' ? el.checked : el.value;
+  }
+  this.execSearch(param);  
+
+  return false;
+}
+
 FindReplace.prototype._lc = function(string) {
     return Xinha._lc(string, 'FindReplace');
 };
\ No newline at end of file
Index: popups/find_replace.html
===================================================================
--- popups/find_replace.html	(revision 1015)
+++ popups/find_replace.html	(working copy)
@@ -1,162 +0,0 @@
-<html>
-<head>
-  <title>Find and Replace</title>
-<!--
-/*---------------------------------------*\
- Find and Replace Plugin for HTMLArea-3.0
- -----------------------------------------
- author: Cau guanabara 
- e-mail: caugb@ibest.com.br
-\*---------------------------------------*/
--->
-<script type="text/javascript" src="../fr_engine.js"></script>
-<script type="text/javascript" src="../../../popups/popup.js"></script>
-<link rel="stylesheet" type="text/css" href="../../../popups/popup.css" />
-
-<script type="text/javascript">
-
-window.resizeTo(335, 250);
-
-var accepted = {
-                'fr_pattern'       : true,
-                'fr_replacement'   : true,
-                'fr_words'         : true,
-                'fr_matchcase'     : true,
-                'fr_replaceall'    : true
-               };
-
-function Init() {
-__dlg_translate('FindReplace');
-__dlg_init();
-
-disab("fr_undo,fr_clear,fr_hiliteall",true);
-
-var params = window.dialogArguments;
-  if(params) {
-  document.getElementById('fr_pattern').value = params["fr_pattern"];
-  document.getElementById('fr_replacement').focus();
-  } else {
-  document.getElementById('fr_pattern').focus();
-  }
-  
-document.body.onkeypress = __dlg_key_press;
-}
-
-function onCancel() {
-  clearDoc();
-  __dlg_close(null);
-  return false;
-}
-
-function onOK() {
-  var required = {'fr_pattern' : _lc("Enter the text you want to find")};
-  for (var i in required) {
-    var el = document.getElementById(i);
-      if (!el.value) {
-        alert(required[i]);
-        el.focus();
-        return false;
-      }
-  }
-
-  var param = {};
-  for (var i in accepted) {
-  var el = document.getElementById(i);
-  param[i] = el.type == 'checkbox' ? el.checked : el.value;
-  }
-  execSearch(param);
-  return false;
-}
-
-function __dlg_key_press(ev) {
-ev || (ev = window.event);
-  switch(ev.keyCode) {
-    case 13:
-    document.getElementById('fr_go').click();
-    document.getElementById('fr_pattern').focus();
-      break;
-    case 27:
-    clearDoc();
-    window.close();
-    return false;
-  }
-return true;
-}
-
-</script>
-
-<style type="text/css">
-table .label { text-align: right; width: 12em; }
-.title {
-background: #ddf;
-color: #000;
-font-weight: bold;
-font-size: 120%;
-padding: 3px 10px;
-margin-bottom: 10px;
-border-bottom: 1px solid black;
-letter-spacing: 2px;
-}
-.buttons { border-top: 1px solid #999; padding: 2px; text-align: right; }
-.hrstyle { border-width: 1px; border-color: #666; width: 95%; padding: 2px; }
-</style>
-  </head>
-  <body class="dialog" onload="Init()">
-  <div class="title">Find and Replace</div>
-  <form action="" method="get">
-  <table border="0" style="width: 100%; padding: 2px;"><!---->
-    <tbody>
-      <tr> 
-        <td width="29%" style="text-align: right; vertical-align: bottom;">Search for:</td>
-        <td width="71%" colspan="2" style="vertical-align: bottom;"> 
-        <input id="fr_pattern" type="text" style="width: 200px" onFocus="this.select();"> 
-        </td>
-      </tr>
-      <tr> 
-        <td style="text-align: right;">Replace with:</td>
-        <td colspan="2"> 
-        <input id="fr_replacement" type="text" style="width: 200px" onFocus="this.select();"> 
-        </td>
-      </tr>
-      <tr> 
-        <td colspan="3"><table width="100%" border="0" cellpadding="1" cellspacing="0">
-            <tr> 
-              <td width="78%" style="padding: 2px">
-              <FIELDSET style="width:90%; padding: 5px">
-                <LEGEND><span>Options</span></LEGEND>
-                  <input id="fr_words" type="checkbox" checked onClick="clearDoc();">
-                <span onClick="e = document.getElementById('fr_words'); 
-                e.click(); e.focus();" style="cursor:default"> 
-                  <span>Whole words only</span></span><br />
-                  <input id="fr_matchcase" type="checkbox" onClick="clearDoc();">
-                <span onClick="e = document.getElementById('fr_matchcase'); 
-                e.click(); e.focus();" style="cursor:default"> 
-                  <span>Case sensitive search</span></span><br />
-                  <input id="fr_replaceall" type="checkbox" onClick="
-                  if(document.getElementById('fr_replacement').value == '') {
-                  alert(_lc('Inform a replacement word'));
-                  return false;
-                  }
-                  clearDoc();">
-                <span onClick="e = document.getElementById('fr_replaceall'); 
-                e.click(); e.focus();" style="cursor:default"> 
-                  <span>Substitute all occurrences</span></span>
-                </FIELDSET></td>
-<td width="22%" style="vertical-align: bottom; text-align: right; padding: 4px"> 
-<button type="button" id="fr_clear" onClick="clearMarks()">Clear</button>
-<div class="space"></div>
-<button type="button" id="fr_hiliteall" onClick="hiliteAll()">Highlight</button>
-<div class="space"></div>
-<button type="button" id="fr_undo" onClick="resetContents();">Undo</button>
-</td>
-            </tr>
-          </table></td>
-      </tr>
-    </tbody>
-  </table>
-<div style="border-top: 1px solid #999; padding: 2px; padding: 5px; text-align: right; height: 20px"><button type="button" id="fr_go" onclick="return onOK();">Next</button>
-<button type="button" name="cancel" onclick="return onCancel();">Done</button>
-</div>
-</form>
-</body>
-</html>
\ No newline at end of file
Index: fr_engine.js
===================================================================
--- fr_engine.js	(revision 1015)
+++ fr_engine.js	(working copy)
@@ -5,145 +5,138 @@
  e-mail: caugb@ibest.com.br
 \*---------------------------------------*/
 
-var FindReplace = window.opener.FindReplace;
-var editor = FindReplace.editor;
-var is_mo = window.opener.Xinha.is_gecko;
-var tosearch = '';
-var pater = null;
-var buffer = null;
-var matches = 0;
-var replaces = 0;
-var fr_spans = new Array();
-function _lc(string) {
-    return(window.opener.Xinha._lc(string, 'FindReplace'));
-}
-function execSearch(params) {
-var ihtml = editor._doc.body.innerHTML;
-  if(buffer == null) 
-    buffer = ihtml;
+FindReplace.prototype.execSearch = function(params) {
+  var editor = this.editor;
+  var ihtml = editor._doc.body.innerHTML;
+  if(this.buffer == null) 
+    this.buffer = ihtml;
     
-  if(params['fr_pattern'] != tosearch) {
-    if(tosearch != '')
-      clearDoc();
-  tosearch = params['fr_pattern'];
+  if(params['fr_pattern'] != this.tosearch) {
+    if(this.tosearch != '')
+      this.clearDoc();
+    this.tosearch = params['fr_pattern'];
   }
   
-  if(matches == 0) {
-  er = params['fr_words'] ? "/(?!<[^>]*)(\\b"+params['fr_pattern']+"\\b)(?![^<]*>)/g" :
-                            "/(?!<[^>]*)("+params['fr_pattern']+")(?![^<]*>)/g";
+  if (this.matches == 0) {
+    er = params['fr_words'] ? "/(?!<[^>]*)(\\b"+params['fr_pattern']+"\\b)(?![^<]*>)/g" :
+      "/(?!<[^>]*)("+params['fr_pattern']+")(?![^<]*>)/g";
     if(!params['fr_matchcase'])
       er += "i"; 
-
-  pater = eval(er);
-  
-  var tago = '<span id=frmark>';
-  var tagc = '</span>';
-  var newHtml = ihtml.replace(pater,tago+"$1"+tagc);
-  
-  editor.setHTML(newHtml);
-  
-  var getallspans = editor._doc.body.getElementsByTagName("span"); 
+    
+    this.pater = eval(er);
+    
+    var tago = '<span id=frmark>';
+    var tagc = '</span>';
+    var newHtml = ihtml.replace(this.pater,tago+"$1"+tagc);
+    
+    editor.setHTML(newHtml);
+    
+    var getallspans = editor._doc.body.getElementsByTagName("span"); 
     for (var i = 0; i < getallspans.length; i++) 
       if(/^frmark/.test(getallspans[i].id))
-        fr_spans.push(getallspans[i]);
+        this.fr_spans.push(getallspans[i]);
   }
 
-spanWalker(params['fr_pattern'],params['fr_replacement'],params['fr_replaceall']);
+  this.spanWalker(params['fr_pattern'],params['fr_replacement'],params['fr_replaceall']);
 }
 
-function spanWalker(pattern,replacement,replaceall) {
-var foundtrue = false;
-clearMarks();
+FindReplace.prototype.spanWalker = function(pattern, replacement, replaceall) {
+  var foundtrue = false;
+  this.clearMarks();
 
-  for (var i = matches; i < fr_spans.length; i++) {
-  var elm = fr_spans[i];
-  foundtrue = true;
+  for (var i = this.matches; i < this.fr_spans.length; i++) {
+    var elm = this.fr_spans[i];
+    foundtrue = true;
     if(!(/[0-9]$/.test(elm.id))) { 
-    matches++;
-    disab('fr_clear',false);
-    elm.id = 'frmark_'+matches;
-    elm.style.color = 'white';
-    elm.style.backgroundColor = 'highlight';
-    elm.style.fontWeight = 'bold';
-    elm.scrollIntoView(false);
+      this.matches++;
+      this.disab('fr_clear',false);
+      elm.id = 'frmark_'+this.matches;
+      elm.style.color = 'white';
+      elm.style.backgroundColor = 'highlight';
+      elm.style.fontWeight = 'bold';
+      elm.scrollIntoView(false);
       if(/\w/.test(replacement)) {
-        if(replaceall || confirm(_lc("Substitute this occurrence?"))) {
-        elm.firstChild.replaceData(0,elm.firstChild.data.length,replacement);
-        replaces++;
-        disab('fr_undo',false);
+        if(replaceall || confirm(this._lc("Substitute this occurrence?"))) {
+          elm.firstChild.replaceData(0,elm.firstChild.data.length,replacement);
+          this.replaces++;
+          this.disab('fr_undo',false);
         }
         if(replaceall) {
-        clearMarks();
-        continue;
+          this.clearMarks();
+          continue;
         }
       }
-    break;
+      break;
     }
   }
-  var last = (i >= fr_spans.length - 1);
+  var last = (i >= this.fr_spans.length - 1);
   if(last || !foundtrue) { // EOF
-  var message = _lc("Done")+':\n\n';
-    if(matches > 0) {
-      if(matches == 1) message += matches+' '+_lc("found item");
-      else             message += matches+' '+_lc("found items");
-      if(replaces > 0) {
-        if(replaces == 1) message += ',\n'+replaces+' '+_lc("replaced item");
-        else              message += ',\n'+replaces+' '+_lc("replaced items");
+    var message = this._lc("Done")+':\n\n';
+    if(this.matches > 0) {
+      if(this.matches == 1) message += this.matches+' '+this._lc("found item");
+      else             message += this.matches+' '+this._lc("found items");
+      if(this.replaces > 0) {
+        if(this.replaces == 1) message += ',\n'+this.replaces+' '+this._lc("replaced item");
+        else              message += ',\n'+this.replaces+' '+this._lc("replaced items");
       }
-    hiliteAll();
-    disab('fr_hiliteall',false);
-    } else { message += '"'+pattern+'" '+_lc("not found"); }
-  alert(message+'.');
+      this.hiliteAll();
+      this.disab('fr_hiliteall',false);
+    } else { message += '"'+pattern+'" '+this._lc("not found"); }
+    alert(message+'.');
   }
 }
 
-function clearDoc() {
-var doc = editor._doc.body.innerHTML; 
-var er = /(<span\s+[^>]*id=.?frmark[^>]*>)([^<>]*)(<\/span>)/gi;
-editor._doc.body.innerHTML = doc.replace(er,"$2");
-pater = null;
-tosearch = '';
-fr_spans = new Array();
-matches = 0;
-replaces = 0;
-disab("fr_hiliteall,fr_clear",true);
+FindReplace.prototype.clearDoc = function() {
+  var editor = this.editor;
+  var doc = editor._doc.body.innerHTML; 
+  var er = /(<span\s+[^>]*id=.?frmark[^>]*>)([^<>]*)(<\/span>)/gi;
+  editor._doc.body.innerHTML = doc.replace(er,"$2");
+  this.pater = null;
+  this.tosearch = '';
+  this.fr_spans = new Array();
+  this.matches = 0;
+  this.replaces = 0;
+  this.disab("fr_hiliteall,fr_clear",true);
 }
 
-function clearMarks() {
-var getall = editor._doc.body.getElementsByTagName("span"); 
+FindReplace.prototype.clearMarks = function() {
+  var editor = this.editor;
+  var getall = editor._doc.body.getElementsByTagName("span"); 
   for (var i = 0; i < getall.length; i++) {
-  var elm = getall[i];
+    var elm = getall[i];
     if(/^frmark/.test(elm.id)) {
-    var objStyle = editor._doc.getElementById(elm.id).style;
-    objStyle.backgroundColor = "";
-    objStyle.color = "";
-    objStyle.fontWeight = "";
+      var objStyle = editor._doc.getElementById(elm.id).style;
+      objStyle.backgroundColor = "";
+      objStyle.color = "";
+      objStyle.fontWeight = "";
     }
   }
 }
 
-function hiliteAll() { 
-var getall = editor._doc.body.getElementsByTagName("span"); 
+FindReplace.prototype.hiliteAll = function() { 
+  var editor = this.editor;
+  var getall = editor._doc.body.getElementsByTagName("span"); 
   for (var i = 0; i < getall.length; i++) {
-  var elm = getall[i];
+    var elm = getall[i];
     if(/^frmark/.test(elm.id)) { 
-    var objStyle = editor._doc.getElementById(elm.id).style;
-    objStyle.backgroundColor = "highlight";
-    objStyle.color = "white";
-    objStyle.fontWeight = "bold";
+      var objStyle = editor._doc.getElementById(elm.id).style;
+      objStyle.backgroundColor = "highlight";
+      objStyle.color = "white";
+      objStyle.fontWeight = "bold";
     }
   }
 }
 
-function resetContents() { 
-  if(buffer == null) return;
-var transp = editor._doc.body.innerHTML;
-editor._doc.body.innerHTML = buffer;
-buffer = transp;
+FindReplace.prototype.resetContents = function() { 
+  var editor = this.editor;
+  if(this.buffer == null) return;
+  var transp = editor._doc.body.innerHTML;
+  editor._doc.body.innerHTML = this.buffer;
+  this.buffer = transp;
 }
 
-function disab(elms,toset) { 
-var names = elms.split(/[,; ]+/);
+FindReplace.prototype.disab = function(elms,toset) { 
+  var names = elms.split(/[,; ]+/);
   for(var i = 0; i < names.length; i++) 
     document.getElementById(names[i]).disabled = toset;
 }
\ No newline at end of file

