Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/find-replace.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/find-replace.js	(révision 7091)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/find-replace.js	(copie de travail)
@@ -33,88 +33,461 @@
  * TYPO3 SVN ID: $Id$
  */
 FindReplace = HTMLArea.Plugin.extend({
-
-	constructor : function(editor, pluginName) {
+	constructor: function(editor, pluginName) {
 		this.base(editor, pluginName);
 	},
-
 	/*
 	 * This function gets called by the class constructor
 	 */
-	configurePlugin : function(editor) {
-
+	configurePlugin: function(editor) {
 		/*
 		 * Registering plugin "About" information
 		 */
 		var pluginInformation = {
-			version		: "1.2",
-			developer	: "Cau Guanabara & Stanislas Rolland",
-			developerUrl	: "mailto:caugb@ibest.com.br",
-			copyrightOwner	: "Cau Guanabara & Stanislas Rolland",
-			sponsor		: "Independent production & SJBR",
-			sponsorUrl	: "http://www.netflash.com.br/gb/HA3-rc1/examples/find-replace.html",
-			license		: "GPL"
+			version		: '2.0',
+			developer	: 'Cau Guanabara & Stanislas Rolland',
+			developerUrl	: 'http://www.sjbr.ca',
+			copyrightOwner	: 'Cau Guanabara & Stanislas Rolland',
+			sponsor		: 'Independent production & SJBR',
+			sponsorUrl	: 'http://www.sjbr.ca',
+			license		: 'GPL'
 		};
 		this.registerPluginInformation(pluginInformation);
-
 		/*
 		 * Registering the button
 		 */
-		var buttonId = "FindReplace";
+		var buttonId = 'FindReplace';
 		var buttonConfiguration = {
 			id		: buttonId,
-			tooltip		: this.localize("Find and Replace"),
-			action		: "onButtonPress",
+			tooltip		: this.localize('Find and Replace'),
+			action		: 'onButtonPress',
 			dialog		: true
 		};
 		this.registerButton(buttonConfiguration);
-
-		this.popupWidth = 400;
-		this.popupHeight = 360;
-
+			// Compile regular expression to clean up marks
+		this.marksCleaningRE = /(<span\s+[^>]*id="?htmlarea-frmark[^>]*"?>)([^<>]*)(<\/span>)/gi;
 		return true;
 	},
-
 	/*
-	 * This function gets called when the button was pressed.
+	 * This function gets called when the 'Find & Replace' button is pressed.
 	 *
 	 * @param	object		editor: the editor instance
 	 * @param	string		id: the button id or the key
 	 *
 	 * @return	boolean		false if action is completed
 	 */
-	onButtonPress : function (editor, id, target) {
+	onButtonPress: function (editor, id, target) {
 			// Could be a button or its hotkey
 		var buttonId = this.translateHotKey(id);
 		buttonId = buttonId ? buttonId : id;
-
-		var sel = this.editor.getSelectedHTML(), param = null;
-		if (/\w/.test(sel)) {
-			sel = sel.replace(/<[^>]*>/g,"");
-			sel = sel.replace(/&nbsp;/g,"");
+			// Initialize search variables
+		this.buffer = null;
+		this.initVariables();
+			// Disable the toolbar undo/redo buttons and snapshots while this window is opened
+		var plugin = this.getPluginInstance('UndoRedo');
+		if (plugin) {
+			plugin.stop();
+			var undo = this.getButton('Undo');
+			if (undo) {
+				undo.setDisabled(true);
+			}
+			var redo = this.getButton('Redo');
+			if (redo) {
+				redo.setDisabled(true);
+			}
 		}
-		if (/\w/.test(sel)) {
-			param = { fr_pattern: sel };
+			// Open dialogue window
+		this.openDialogue(
+			buttonId,
+			'Find and Replace',
+			this.getWindowDimensions(
+				{
+					width: 460,
+					height:360
+				},
+				buttonId
+			)
+		);
+		return false;
+	},
+	/*
+	 * Open the dialogue window
+	 *
+	 * @param	string		buttonId: the button id
+	 * @param	string		title: the window title
+	 * @param	integer		dimensions: the opening width of the window
+	 *
+	 * @return	void
+	 */
+	openDialogue: function (buttonId, title, dimensions) {
+		this.dialog = new Ext.Window({
+			title: this.localize(title),
+			cls: 'htmlarea-window',
+			border: false,
+			width: dimensions.width,
+			height: 'auto',
+				// As of ExtJS 3.1, JS error with IE when the window is resizable
+			resizable: !Ext.isIE,
+			iconCls: buttonId,
+			listeners: {
+				close: {
+					fn: this.onClose,
+					scope: this
+				}
+			},
+			items: [{
+					xtype: 'fieldset',
+					defaultType: 'textfield',
+					labelWidth: 150,
+					defaults: {
+						labelSeparator: '',
+						width: 250,
+						listeners: {
+							change: {
+								fn: this.clearDoc,
+								scope: this
+							}
+						}
+					},
+					listeners: {
+						render: {
+							fn: this.initPattern,
+							scope: this
+						}
+					},
+					items: [{
+							itemId: 'pattern',
+							fieldLabel: this.localize('Search for:')
+						},{
+							itemId: 'replacement',
+							fieldLabel: this.localize('Replace with:')
+						}
+					]
+				},{
+					xtype: 'fieldset',
+					defaultType: 'checkbox',
+					title: this.localize('Options'),
+					labelWidth: 150,
+					items: [{
+							itemId: 'words',
+							fieldLabel: this.localize('Whole words only'),
+							listeners: {
+								check: {
+									fn: this.clearDoc,
+									scope: this
+								}
+							}
+						},{
+							itemId: 'matchCase',
+							fieldLabel: this.localize('Case sensitive search'),
+							listeners: {
+								check: {
+									fn: this.clearDoc,
+									scope: this
+								}
+							}
+						},{
+							itemId: 'replaceAll',
+							fieldLabel: this.localize('Substitute all occurrences'),
+							listeners: {
+								check: {
+									fn: this.requestReplacement,
+									scope: this
+								}
+							}
+						}
+					]
+				},{
+					xtype: 'fieldset',
+					defaultType: 'button',
+					title: this.localize('Actions'),
+					defaults: {
+						minWidth: 150,
+						disabled: true,
+						style: {
+							marginBottom: '5px'
+						}
+					},
+					items: [{
+							text: this.localize('Clear'),
+							itemId: 'clear',
+							listeners: {
+								click: {
+									fn: this.clearMarks,
+									scope: this
+								}
+							}
+						},{
+							text: this.localize('Highlight'),
+							itemId: 'hiliteall',
+							listeners: {
+								click: {
+									fn: this.hiliteAll,
+									scope: this
+								}
+							}
+						},{
+							text: this.localize('Undo'),
+							itemId: 'undo',
+							listeners: {
+								click: {
+									fn: this.resetContents,
+									scope: this
+								}
+							}
+						}
+					]
+				}
+			],
+			buttons: [
+				this.buildButtonConfig('Next', this.onNext),
+				this.buildButtonConfig('Done', this.onCancel)
+			]
+		});
+		this.show();
+	},
+	/*
+	 * Handler invoked to initialize the pattern to search
+	 *
+	 * @param	object		fieldset: the fieldset component
+	 *
+	 * @return	void
+	 */
+	initPattern: function (fieldset) {
+		var selection = this.editor.getSelectedHTML();
+		if (/\S/.test(selection)) {
+			selection = selection.replace(/<[^>]*>/g, '');
+			selection = selection.replace(/&nbsp;/g, '');
 		}
-		if (Ext.isOpera) {
-			this.cleanUpRegularExpression = /(<span\s+[^>]*id=.?frmark[^>]*>)([^<>]*)(<\/span>)/gi;
-			this.cleanUp.defer(200, this);
+		if (/\S/.test(selection)) {
+			fieldset.getComponent('pattern').setValue(selection);
+			fieldset.getComponent('replacement').focus();
+		} else {
+			fieldset.getComponent('pattern').focus();
 		}
-		this.dialog = this.openDialog("FindReplace", this.makeUrlFromPopupName("find_replace"), null, param, {width:this.popupWidth, height:this.popupHeight});
+	},
+	/*
+	 * Handler invoked when the replace all checkbox is checked
+	 */
+	requestReplacement: function () {
+		if (!this.dialog.find('itemId', 'replacement')[0].getValue() && this.dialog.find('itemId', 'replaceAll')[0].getValue()) {
+			Ext.MessageBox.alert('', this.localize('Inform a replacement word'));
+		}
+		this.clearDoc();
+	},
+	/*
+	 * Handler invoked when the 'Next' button is pressed
+	 */
+	onNext: function () {
+		if (!this.dialog.find('itemId', 'pattern')[0].getValue()) {
+			Ext.MessageBox.alert('', this.localize('Enter the text you want to find'));
+			this.dialog.find('itemId', 'pattern')[0].focus();
+			return false;
+		}
+		var fields = [
+			'pattern',
+			'replacement',
+			'words',
+			'matchCase',
+			'replaceAll'
+		];
+		var params = {};
+		Ext.each(fields, function (field) {
+			params[field] = this.dialog.find('itemId', field)[0].getValue();
+		}, this);
+		this.search(params);
 		return false;
 	},
-
 	/*
-	 * This function cleans up any span tag left by Opera if the window was closed with the close handle in which case the unload event is not fired by Opera
+	 * Search the pattern and insert span tags
 	 *
+	 * @param	object		params: the parameters of the search corresponding to the values of fields:
+	 *					pattern
+	 *					replacement
+	 *					words
+	 *					matchCase
+	 *					replaceAll
+	 *
 	 * @return	void
 	 */
-	cleanUp : function () {
-		if (this.dialog && (!this.dialog.dialogWindow || (this.dialog.dialogWindow && this.dialog.dialogWindow.closed))) {
-			this.editor.setHTML(this.editor.getInnerHTML().replace(this.cleanUpRegularExpression,"$2"));
-			this.dialog.close();
+	search: function (params) {
+		var html = this.editor.getInnerHTML();
+		if (this.buffer == null) {
+			this.buffer = html;
+		}
+		if (this.matches == 0) {
+			var pattern = new RegExp(params.words ? '(?!<[^>]*)(\\b' + params.pattern + '\\b)(?![^<]*>)' : '(?!<[^>]*)(' + params.pattern + ')(?![^<]*>)', 'g' + (params.matchCase? '' : 'i'));
+			this.editor.setHTML(html.replace(pattern, '<span id="htmlarea-frmark">' + "$1" + '</span>'));
+			Ext.each(this.editor.document.body.getElementsByTagName('span'), function (mark) {
+				if (/^htmlarea-frmark/.test(mark.id)) {
+					this.spans.push(mark);
+				}
+			}, this);
+		}
+		this.spanWalker(params.pattern, params.replacement, params.replaceAll);
+	},
+	/*
+	 * Walk the span tags
+	 *
+	 * @param	string		pattern: the pattern being searched for
+	 * @param	string		replacement: the replacement string
+	 * @param	bolean		replaceAll: true if all occurrences should be replaced
+	 *
+	 * @return	void
+	 */
+	spanWalker: function (pattern, replacement, replaceAll) {
+		this.clearMarks();
+		if (this.spans.length) {
+			Ext.each(this.spans, function (mark, i) {
+				if (i >= this.matches && !/[0-9]$/.test(mark.id)) {
+					this.matches++;
+					this.disableActions('clear', false);
+					mark.id = 'htmlarea-frmark_' + this.matches;
+					mark.style.color = 'white';
+					mark.style.backgroundColor = 'highlight';
+					mark.style.fontWeight = 'bold';
+					mark.scrollIntoView(false);
+					var self = this;
+					function replace(button) {
+						if (button == 'yes') {
+							mark.firstChild.replaceData(0, mark.firstChild.data.length, replacement);
+							self.replaces++;
+							self.disableActions('undo', false);
+						}
+						self.endWalk(pattern, i);
+					}
+					if (replaceAll) {
+						replace('yes');
+						return true;
+					} else {
+						Ext.MessageBox.confirm('', this.localize('Substitute this occurrence?'), replace, this);
+						return false;
+					}
+				}
+			}, this);
 		} else {
-			this.cleanUp.defer(200, this);
+			this.endWalk(pattern, 0);
 		}
+	},
+	/*
+	 * End the replacement walk
+	 *
+	 * @param	string		pattern: the pattern being searched for
+	 * @param	integer		index: the index reached in the walk
+	 *
+	 * @return 	void
+	 */
+	endWalk: function (pattern, index) {
+		if (index >= this.spans.length - 1 || !this.spans.length) {
+			var message = this.localize('Done') + ':<br /><br />';
+			if (this.matches > 0) {
+				if (this.matches == 1) {
+					message += this.matches + ' ' + this.localize('found item');
+				} else {
+					message += this.matches + ' ' + this.localize('found items');
+				}
+				if (this.replaces > 0) {
+					if (this.replaces == 1) {
+						message += ',<br />' + this.replaces + ' ' + this.localize('replaced item');
+					} else {
+						message += ',<br />' + this.replaces + ' ' + this.localize('replaced items');
+					}
+				}
+				this.hiliteAll();
+			} else {
+				message += '"' + pattern + '" ' + this.localize('not found');
+				this.disableActions('hiliteall,clear', true);
+			}
+			Ext.MessageBox.minWidth = 300;
+			Ext.MessageBox.alert('', message + '.');
+		}
+	},
+	/*
+	 * Remove all marks
+	 */
+	clearDoc: function () {
+		this.editor.setHTML(this.editor.getInnerHTML().replace(this.marksCleaningRE, "$2"));
+		this.initVariables();
+		this.disableActions('hiliteall,clear', true);
+	},
+	/*
+	 * De-highlight all marks
+	 */
+	clearMarks: function () {
+		Ext.each(this.editor.document.body.getElementsByTagName('span'), function (mark) {
+			if (/^htmlarea-frmark/.test(mark.id)) {
+				mark.style.backgroundColor = '';
+				mark.style.color = '';
+				mark.style.fontWeight = '';
+			}
+		}, this);
+		this.disableActions('hiliteall', false);
+		this.disableActions('clear', true);
+	},
+	/*
+	 * Highlight all marks
+	 */
+	hiliteAll: function () {
+		Ext.each(this.editor.document.body.getElementsByTagName('span'), function (mark) {
+			if (/^htmlarea-frmark/.test(mark.id)) {
+				mark.style.backgroundColor = 'highlight';
+				mark.style.color = 'white';
+				mark.style.fontWeight = 'bold';
+			}
+		}, this);
+		this.disableActions('clear', false);
+		this.disableActions('hiliteall', true);
+	},
+	/*
+	 * Undo the replace operation
+	 */
+	resetContents: function () {
+		if (this.buffer != null) {
+			var transp = this.editor.getInnerHTML();
+			this.editor.setHTML(this.buffer);
+			this.buffer = transp;
+			this.disableActions('clear', true);
+		}
+	},
+	/*
+	 * Disable action buttons
+	 *
+	 * @param	array		actions: array of buttonIds to set disabled/enabled
+	 * @param	boolean		disabled: true to set disabled
+	 */
+	disableActions: function (actions, disabled) {
+		Ext.each(actions.split(/[,; ]+/), function (action) {
+				this.dialog.find('itemId', action)[0].setDisabled(disabled);
+		}, this);
+	},
+	/*
+	 * Initialize find & replace variables
+	 */
+	initVariables: function () {
+		this.matches = 0;
+		this.replaces = 0;
+		this.spans = new Array();
+	},
+	/*
+	 * Clear the document before leaving on 'Done' button
+	 */
+	onCancel: function () {
+		this.clearDoc();
+		var plugin = this.getPluginInstance('UndoRedo');
+		if (plugin) {
+			plugin.start();
+		}
+		this.base();
+	},
+	/*
+	 * Clear the document before leaving on window close handle
+	 */
+	onClose: function () {
+		this.clearDoc();
+		var plugin = this.getPluginInstance('UndoRedo');
+		if (plugin) {
+			plugin.start();
+		}
+		this.base();
 	}
 });
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/fr_engine.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/fr_engine.js	(révision 7091)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/fr_engine.js	(copie de travail)
@@ -1,154 +0,0 @@
-/*---------------------------------------*\
- Find and Replace Plugin for HTMLArea-3.0
- -----------------------------------------
- author: Cau guanabara 
- e-mail: caugb@ibest.com.br
-\*---------------------------------------*/
-
-	var tosearch = '';
-	var pater = null;
-	var buffer = null;
-	var matches = 0;
-	var replaces = 0;
-	var fr_spans = new Array();
-		
-	function execSearch (params) {
-		var ihtml = dialog.plugin.getPluginInstance("EditorMode").getInnerHTML();
-		if (buffer == null) {
-			buffer = ihtml;
-		}
-		
-		if (params.fr_pattern != tosearch) {
-			if (tosearch != "") {
-				clearDoc();
-			}
-			tosearch = params.fr_pattern;
-		}
-		
-		if (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);
-			dialog.plugin.getPluginInstance("EditorMode").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]);
-				}
-			}
-		}
-		spanWalker(params['fr_pattern'],params['fr_replacement'],params['fr_replaceall']);
-	};
-	
-	function spanWalker (pattern,replacement,replaceall) {
-		var foundtrue = false;
-		clearMarks();
-		
-		for (var i = matches; i < fr_spans.length; i++) {
-			var elm = fr_spans[i];
-			foundtrue = true;
-			if (!(/[0-9]$/.test(elm.id))) {
-				matches++;
-				disable('fr_clear', false);
-				elm.id = 'frmark_'+ matches;
-				elm.style.color = 'white';
-				elm.style.backgroundColor = 'highlight';
-				elm.style.fontWeight = 'bold';
-				elm.scrollIntoView(false);
-				if (replaceall || confirm(dialog.plugin.localize("Substitute this occurrence?"))) {
-					elm.firstChild.replaceData(0,elm.firstChild.data.length,replacement);
-					replaces++;
-					disable('fr_undo', false);
-				}
-				if (replaceall) {
-					clearMarks();
-					continue;
-				}
-				break;
-			}
-		}
-		var last = (i >= fr_spans.length - 1);
-		if (last || !foundtrue) { // EOF
-			var message = dialog.plugin.localize("Done")+":\n\n";
-			if (matches > 0) {
-				if (matches == 1) {
-					message += matches+' ' + dialog.plugin.localize("found item");
-				} else {
-					message += matches+' ' + dialog.plugin.localize("found items");
-				}
-				if (replaces > 0) {
-					if (replaces == 1) {
-						message += ',\n'+replaces+' ' + dialog.plugin.localize("replaced item");
-					} else {
-						message += ',\n'+replaces+' ' + dialog.plugin.localize("replaced items");
-					}
-				}
-				hiliteAll();
-				disable('fr_hiliteall', false);
-			} else {
-				message += '"' + pattern + '" ' + dialog.plugin.localize("not found");
-			}
-			alert(message+'.');
-		}
-	};
-	
-	function clearDoc () {
-		var er = /(<span\s+[^>]*id=.?frmark[^>]*>)([^<>]*)(<\/span>)/gi;
-		dialog.plugin.getPluginInstance("EditorMode").setHTML(dialog.plugin.getPluginInstance("EditorMode").getInnerHTML().replace(er,"$2"));
-		pater = null;
-		tosearch = '';
-		fr_spans = new Array();
-		matches = 0;
-		replaces = 0;
-		disable("fr_hiliteall,fr_clear", true);
-	};
-	
-	function clearMarks () {
-		var getall = editor._doc.body.getElementsByTagName("span");
-		for (var i = 0; i < getall.length; i++) {
-			var elm = getall[i];
-			if (/^frmark/.test(elm.id)) {
-				var objStyle = editor._doc.getElementById(elm.id).style;
-				objStyle.backgroundColor = "";
-				objStyle.color = "";
-				objStyle.fontWeight = "";
-			}
-		}
-	};
-	
-	function hiliteAll () {
-		var getall = editor._doc.body.getElementsByTagName("span");
-		for (var i = 0; i < getall.length; 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";
-			}
-		}
-	};
-	
-	function resetContents () {
-		if (buffer != null) {
-			var transp = dialog.plugin.getPluginInstance("EditorMode").getInnerHTML();
-			dialog.plugin.getPluginInstance("EditorMode").setHTML(buffer);
-			buffer = transp;
-		}
-	};
-	
-	function disable (elms, toset) {
-		var names = elms.split(/[,; ]+/);
-		for (var i = 0; i < names.length; i++) {
-			document.getElementById(names[i]).disabled = toset;
-		}
-	};
-	
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/locallang.xml
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/locallang.xml	(révision 7091)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/locallang.xml	(copie de travail)
@@ -15,13 +15,13 @@
 			<label index="replaced item">item replaced</label>
 			<label index="not found">not found</label>
 			<label index="Find and Replace">Find And Replace</label>
-			<label index="Options">Options:</label>
+			<label index="Options">Options</label>
 			<label index="Whole words only">Whole words only</label>
 			<label index="Case sensitive search">Case sensitive search</label>
 			<label index="Substitute all occurrences">Substitute all occurrences</label>
 			<label index="Search for:">Search for:</label>
 			<label index="Replace with:">Replace with:</label>
-			<label index="Actions">Actions:</label>
+			<label index="Actions">Actions</label>
 			<label index="Clear">Clear</label>
 			<label index="Highlight">Highlight</label>
 			<label index="Undo">Undo</label>
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/popups/find_replace.html
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/popups/find_replace.html	(révision 7091)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/popups/find_replace.html	(copie de travail)
@@ -1,183 +0,0 @@
-<!DOCTYPE html
-     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-<!--
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2004 Cau guanabara <caugb@ibest.com.br>
-*  (c) 2005-2008 Stanislas Rolland <typo3(arobas)sjbr.ca>
-*  All rights reserved
-*
-*  This script is part of the TYPO3 project. The TYPO3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*  A copy is found in the textfile GPL.txt and important notices to the license
-*  from the author is found in LICENSE.txt distributed with these scripts.
-*
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This script is a modified version of a script published under the htmlArea License.
-*  A copy of the htmlArea License may be found in the textfile HTMLAREA_LICENSE.txt.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-/*
- * Find and Replace Plugin for TYPO3 htmlArea RTE
- *
- * TYPO3 SVN ID: $Id$
- */
--->
-<head>
-	<title>Find and Replace</title>
-	<meta http-equiv="Content-Style-Type" content="text/css" />
-	<script type="text/javascript" src="../fr_engine.js"></script>
-	<script type="text/javascript">
-		/*<![CDATA[*/
-		<!--
-		var dialog = window.opener.HTMLArea.Dialog.FindReplace;
-		var editor;
-		var accepted = {
-			'fr_pattern'       : true,
-			'fr_replacement'   : true,
-			'fr_words'         : true,
-			'fr_matchcase'     : true,
-			'fr_replaceall'    : true
-		};
-
-		function Init() {
-			editor = dialog.plugin.editor;
-			disable("fr_undo,fr_clear,fr_hiliteall", true);
-
-			var params = dialog.arguments;
-			if (params) {
-				document.getElementById('fr_pattern').value = params.fr_pattern;
-				document.getElementById('fr_replacement').focus();
-			} else {
-				document.getElementById('fr_pattern').focus();
-			}
-			window.opener.HTMLArea._addEvent(document, "keypress", onKeyPress);
-			if (window.opener.HTMLArea.is_gecko) {
-				window.opener.HTMLArea._addEvent(window, "unload", onCancel);
-			}
-			dialog.initialize();
-			if (HTMLArea.is_ie) {
-				HTMLArea._addEvent(window, "unload", onCancel);
-			}
-		};
-		function requestReplacement() {
-			if (!document.getElementById("fr_replacement").value && document.getElementById("fr_replaceall").checked) {
-				return confirm(dialog.plugin.localize("Inform a replacement word"));
-			}
-			clearDoc();
-		}
-		function onCancel() {
-			if (dialog) {
-				clearDoc();
-				HTMLArea._removeEvent(document, "keypress", onKeyPress);
-				HTMLArea._removeEvent(window, "unload", onCancel);
-				dialog.close();
-			}
-			return false;
-		};
-		function onOK() {
-			var required = {'fr_pattern' : dialog.plugin.localize("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 onEscape(ev) {
-			if (!ev) var ev = window.event;
-			if (ev.keyCode == 27) {
-				return onCancel();
-			}
-			return true;
-		};
-		function onKeyPress (ev) {
-			if (!ev) var ev = window.event;
-			switch(ev.keyCode) {
-				case 13:
-					document.getElementById('fr_go').click();
-					document.getElementById('fr_pattern').focus();
-					break;
-				case 27:
-					return onCancel();
-			}
-			return true;
-		};
-		// -->
-		/*]]>*/
-	</script>
-</head>
-<body class="popupwin htmlarea-find-replace" onload="Init();">
-<div id="content">
-<div class="title">Find and Replace</div>
-<form action="" method="get">
-	<fieldset>
-		<div>
-			<label for="fr_pattern">Search for:</label><br />
-			<input id="fr_pattern" type="text" size="35" onFocus="this.select();">
-		</div>
-		<div>
-			<label for="fr_replacement">Replace with:</label><br />
-			<input id="fr_replacement" type="text" size="35" onFocus="this.select();">
-		</div>
-	</fieldset>
-	<fieldset>
-		<legend>Options</legend>
-		<div>
-				<input id="fr_words" type="checkbox" checked="checked" onClick="clearDoc();">
-				<label for="fr_words" class="long-label">Whole words only</label>
-		</div>
-		<div>
-				<input id="fr_matchcase" type="checkbox" onClick="clearDoc();">
-				<label for="fr_matchcase" class="long-label">Case sensitive search</label>
-		</div>
-		<div>
-				<input id="fr_replaceall" type="checkbox" onClick="requestReplacement();">
-				<label for="fr_replaceall" class="long-label">Substitute all occurrences</label>
-		</div>
-	</fieldset>
-	<fieldset>
-		<legend>Actions</legend>
-		<div>
-				<button type="button" class="long-button" id="fr_clear" onClick="clearMarks();">Clear</button>
-		</div>
-		<div>
-				<button type="button" class="long-button" id="fr_hiliteall" onClick="hiliteAll();">Highlight</button>
-		</div>
-		<div>
-				<button type="button" class="long-button" id="fr_undo" onClick="resetContents();">Undo</button>
-		</div>
-	</fieldset>
-	<div class="buttons">
-		<button type="button" id="fr_go" onclick="return onOK();">Next</button>
-		<button type="button" name="cancel" onclick="return onCancel();">Done</button>
-	</div>
-</form>
-</div>
-</body>
-</html>
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/UndoRedo/undo-redo.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/UndoRedo/undo-redo.js	(révision 7091)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/UndoRedo/undo-redo.js	(copie de travail)
@@ -32,16 +32,13 @@
  * TYPO3 SVN ID: $Id$
  */
 UndoRedo = HTMLArea.Plugin.extend({
-	
-	constructor : function (editor, pluginName) {
+	constructor: function (editor, pluginName) {
 		this.base(editor, pluginName);
 	},
-	
 	/*
 	 * This function gets called by the class constructor
 	 */
-	configurePlugin : function (editor) {
-		
+	configurePlugin: function (editor) {
 		this.pageTSconfiguration = this.editorConfiguration.buttons.undo;
 		this.customUndo = true;
 		this.undoQueue = new Array();
@@ -50,21 +47,19 @@
 		this.undoSteps = 25;
 			// The time interval at which undo samples are taken: 1/2 sec.
 		this.undoTimeout = 500;
-		
 		/*
 		 * Registering plugin "About" information
 		 */
 		var pluginInformation = {
-			version		: "1.1",
-			developer	: "Stanislas Rolland",
-			developerUrl	: "http://www.sjbr.ca",
-			copyrightOwner	: "Stanislas Rolland",
-			sponsor		: "SJBR",
-			sponsorUrl	: "http://www.sjbr.ca",
-			license		: "GPL"
+			version		: '2.0',
+			developer	: 'Stanislas Rolland',
+			developerUrl	: 'http://www.sjbr.ca',
+			copyrightOwner	: 'Stanislas Rolland',
+			sponsor		: 'SJBR',
+			sponsorUrl	: 'http://www.sjbr.ca',
+			license		: 'GPL'
 		};
 		this.registerPluginInformation(pluginInformation);
-		
 		/*
 		 * Registering the buttons
 		 */
@@ -75,42 +70,55 @@
 			var buttonConfiguration = {
 				id		: buttonId,
 				tooltip		: this.localize(buttonId.toLowerCase()),
-				action		: "onButtonPress",
+				action		: 'onButtonPress',
 				hotKey		: (this.editorConfiguration.buttons[buttonId.toLowerCase()]?this.editorConfiguration.buttons[buttonId.toLowerCase()].hotKey:button[2]),
 				noAutoUpdate	: true
 			};
 			this.registerButton(buttonConfiguration);
 		}
-		
 		return true;
 	},
-	
 	/*
 	 * The list of buttons added by this plugin
 	 */
-	buttonList : [
-		["Undo", null, "z"],
-		["Redo", null, "y"]
+	buttonList: [
+		['Undo', null, 'z'],
+		['Redo', null, 'y']
 	],
-	
 	/*
 	 * This function gets called when the editor is generated
 	 */
 	onGenerate: function () {
 			// Start undo snapshots
 		if (this.customUndo) {
-			Ext.TaskMgr.start({
+			this.task = {
 				run: this.takeSnapshot,
 				scope: this,
 				interval: this.undoTimeout
-			});
+			};
+			this.start();
 		}
 	},
-	
 	/*
+	 * Start the undo/redo snapshot task
+	 */
+	start: function () {
+		if (this.customUndo) {
+			Ext.TaskMgr.start(this.task);
+		}
+	},
+	/*
+	 * Start the undo/redo snapshot task
+	 */
+	stop: function () {
+		if (this.customUndo) {
+			Ext.TaskMgr.stop(this.task);
+		}
+	},
+	/*
 	 * Take a snapshot of the current contents for undo
 	 */
-	takeSnapshot : function () {
+	takeSnapshot: function () {
 		var currentTime = (new Date()).getTime();
 		var newSnapshot = false;
 		if (this.undoPosition >= this.undoSteps) {
@@ -146,7 +154,6 @@
 			}
 		}
 	},
-
 	/*
 	 * Build the snapshot entry
 	 *
@@ -155,17 +162,17 @@
 	 *				- bookmark (the bookmark),
 	 *				- bookmarkedText (the content of the RTE including the bookmark)
 	 */
-	buildSnapshot : function () {
+	buildSnapshot: function () {
 		var bookmark = null, bookmarkedText = null;
 			// Insert a bookmark
-		if (this.editor.getMode() == "wysiwyg" && this.editor.isEditable()) {
+		if (this.editor.getMode() == 'wysiwyg' && this.editor.isEditable()) {
 			var selection = this.editor._getSelection();
-			if ((HTMLArea.is_gecko && !HTMLArea.is_opera9) || (HTMLArea.is_ie && selection.type.toLowerCase() != "control")) {
+			if ((HTMLArea.is_gecko && !HTMLArea.is_opera9) || (HTMLArea.is_ie && selection.type.toLowerCase() != 'control')) {
 					// Catch error in FF when the selection contains no usable range
 				try {
 						// Work around IE8 bug: can't create a range correctly if the selection is empty and the focus is not on the editor window
 						// But we cannot grab focus from an opened window just for the sake of taking this bookmark
-					if (!HTMLArea.is_ie || !this.editor.hasOpenedWindow() || selection.type.toLowerCase() != "none") {
+					if (!HTMLArea.is_ie || !this.editor.hasOpenedWindow() || selection.type.toLowerCase() != 'none') {
 						bookmark = this.editor.getBookmark(this.editor._createRange(selection));
 					}
 				} catch (e) {
@@ -189,11 +196,10 @@
 			bookmarkedText	: bookmarkedText
 		};
 	},
-	
 	/*
 	 * Execute the undo request
 	 */
-	undo : function () {
+	undo: function () {
 		if (this.undoPosition > 0) {
 				// Make sure we would not loose any changes
 			this.takeSnapshot();
@@ -201,11 +207,10 @@
 			this.updateButtonsState();
 		}
 	},
-	
 	/*
 	 * Execute the redo request
 	 */
-	redo : function () {
+	redo: function () {
 		if (this.undoPosition < this.undoQueue.length - 1) {
 				// Make sure we would not loose any changes
 			this.takeSnapshot();
@@ -216,11 +221,10 @@
 			}
 		}
 	},
-	
 	/*
 	 * Set content using undo queue position
 	 */
-	setContent : function (undoPosition) {
+	setContent: function (undoPosition) {
 		var bookmark = this.undoQueue[undoPosition].bookmark;
 		if (bookmark) {
 			this.editor.setHTML(this.undoQueue[undoPosition].bookmarkedText);
@@ -231,7 +235,6 @@
 			this.editor.setHTML(this.undoQueue[undoPosition].text);
 		}
 	},
-	
 	/*
 	 * This function gets called when the toolbar is updated
 	 */
@@ -257,7 +260,6 @@
 			button.setDisabled(!button.textMode);
 		}
 	},
-	
 	/*
 	 * Update the state of the undo/redo buttons
 	 */
@@ -278,7 +280,6 @@
 			this.onUpdateToolbar(button, mode, selectionEmpty, ancestors)
 		}
 	},
-	
 	/*
 	 * This function gets called when the button was pressed.
 	 *
@@ -287,7 +288,7 @@
 	 *
 	 * @return	boolean		false if action is completed
 	 */
-	onButtonPress : function (editor, id) {
+	onButtonPress: function (editor, id) {
 			// Could be a button or its hotkey
 		var buttonId = this.translateHotKey(id);
 		buttonId = buttonId ? buttonId : id;
Index: typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css	(révision 7091)
+++ typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css	(copie de travail)
@@ -240,15 +240,14 @@
 }
 .htmlarea-window .x-form-item-label {
 	text-align: right;
-	vertical-align: middle;
-	padding: 4px 5px 0 5px;
+	padding: 3px 5px 0 5px;
 }
 .htmlarea-window .x-btn-text {
 	font-weight: normal;
 	color: #000000;
 }
-.htmlarea-window .x-form-check-wrap input {
-	vertical-align: middle;
+.htmlarea-window .x-form-check-wrap {
+	padding-top: 3px;
 }
 .htmlarea-window .show-color {
 	margin-top: 10px;
@@ -463,11 +462,6 @@
 	height: 20px;
 	vertical-align: middle;
 }
-/* Selectors for the FindReplace dialogue */
-.htmlarea-find-replace .long-label {
-	text-align:left;
-	width:30em;
-}
 /* Selectors for the CharacterMap dialogue */
 .htmlarea-window .character-map .character {
 	display: block;
Index: typo3/sysext/t3skin/rtehtmlarea/htmlarea.css
===================================================================
--- typo3/sysext/t3skin/rtehtmlarea/htmlarea.css	(révision 7091)
+++ typo3/sysext/t3skin/rtehtmlarea/htmlarea.css	(copie de travail)
@@ -246,15 +246,14 @@
 }
 .htmlarea-window .x-form-item-label {
 	text-align: right;
-	vertical-align: middle;
-	padding: 4px 5px 0 5px;
+	padding: 3px 5px 0 5px;
 }
 .htmlarea-window .x-btn-text {
 	font-weight: normal;
 	color: #000000;
 }
-.htmlarea-window .x-form-check-wrap input {
-	vertical-align: middle;
+.htmlarea-window .x-form-check-wrap {
+	padding-top: 3px;
 }
 .htmlarea-window .show-color {
 	margin-top: 10px;
@@ -470,11 +469,6 @@
 	height: 20px;
 	vertical-align: middle;
 }
-/* Selectors for the FindReplace dialogue */
-.htmlarea-find-replace .long-label {
-	text-align:left;
-	width:30em;
-}
 /* Selectors for the CharacterMap dialogue */
 .htmlarea-window .character-map .character {
 	display: block;
