Project

General

Profile

Feature #22257 » rtehtmlarea_feature_13785.patch

Administrator Admin, 2010-03-10 04:37

View differences:

typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/find-replace.js (copie de travail)
* 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();
}
});
typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/fr_engine.js (copie de travail)
/*---------------------------------------*\
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;
}
};
typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/locallang.xml (copie de travail)
<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>
typo3/sysext/rtehtmlarea/htmlarea/plugins/FindReplace/popups/find_replace.html (copie de travail)
<!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>
typo3/sysext/rtehtmlarea/htmlarea/plugins/UndoRedo/undo-redo.js (copie de travail)
* 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();
......
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
*/
......
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) {
......
}
}
},
/*
* Build the snapshot entry
*
......
* - 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) {
......
bookmarkedText : bookmarkedText
};
},
/*
* Execute the undo request
*/
undo : function () {
undo: function () {
if (this.undoPosition > 0) {
// Make sure we would not loose any changes
this.takeSnapshot();
......
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();
......
}
}
},
/*
* 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);
......
this.editor.setHTML(this.undoQueue[undoPosition].text);
}
},
/*
* This function gets called when the toolbar is updated
*/
......
button.setDisabled(!button.textMode);
}
},
/*
* Update the state of the undo/redo buttons
*/
......
this.onUpdateToolbar(button, mode, selectionEmpty, ancestors)
}
},
/*
* This function gets called when the button was pressed.
*
......
*
* @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;
typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css (copie de travail)
}
.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;
......
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;
typo3/sysext/t3skin/rtehtmlarea/htmlarea.css (copie de travail)
}
.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;
......
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;
(1-1/2)