Ticket #1176: FindReplacePlugin.patch
| File FindReplacePlugin.patch, 21.8 kB (added by guest, 3 months ago) |
|---|
-
dialog.html
1 <h1 id="[h1]"><l10n>Find and Replace</l10n></h1> 2 <!-- 3 /*---------------------------------------*\ 4 Find and Replace Plugin for HTMLArea-3.0 5 ----------------------------------------- 6 author: Cau guanabara 7 e-mail: caugb@ibest.com.br 8 \*---------------------------------------*/ 9 --> 10 11 <form action="" method="get" id="[inputs]"> 12 <table border="0" style="width: 100%; padding: 2px;"><!----> 13 <tbody> 14 <tr> 15 <td width="29%" style="text-align: right; vertical-align: bottom;"><l10n>Search for:</l10n></td> 16 <td width="71%" colspan="2" style="vertical-align: bottom;"> 17 <input id="fr_pattern" type="text" style="width: 200px" onFocus="this.select();"> 18 </td> 19 </tr> 20 <tr> 21 <td style="text-align: right;"><l10n>Replace with:</l10n></td> 22 <td colspan="2"> 23 <input id="fr_replacement" type="text" style="width: 200px" onFocus="this.select();"> 24 </td> 25 </tr> 26 <tr> 27 <td colspan="3"><table width="100%" border="0" cellpadding="1" cellspacing="0"> 28 <tr> 29 <td width="78%" style="padding: 2px"> 30 <FIELDSET style="width:90%; padding: 5px"> 31 <LEGEND><span><l10n>Options</l10n></span></LEGEND> 32 <input id="fr_words" type="checkbox" checked> 33 <span id="fr_words_span" style="cursor:default"> 34 <span><l10n>Whole words only</l10n></span></span><br /> 35 <input id="fr_matchcase" type="checkbox"> 36 <span id="fr_matchcase_span" style="cursor:default"> 37 <span><l10n>Case sensitive search</l10n></span></span><br /> 38 <input id="fr_replaceall" type="checkbox" /> 39 <span id="fr_replaceall_span" style="cursor:default"> 40 <span><l10n>Substitute all occurrences</l10n></span></span> 41 </FIELDSET></td> 42 <td width="22%" style="vertical-align: bottom; text-align: right; padding: 4px"> 43 <input type="button" id="fr_clear" value="_(Clear)" style="margin:3px;" /> 44 <div class="space"></div> 45 <input type="button" id="fr_hiliteall"value="_(Highlight)" style="margin:3px;" /> 46 <div class="space"></div> 47 <input type="button" id="fr_undo" value="_(Undo)" style="margin:3px;" /> 48 </td> 49 </tr> 50 </table></td> 51 </tr> 52 </tbody> 53 </table> 54 <div class="buttons" id="[buttons]"> 55 <input type="button" id="fr_go" name="[next]" value="_(Next)" /> 56 <input type="button" id="[done]" value="_(Done)" /> 57 </div> 58 </form> -
find-replace.js
6 6 \*---------------------------------------*/ 7 7 8 8 function FindReplace(editor) { 9 this.editor = editor; 10 var cfg = editor.config; 11 var self = this; 12 cfg.registerButton("FR-findreplace", this._lc("Find and Replace"), 13 editor.imgURL("ed_find.gif", "FindReplace"), false, 14 function(editor) { self.buttonPress(editor); }); 15 cfg.addToolbarElement(["FR-findreplace","separator"], ["formatblock","fontsize","fontname"], -1); 9 this.editor = editor; 10 var cfg = editor.config; 11 var self = this; 12 13 this.tosearch = ''; 14 this.pater = null; 15 this.matches = 0; 16 this.replaces = 0; 17 this.fr_spans = new Array(); 18 19 cfg.registerButton("FR-findreplace", this._lc("Find and Replace"), 20 editor.imgURL("ed_find.gif", "FindReplace"), false, 21 function(editor) { self.buttonPress();}); 22 cfg.addToolbarElement(["FR-findreplace","separator"], ["formatblock","fontsize","fontname"], -1); 16 23 } 17 24 25 FindReplace.prototype.onGenerateOnce = function(editor) { 26 var self = FindReplace; 27 28 this.accepted = { 29 'fr_pattern' : true, 30 'fr_replacement' : true, 31 'fr_words' : true, 32 'fr_matchcase' : true, 33 'fr_replaceall' : true 34 }; 35 36 Xinha._getback(Xinha.getPluginDir("FindReplace") + '/fr_engine.js', function(getback) { eval(getback); self.methodsReady = true; }); 37 Xinha._getback(Xinha.getPluginDir("FindReplace") + "/dialog.html", function(getback) { self.html = getback; }); 38 } 39 18 40 FindReplace.prototype.buttonPress = function(editor) { 19 FindReplace.editor = editor; 20 var sel = editor.getSelectedHTML(); 41 if (!this.dialog) this.prepareDialog(); 42 var editor = this.editor; 43 var sel = editor.getSelectedHTML(); 21 44 if(/\w/.test(sel)) { 22 sel = sel.replace(/<[^>]*>/g,"");23 sel = sel.replace(/ /g,"");45 sel = sel.replace(/<[^>]*>/g,""); 46 sel = sel.replace(/ /g,""); 24 47 } 25 var param = /\w/.test(sel) ? {fr_pattern: sel} : null; 26 editor._popupDialog("plugin://FindReplace/find_replace", null, param); 48 this.params = /\w/.test(sel) ? {fr_pattern: sel} : null; 49 this.buffer = null; 50 51 this.dialog.show(); 52 this.disab("fr_undo,fr_clear,fr_hiliteall",true); 27 53 }; 28 54 29 55 FindReplace._pluginInfo = { … … 37 63 license : "htmlArea" 38 64 }; 39 65 66 FindReplace.prototype.prepareDialog = function(editor) { 67 var editor = this.editor 68 var self = this; 69 70 this.dialog = new Xinha.Dialog(editor, FindReplace.html, 'FindReplace'); 71 72 this.dialog.getElementById('fr_words').onclick = function() {self.clearDoc();} 73 this.dialog.getElementById('fr_words_span').onclick = function() { 74 e = self.dialog.getElementById('fr_words'); 75 e.click(); 76 e.focus(); 77 } 78 this.dialog.getElementById('fr_matchcase').onclick = function() {self.clearDoc();} 79 this.dialog.getElementById('fr_matchcase_span').onclick = function() { 80 e = self.dialog.getElementById('fr_matchcase'); 81 e.click(); 82 e.focus(); 83 } 84 this.dialog.getElementById('fr_replaceall').onclick = function() { 85 if(self.dialog.getElementById('fr_replacement').value == '') { 86 alert(self._lc('You must enter a replacement word')); 87 return false; 88 } 89 self.clearDoc(); 90 } 91 this.dialog.getElementById('fr_replaceall_span').onclick = function() { 92 e = self.dialog.getElementById('fr_replaceall'); 93 e.click(); 94 e.focus(); 95 } 96 this.dialog.getElementById('fr_clear').onclick = function() {self.clearMarks();} 97 this.dialog.getElementById('fr_hiliteall').onclick = function() {self.hiliteAll();} 98 this.dialog.getElementById('fr_undo').onclick = function() {self.resetContents();} 99 this.dialog.getElementById('done').onclick = function() {self.clearDoc(); self.dialog.hide();} 100 this.dialog.getElementById('fr_go').onclick = function() {self.findNext();} 101 this.dialog.getElementById('inputs').onkeypress = function(ev) { 102 ev || (ev = window.event); 103 switch(ev.keyCode) { 104 case 13: // enter 105 self.dialog.getElementById('fr_go').click(); 106 self.dialog.getElementById('fr_pattern').focus(); 107 break; 108 case 27: // ESC 109 self.dialog.getElementById('done').click(); 110 return false; 111 } 112 return true; 113 } 114 115 if (this.params) { 116 this.dialog.getElementById('fr_pattern').value = this.params["fr_pattern"]; 117 this.dialog.getElementById('fr_replacement').focus(); 118 } else { 119 self.dialog.getElementById('fr_pattern').focus(); 120 } 121 } 122 123 FindReplace.prototype.findNext = function(editor) { 124 var dialog = this.dialog; 125 var required = {'fr_pattern' : this._lc("Enter the text you want to find")}; 126 for (var i in required) { 127 var el = dialog.getElementById(i); 128 if (!el.value) { 129 alert(required[i]); 130 el.focus(); 131 return false; 132 } 133 } 134 135 var param = {}; 136 for (var i in this.accepted) { 137 var el = dialog.getElementById(i); 138 param[i] = el.type == 'checkbox' ? el.checked : el.value; 139 } 140 this.execSearch(param); 141 142 return false; 143 } 144 40 145 FindReplace.prototype._lc = function(string) { 41 146 return Xinha._lc(string, 'FindReplace'); 42 147 }; 148 No newline at end of file -
popups/find_replace.html
1 <html>2 <head>3 <title>Find and Replace</title>4 <!--5 /*---------------------------------------*\6 Find and Replace Plugin for HTMLArea-3.07 -----------------------------------------8 author: Cau guanabara9 e-mail: caugb@ibest.com.br10 \*---------------------------------------*/11 -->12 <script type="text/javascript" src="../fr_engine.js"></script>13 <script type="text/javascript" src="../../../popups/popup.js"></script>14 <link rel="stylesheet" type="text/css" href="../../../popups/popup.css" />15 16 <script type="text/javascript">17 18 window.resizeTo(335, 250);19 20 var accepted = {21 'fr_pattern' : true,22 'fr_replacement' : true,23 'fr_words' : true,24 'fr_matchcase' : true,25 'fr_replaceall' : true26 };27 28 function Init() {29 __dlg_translate('FindReplace');30 __dlg_init();31 32 disab("fr_undo,fr_clear,fr_hiliteall",true);33 34 var params = window.dialogArguments;35 if(params) {36 document.getElementById('fr_pattern').value = params["fr_pattern"];37 document.getElementById('fr_replacement').focus();38 } else {39 document.getElementById('fr_pattern').focus();40 }41 42 document.body.onkeypress = __dlg_key_press;43 }44 45 function onCancel() {46 clearDoc();47 __dlg_close(null);48 return false;49 }50 51 function onOK() {52 var required = {'fr_pattern' : _lc("Enter the text you want to find")};53 for (var i in required) {54 var el = document.getElementById(i);55 if (!el.value) {56 alert(required[i]);57 el.focus();58 return false;59 }60 }61 62 var param = {};63 for (var i in accepted) {64 var el = document.getElementById(i);65 param[i] = el.type == 'checkbox' ? el.checked : el.value;66 }67 execSearch(param);68 return false;69 }70 71 function __dlg_key_press(ev) {72 ev || (ev = window.event);73 switch(ev.keyCode) {74 case 13:75 document.getElementById('fr_go').click();76 document.getElementById('fr_pattern').focus();77 break;78 case 27:79 clearDoc();80 window.close();81 return false;82 }83 return true;84 }85 86 </script>87 88 <style type="text/css">89 table .label { text-align: right; width: 12em; }90 .title {91 background: #ddf;92 color: #000;93 font-weight: bold;94 font-size: 120%;95 padding: 3px 10px;96 margin-bottom: 10px;97 border-bottom: 1px solid black;98 letter-spacing: 2px;99 }100 .buttons { border-top: 1px solid #999; padding: 2px; text-align: right; }101 .hrstyle { border-width: 1px; border-color: #666; width: 95%; padding: 2px; }102 </style>103 </head>104 <body class="dialog" onload="Init()">105 <div class="title">Find and Replace</div>106 <form action="" method="get">107 <table border="0" style="width: 100%; padding: 2px;"><!---->108 <tbody>109 <tr>110 <td width="29%" style="text-align: right; vertical-align: bottom;">Search for:</td>111 <td width="71%" colspan="2" style="vertical-align: bottom;">112 <input id="fr_pattern" type="text" style="width: 200px" onFocus="this.select();">113 </td>114 </tr>115 <tr>116 <td style="text-align: right;">Replace with:</td>117 <td colspan="2">118 <input id="fr_replacement" type="text" style="width: 200px" onFocus="this.select();">119 </td>120 </tr>121 <tr>122 <td colspan="3"><table width="100%" border="0" cellpadding="1" cellspacing="0">123 <tr>124 <td width="78%" style="padding: 2px">125 <FIELDSET style="width:90%; padding: 5px">126 <LEGEND><span>Options</span></LEGEND>127 <input id="fr_words" type="checkbox" checked onClick="clearDoc();">128 <span onClick="e = document.getElementById('fr_words');129 e.click(); e.focus();" style="cursor:default">130 <span>Whole words only</span></span><br />131 <input id="fr_matchcase" type="checkbox" onClick="clearDoc();">132 <span onClick="e = document.getElementById('fr_matchcase');133 e.click(); e.focus();" style="cursor:default">134 <span>Case sensitive search</span></span><br />135 <input id="fr_replaceall" type="checkbox" onClick="136 if(document.getElementById('fr_replacement').value == '') {137 alert(_lc('Inform a replacement word'));138 return false;139 }140 clearDoc();">141 <span onClick="e = document.getElementById('fr_replaceall');142 e.click(); e.focus();" style="cursor:default">143 <span>Substitute all occurrences</span></span>144 </FIELDSET></td>145 <td width="22%" style="vertical-align: bottom; text-align: right; padding: 4px">146 <button type="button" id="fr_clear" onClick="clearMarks()">Clear</button>147 <div class="space"></div>148 <button type="button" id="fr_hiliteall" onClick="hiliteAll()">Highlight</button>149 <div class="space"></div>150 <button type="button" id="fr_undo" onClick="resetContents();">Undo</button>151 </td>152 </tr>153 </table></td>154 </tr>155 </tbody>156 </table>157 <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>158 <button type="button" name="cancel" onclick="return onCancel();">Done</button>159 </div>160 </form>161 </body>162 </html>163 No newline at end of file -
fr_engine.js
5 5 e-mail: caugb@ibest.com.br 6 6 \*---------------------------------------*/ 7 7 8 var FindReplace = window.opener.FindReplace; 9 var editor = FindReplace.editor; 10 var is_mo = window.opener.Xinha.is_gecko; 11 var tosearch = ''; 12 var pater = null; 13 var buffer = null; 14 var matches = 0; 15 var replaces = 0; 16 var fr_spans = new Array(); 17 function _lc(string) { 18 return(window.opener.Xinha._lc(string, 'FindReplace')); 19 } 20 function execSearch(params) { 21 var ihtml = editor._doc.body.innerHTML; 22 if(buffer == null) 23 buffer = ihtml; 8 FindReplace.prototype.execSearch = function(params) { 9 var editor = this.editor; 10 var ihtml = editor._doc.body.innerHTML; 11 if(this.buffer == null) 12 this.buffer = ihtml; 24 13 25 if(params['fr_pattern'] != t osearch) {26 if(t osearch != '')27 clearDoc();28 tosearch = params['fr_pattern'];14 if(params['fr_pattern'] != this.tosearch) { 15 if(this.tosearch != '') 16 this.clearDoc(); 17 this.tosearch = params['fr_pattern']; 29 18 } 30 19 31 if (matches == 0) {32 er = params['fr_words'] ? "/(?!<[^>]*)(\\b"+params['fr_pattern']+"\\b)(?![^<]*>)/g" :33 "/(?!<[^>]*)("+params['fr_pattern']+")(?![^<]*>)/g";20 if (this.matches == 0) { 21 er = params['fr_words'] ? "/(?!<[^>]*)(\\b"+params['fr_pattern']+"\\b)(?![^<]*>)/g" : 22 "/(?!<[^>]*)("+params['fr_pattern']+")(?![^<]*>)/g"; 34 23 if(!params['fr_matchcase']) 35 24 er += "i"; 36 37 pater = eval(er);38 39 var tago = '<span id=frmark>';40 var tagc = '</span>';41 var newHtml = ihtml.replace(pater,tago+"$1"+tagc);42 43 editor.setHTML(newHtml);44 45 var getallspans = editor._doc.body.getElementsByTagName("span");25 26 this.pater = eval(er); 27 28 var tago = '<span id=frmark>'; 29 var tagc = '</span>'; 30 var newHtml = ihtml.replace(this.pater,tago+"$1"+tagc); 31 32 editor.setHTML(newHtml); 33 34 var getallspans = editor._doc.body.getElementsByTagName("span"); 46 35 for (var i = 0; i < getallspans.length; i++) 47 36 if(/^frmark/.test(getallspans[i].id)) 48 fr_spans.push(getallspans[i]);37 this.fr_spans.push(getallspans[i]); 49 38 } 50 39 51 spanWalker(params['fr_pattern'],params['fr_replacement'],params['fr_replaceall']);40 this.spanWalker(params['fr_pattern'],params['fr_replacement'],params['fr_replaceall']); 52 41 } 53 42 54 function spanWalker(pattern,replacement,replaceall) {55 var foundtrue = false;56 clearMarks();43 FindReplace.prototype.spanWalker = function(pattern, replacement, replaceall) { 44 var foundtrue = false; 45 this.clearMarks(); 57 46 58 for (var i = matches; i <fr_spans.length; i++) {59 var elm =fr_spans[i];60 foundtrue = true;47 for (var i = this.matches; i < this.fr_spans.length; i++) { 48 var elm = this.fr_spans[i]; 49 foundtrue = true; 61 50 if(!(/[0-9]$/.test(elm.id))) { 62 matches++;63 disab('fr_clear',false);64 elm.id = 'frmark_'+matches;65 elm.style.color = 'white';66 elm.style.backgroundColor = 'highlight';67 elm.style.fontWeight = 'bold';68 elm.scrollIntoView(false);51 this.matches++; 52 this.disab('fr_clear',false); 53 elm.id = 'frmark_'+this.matches; 54 elm.style.color = 'white'; 55 elm.style.backgroundColor = 'highlight'; 56 elm.style.fontWeight = 'bold'; 57 elm.scrollIntoView(false); 69 58 if(/\w/.test(replacement)) { 70 if(replaceall || confirm( _lc("Substitute this occurrence?"))) {71 elm.firstChild.replaceData(0,elm.firstChild.data.length,replacement);72 replaces++;73 disab('fr_undo',false);59 if(replaceall || confirm(this._lc("Substitute this occurrence?"))) { 60 elm.firstChild.replaceData(0,elm.firstChild.data.length,replacement); 61 this.replaces++; 62 this.disab('fr_undo',false); 74 63 } 75 64 if(replaceall) { 76 clearMarks();77 continue;65 this.clearMarks(); 66 continue; 78 67 } 79 68 } 80 break;69 break; 81 70 } 82 71 } 83 var last = (i >= fr_spans.length - 1);72 var last = (i >= this.fr_spans.length - 1); 84 73 if(last || !foundtrue) { // EOF 85 var message =_lc("Done")+':\n\n';86 if( matches > 0) {87 if( matches == 1) message += matches+' '+_lc("found item");88 else message += matches+' '+_lc("found items");89 if( replaces > 0) {90 if( replaces == 1) message += ',\n'+replaces+' '+_lc("replaced item");91 else message += ',\n'+ replaces+' '+_lc("replaced items");74 var message = this._lc("Done")+':\n\n'; 75 if(this.matches > 0) { 76 if(this.matches == 1) message += this.matches+' '+this._lc("found item"); 77 else message += this.matches+' '+this._lc("found items"); 78 if(this.replaces > 0) { 79 if(this.replaces == 1) message += ',\n'+this.replaces+' '+this._lc("replaced item"); 80 else message += ',\n'+this.replaces+' '+this._lc("replaced items"); 92 81 } 93 hiliteAll();94 disab('fr_hiliteall',false);95 } else { message += '"'+pattern+'" '+ _lc("not found"); }96 alert(message+'.');82 this.hiliteAll(); 83 this.disab('fr_hiliteall',false); 84 } else { message += '"'+pattern+'" '+this._lc("not found"); } 85 alert(message+'.'); 97 86 } 98 87 } 99 88 100 function clearDoc() { 101 var doc = editor._doc.body.innerHTML; 102 var er = /(<span\s+[^>]*id=.?frmark[^>]*>)([^<>]*)(<\/span>)/gi; 103 editor._doc.body.innerHTML = doc.replace(er,"$2"); 104 pater = null; 105 tosearch = ''; 106 fr_spans = new Array(); 107 matches = 0; 108 replaces = 0; 109 disab("fr_hiliteall,fr_clear",true); 89 FindReplace.prototype.clearDoc = function() { 90 var editor = this.editor; 91 var doc = editor._doc.body.innerHTML; 92 var er = /(<span\s+[^>]*id=.?frmark[^>]*>)([^<>]*)(<\/span>)/gi; 93 editor._doc.body.innerHTML = doc.replace(er,"$2"); 94 this.pater = null; 95 this.tosearch = ''; 96 this.fr_spans = new Array(); 97 this.matches = 0; 98 this.replaces = 0; 99 this.disab("fr_hiliteall,fr_clear",true); 110 100 } 111 101 112 function clearMarks() { 113 var getall = editor._doc.body.getElementsByTagName("span"); 102 FindReplace.prototype.clearMarks = function() { 103 var editor = this.editor; 104 var getall = editor._doc.body.getElementsByTagName("span"); 114 105 for (var i = 0; i < getall.length; i++) { 115 var elm = getall[i];106 var elm = getall[i]; 116 107 if(/^frmark/.test(elm.id)) { 117 var objStyle = editor._doc.getElementById(elm.id).style;118 objStyle.backgroundColor = "";119 objStyle.color = "";120 objStyle.fontWeight = "";108 var objStyle = editor._doc.getElementById(elm.id).style; 109 objStyle.backgroundColor = ""; 110 objStyle.color = ""; 111 objStyle.fontWeight = ""; 121 112 } 122 113 } 123 114 } 124 115 125 function hiliteAll() { 126 var getall = editor._doc.body.getElementsByTagName("span"); 116 FindReplace.prototype.hiliteAll = function() { 117 var editor = this.editor; 118 var getall = editor._doc.body.getElementsByTagName("span"); 127 119 for (var i = 0; i < getall.length; i++) { 128 var elm = getall[i];120 var elm = getall[i]; 129 121 if(/^frmark/.test(elm.id)) { 130 var objStyle = editor._doc.getElementById(elm.id).style;131 objStyle.backgroundColor = "highlight";132 objStyle.color = "white";133 objStyle.fontWeight = "bold";122 var objStyle = editor._doc.getElementById(elm.id).style; 123 objStyle.backgroundColor = "highlight"; 124 objStyle.color = "white"; 125 objStyle.fontWeight = "bold"; 134 126 } 135 127 } 136 128 } 137 129 138 function resetContents() { 139 if(buffer == null) return; 140 var transp = editor._doc.body.innerHTML; 141 editor._doc.body.innerHTML = buffer; 142 buffer = transp; 130 FindReplace.prototype.resetContents = function() { 131 var editor = this.editor; 132 if(this.buffer == null) return; 133 var transp = editor._doc.body.innerHTML; 134 editor._doc.body.innerHTML = this.buffer; 135 this.buffer = transp; 143 136 } 144 137 145 function disab(elms,toset) {146 var names = elms.split(/[,; ]+/);138 FindReplace.prototype.disab = function(elms,toset) { 139 var names = elms.split(/[,; ]+/); 147 140 for(var i = 0; i < names.length; i++) 148 141 document.getElementById(names[i]).disabled = toset; 149 142 } 143 No newline at end of file
