Index: typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js (révision 7101)
+++ typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js (copie de travail)
@@ -1405,6 +1405,424 @@
}
});
Ext.reg('htmlareaiframe', HTMLArea.Iframe);
+/*!
+ * Ext JS Library 3.1.1
+ * Copyright(c) 2006-2010 Ext JS, LLC
+ * licensing@extjs.com
+ * http://www.extjs.com/license
+ */
+/**
+ * @class Ext.ux.StatusBar
+ *
Basic status bar component that can be used as the bottom toolbar of any {@link Ext.Panel}. In addition to
+ * supporting the standard {@link Ext.Toolbar} interface for adding buttons, menus and other items, the StatusBar
+ * provides a greedy status element that can be aligned to either side and has convenient methods for setting the
+ * status text and icon. You can also indicate that something is processing using the {@link #showBusy} method.
+ *
+new Ext.Panel({
+ title: 'StatusBar',
+ // etc.
+ bbar: new Ext.ux.StatusBar({
+ id: 'my-status',
+
+ // defaults to use when the status is cleared:
+ defaultText: 'Default status text',
+ defaultIconCls: 'default-icon',
+
+ // values to set initially:
+ text: 'Ready',
+ iconCls: 'ready-icon',
+
+ // any standard Toolbar items:
+ items: [{
+ text: 'A Button'
+ }, '-', 'Plain Text']
+ })
+});
+
+// Update the status bar later in code:
+var sb = Ext.getCmp('my-status');
+sb.setStatus({
+ text: 'OK',
+ iconCls: 'ok-icon',
+ clear: true // auto-clear after a set interval
+});
+
+// Set the status bar to show that something is processing:
+sb.showBusy();
+
+// processing....
+
+sb.clearStatus(); // once completeed
+
+ * @extends Ext.Toolbar
+ * @constructor
+ * Creates a new StatusBar
+ * @param {Object/Array} config A config object
+ */
+Ext.ux.StatusBar = Ext.extend(Ext.Toolbar, {
+ /**
+ * @cfg {String} statusAlign
+ * The alignment of the status element within the overall StatusBar layout. When the StatusBar is rendered,
+ * it creates an internal div containing the status text and icon. Any additional Toolbar items added in the
+ * StatusBar's {@link #items} config, or added via {@link #add} or any of the supported add* methods, will be
+ * rendered, in added order, to the opposite side. The status element is greedy, so it will automatically
+ * expand to take up all sapce left over by any other items. Example usage:
+ *
+// Create a left-aligned status bar containing a button,
+// separator and text item that will be right-aligned (default):
+new Ext.Panel({
+ title: 'StatusBar',
+ // etc.
+ bbar: new Ext.ux.StatusBar({
+ defaultText: 'Default status text',
+ id: 'status-id',
+ items: [{
+ text: 'A Button'
+ }, '-', 'Plain Text']
+ })
+});
+
+// By adding the statusAlign config, this will create the
+// exact same toolbar, except the status and toolbar item
+// layout will be reversed from the previous example:
+new Ext.Panel({
+ title: 'StatusBar',
+ // etc.
+ bbar: new Ext.ux.StatusBar({
+ defaultText: 'Default status text',
+ id: 'status-id',
+ statusAlign: 'right',
+ items: [{
+ text: 'A Button'
+ }, '-', 'Plain Text']
+ })
+});
+
+ */
+ /**
+ * @cfg {String} defaultText
+ * The default {@link #text} value. This will be used anytime the status bar is cleared with the
+ * useDefaults:true option (defaults to '').
+ */
+ /**
+ * @cfg {String} defaultIconCls
+ * The default {@link #iconCls} value (see the iconCls docs for additional details about customizing the icon).
+ * This will be used anytime the status bar is cleared with the useDefaults:true option (defaults to '').
+ */
+ /**
+ * @cfg {String} text
+ * A string that will be initially set as the status message. This string
+ * will be set as innerHTML (html tags are accepted) for the toolbar item.
+ * If not specified, the value set for {@link #defaultText}
+ * will be used.
+ */
+ /**
+ * @cfg {String} iconCls
+ * A CSS class that will be initially set as the status bar icon and is
+ * expected to provide a background image (defaults to '').
+ * Example usage:
+// Example CSS rule:
+.x-statusbar .x-status-custom {
+ padding-left: 25px;
+ background: transparent url(images/custom-icon.gif) no-repeat 3px 2px;
+}
+
+// Setting a default icon:
+var sb = new Ext.ux.StatusBar({
+ defaultIconCls: 'x-status-custom'
+});
+
+// Changing the icon:
+sb.setStatus({
+ text: 'New status',
+ iconCls: 'x-status-custom'
+});
+
+ */
+
+ /**
+ * @cfg {String} cls
+ * The base class applied to the containing element for this component on render (defaults to 'x-statusbar')
+ */
+ cls : 'x-statusbar',
+ /**
+ * @cfg {String} busyIconCls
+ * The default {@link #iconCls}
applied when calling
+ * {@link #showBusy}
(defaults to 'x-status-busy' ).
+ * It can be overridden at any time by passing the iconCls
+ * argument into {@link #showBusy}
.
+ */
+ busyIconCls : 'x-status-busy',
+ /**
+ * @cfg {String} busyText
+ * The default {@link #text}
applied when calling
+ * {@link #showBusy}
(defaults to 'Loading...' ).
+ * It can be overridden at any time by passing the text
+ * argument into {@link #showBusy}
.
+ */
+ busyText : 'Loading...',
+ /**
+ * @cfg {Number} autoClear
+ * The number of milliseconds to wait after setting the status via
+ * {@link #setStatus}
before automatically clearing the status
+ * text and icon (defaults to 5000 ). Note that this only applies
+ * when passing the clear argument to {@link #setStatus}
+ * since that is the only way to defer clearing the status. This can
+ * be overridden by specifying a different wait value in
+ * {@link #setStatus}
. Calls to {@link #clearStatus}
+ * always clear the status bar immediately and ignore this value.
+ */
+ autoClear : 5000,
+
+ /**
+ * @cfg {String} emptyText
+ * The text string to use if no text has been set. Defaults to
+ * ' ' ). If there are no other items in the toolbar using
+ * an empty string ('' ) for this value would end up in the toolbar
+ * height collapsing since the empty string will not maintain the toolbar
+ * height. Use '' if the toolbar should collapse in height
+ * vertically when no text is specified and there are no other items in
+ * the toolbar.
+ */
+ emptyText : ' ',
+
+ // private
+ activeThreadId : 0,
+
+ // private
+ initComponent : function(){
+ if(this.statusAlign=='right'){
+ this.cls += ' x-status-right';
+ }
+ Ext.ux.StatusBar.superclass.initComponent.call(this);
+ },
+
+ // private
+ afterRender : function(){
+ Ext.ux.StatusBar.superclass.afterRender.call(this);
+
+ var right = this.statusAlign == 'right';
+ this.currIconCls = this.iconCls || this.defaultIconCls;
+ this.statusEl = new Ext.Toolbar.TextItem({
+ cls: 'x-status-text ' + (this.currIconCls || ''),
+ text: this.text || this.defaultText || ''
+ });
+
+ if(right){
+ this.add('->');
+ this.add(this.statusEl);
+ }else{
+ this.insert(0, this.statusEl);
+ this.insert(1, '->');
+ }
+ this.doLayout();
+ },
+
+ /**
+ * Sets the status {@link #text} and/or {@link #iconCls}. Also supports automatically clearing the
+ * status that was set after a specified interval.
+ * @param {Object/String} config A config object specifying what status to set, or a string assumed
+ * to be the status text (and all other options are defaulted as explained below). A config
+ * object containing any or all of the following properties can be passed:
+ * text {String} : (optional) The status text to display. If not specified, any current
+ * status text will remain unchanged.
+ * iconCls {String} : (optional) The CSS class used to customize the status icon (see
+ * {@link #iconCls} for details). If not specified, any current iconCls will remain unchanged.
+ * clear {Boolean/Number/Object} : (optional) Allows you to set an internal callback that will
+ * automatically clear the status text and iconCls after a specified amount of time has passed. If clear is not
+ * specified, the new status will not be auto-cleared and will stay until updated again or cleared using
+ * {@link #clearStatus}. If true is passed, the status will be cleared using {@link #autoClear},
+ * {@link #defaultText} and {@link #defaultIconCls} via a fade out animation. If a numeric value is passed,
+ * it will be used as the callback interval (in milliseconds), overriding the {@link #autoClear} value.
+ * All other options will be defaulted as with the boolean option. To customize any other options,
+ * you can pass an object in the format:
+ * wait {Number} : (optional) The number of milliseconds to wait before clearing
+ * (defaults to {@link #autoClear}).
+ * anim {Number} : (optional) False to clear the status immediately once the callback
+ * executes (defaults to true which fades the status out).
+ * useDefaults {Number} : (optional) False to completely clear the status text and iconCls
+ * (defaults to true which uses {@link #defaultText} and {@link #defaultIconCls}).
+ *
+ * Example usage:
+// Simple call to update the text
+statusBar.setStatus('New status');
+
+// Set the status and icon, auto-clearing with default options:
+statusBar.setStatus({
+ text: 'New status',
+ iconCls: 'x-status-custom',
+ clear: true
+});
+
+// Auto-clear with custom options:
+statusBar.setStatus({
+ text: 'New status',
+ iconCls: 'x-status-custom',
+ clear: {
+ wait: 8000,
+ anim: false,
+ useDefaults: false
+ }
+});
+
+ * @return {Ext.ux.StatusBar} this
+ */
+ setStatus : function(o){
+ o = o || {};
+
+ if(typeof o == 'string'){
+ o = {text:o};
+ }
+ if(o.text !== undefined){
+ this.setText(o.text);
+ }
+ if(o.iconCls !== undefined){
+ this.setIcon(o.iconCls);
+ }
+
+ if(o.clear){
+ var c = o.clear,
+ wait = this.autoClear,
+ defaults = {useDefaults: true, anim: true};
+
+ if(typeof c == 'object'){
+ c = Ext.applyIf(c, defaults);
+ if(c.wait){
+ wait = c.wait;
+ }
+ }else if(typeof c == 'number'){
+ wait = c;
+ c = defaults;
+ }else if(typeof c == 'boolean'){
+ c = defaults;
+ }
+
+ c.threadId = this.activeThreadId;
+ this.clearStatus.defer(wait, this, [c]);
+ }
+ return this;
+ },
+
+ /**
+ * Clears the status {@link #text} and {@link #iconCls}. Also supports clearing via an optional fade out animation.
+ * @param {Object} config (optional) A config object containing any or all of the following properties. If this
+ * object is not specified the status will be cleared using the defaults below:
+ * anim {Boolean} : (optional) True to clear the status by fading out the status element (defaults
+ * to false which clears immediately).
+ * useDefaults {Boolean} : (optional) True to reset the text and icon using {@link #defaultText} and
+ * {@link #defaultIconCls} (defaults to false which sets the text to '' and removes any existing icon class).
+ *
+ * @return {Ext.ux.StatusBar} this
+ */
+ clearStatus : function(o){
+ o = o || {};
+
+ if(o.threadId && o.threadId !== this.activeThreadId){
+ // this means the current call was made internally, but a newer
+ // thread has set a message since this call was deferred. Since
+ // we don't want to overwrite a newer message just ignore.
+ return this;
+ }
+
+ var text = o.useDefaults ? this.defaultText : this.emptyText,
+ iconCls = o.useDefaults ? (this.defaultIconCls ? this.defaultIconCls : '') : '';
+
+ if(o.anim){
+ // animate the statusEl Ext.Element
+ this.statusEl.el.fadeOut({
+ remove: false,
+ useDisplay: true,
+ scope: this,
+ callback: function(){
+ this.setStatus({
+ text: text,
+ iconCls: iconCls
+ });
+
+ this.statusEl.el.show();
+ }
+ });
+ }else{
+ // hide/show the el to avoid jumpy text or icon
+ this.statusEl.hide();
+ this.setStatus({
+ text: text,
+ iconCls: iconCls
+ });
+ this.statusEl.show();
+ }
+ return this;
+ },
+
+ /**
+ * Convenience method for setting the status text directly. For more flexible options see {@link #setStatus}.
+ * @param {String} text (optional) The text to set (defaults to '')
+ * @return {Ext.ux.StatusBar} this
+ */
+ setText : function(text){
+ this.activeThreadId++;
+ this.text = text || '';
+ if(this.rendered){
+ this.statusEl.setText(this.text);
+ }
+ return this;
+ },
+
+ /**
+ * Returns the current status text.
+ * @return {String} The status text
+ */
+ getText : function(){
+ return this.text;
+ },
+
+ /**
+ * Convenience method for setting the status icon directly. For more flexible options see {@link #setStatus}.
+ * See {@link #iconCls} for complete details about customizing the icon.
+ * @param {String} iconCls (optional) The icon class to set (defaults to '', and any current icon class is removed)
+ * @return {Ext.ux.StatusBar} this
+ */
+ setIcon : function(cls){
+ this.activeThreadId++;
+ cls = cls || '';
+
+ if(this.rendered){
+ if(this.currIconCls){
+ this.statusEl.removeClass(this.currIconCls);
+ this.currIconCls = null;
+ }
+ if(cls.length > 0){
+ this.statusEl.addClass(cls);
+ this.currIconCls = cls;
+ }
+ }else{
+ this.currIconCls = cls;
+ }
+ return this;
+ },
+
+ /**
+ * Convenience method for setting the status text and icon to special values that are pre-configured to indicate
+ * a "busy" state, usually for loading or processing activities.
+ * @param {Object/String} config (optional) A config object in the same format supported by {@link #setStatus}, or a
+ * string to use as the status text (in which case all other options for setStatus will be defaulted). Use the
+ * text and/or iconCls properties on the config to override the default {@link #busyText}
+ * and {@link #busyIconCls} settings. If the config argument is not specified, {@link #busyText} and
+ * {@link #busyIconCls} will be used in conjunction with all of the default options for {@link #setStatus}.
+ * @return {Ext.ux.StatusBar} this
+ */
+ showBusy : function(o){
+ if(typeof o == 'string'){
+ o = {text:o};
+ }
+ o = Ext.applyIf(o || {}, {
+ text: this.busyText,
+ iconCls: this.busyIconCls
+ });
+ return this.setStatus(o);
+ }
+});
+Ext.reg('statusbar', Ext.ux.StatusBar);
/*
* HTMLArea.StatusBar extends Ext.Container
*/
@@ -4006,6 +4424,7 @@
* Dialogue window onClose handler
*/
onClose: function () {
+ this.editor.focus();
this.restoreSelection();
this.editor.updateToolbar();
},
@@ -4014,6 +4433,7 @@
*/
onCancel: function () {
this.dialog.close();
+ this.editor.focus();
},
/*
* Save selection
Index: typo3/sysext/rtehtmlarea/htmlarea/locallang_dialogs.xml
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/locallang_dialogs.xml (révision 7101)
+++ typo3/sysext/rtehtmlarea/htmlarea/locallang_dialogs.xml (copie de travail)
@@ -112,6 +112,7 @@
No language
Remove language
Style
+ Ready
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/locallang.xml
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/locallang.xml (révision 7101)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/locallang.xml (copie de travail)
@@ -23,6 +23,7 @@
HTMLArea Spell Checker
This will drop changes and quit spell checker. Please confirm.
Re-check
+ Replacement
Replace all
Replace with
Replace
@@ -36,6 +37,7 @@
of the word
was found.
were found.
+ Info
Document information
No information available
Total words
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/popups/spell-check-ui-iso-8859-1.html
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/popups/spell-check-ui-iso-8859-1.html (révision 7101)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/popups/spell-check-ui-iso-8859-1.html (copie de travail)
@@ -1,101 +0,0 @@
-
-
-
-
-
- Spell Checker
-
-
-
-
-
-
-
Spell Checker
-
- Dictionary
-
- Re-check
-
-
Please wait. Calling spell checker.
-
-
Original word
-
pliz weit ;-)
-
- Revert
-
-
Replace with
-
-
- Replace
- Replace all
- Ignore
- Ignore all
- Learn
-
-
Suggestions
-
-
-
-
- Info
-
-
-
-
-
-
-
-
- OK
- Cancel
-
-
-
-
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/popups/spell-check-ui.html
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/popups/spell-check-ui.html (révision 7101)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/popups/spell-check-ui.html (copie de travail)
@@ -1,101 +0,0 @@
-
-
-
-
-
- Spell Checker
-
-
-
-
-
-
-
Spell Checker
-
- Dictionary
-
- Re-check
-
-
Please wait. Calling spell checker.
-
-
Original word
-
pliz weit ;-)
-
- Revert
-
-
Replace with
-
-
- Replace
- Replace all
- Ignore
- Ignore all
- Learn
-
-
Suggestions
-
-
-
-
- Info
-
-
-
-
-
-
-
-
- OK
- Cancel
-
-
-
-
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-check-style.css
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-check-style.css (révision 7101)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-check-style.css (copie de travail)
@@ -1,11 +1,29 @@
-html, body { background-color: white; color: black; }
-
-.HA-spellcheck-error { border-bottom: 1px dashed #f00; cursor: default; }
-.HA-spellcheck-same { background-color: #cef; color: #000; }
-.HA-spellcheck-hover { background-color: #433; color: white; }
-.HA-spellcheck-fixed { border-bottom: 1px dashed #0b8; }
-.HA-spellcheck-current { background-color: #9be; color: #000; }
-.HA-spellcheck-suggestions { display: none; }
-
-#HA-spellcheck-dictionaries { display: none; }
-a:link, a:visited { color: #55e; }
+body {
+ background-color: white;
+ color: black;
+ padding: 3px;
+ margin: 0;
+}
+.htmlarea-spellcheck-error {
+ border-bottom: 1px dashed #f00;
+ cursor: default;
+}
+.htmlarea-spellcheck-same {
+ background-color: #cef;
+ color: #000;
+}
+.htmlarea-spellcheck-hover {
+ background-color: #433;
+ color: white;
+ cursor: pointer;
+}
+.htmlarea-spellcheck-fixed {
+ border-bottom: 1px dashed #0b8;
+}
+.htmlarea-spellcheck-current {
+ background-color: #9be;
+ color: #000;
+}
+a:link, a:visited {
+ color: #55e;
+}
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-check-ui.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-check-ui.js (révision 7101)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-check-ui.js (copie de travail)
@@ -1,429 +0,0 @@
-/***************************************************************
-* Copyright notice
-*
-* (c) 2003 dynarch.com. Authored by Mihai Bazon, sponsored by www.americanbible.org.
-* (c) 2004-2009 Stanislas Rolland
-* 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!
-***************************************************************/
-/*
- * Spell Checker Plugin for TYPO3 htmlArea RTE
- *
- * TYPO3 SVN ID: $Id$
- */
-var dialog = window.opener.HTMLArea.Dialog.SpellChecker;
-var frame = null;
-var currentElement = null;
-var wrongWords = null;
-var modified = false;
-var allWords = {};
-var fixedWords = [];
-var suggested_words = {};
-
-var to_p_dict = []; // List of words to add to personal dictionary
-var to_r_list = []; // List of words to add to replacement list
-
-function makeCleanDoc(leaveFixed) {
- // document.getElementById("status").innerHTML = 'Please wait: rendering valid HTML';
- var words = wrongWords.concat(fixedWords);
- for (var i = words.length; --i >= 0;) {
- var el = words[i];
- if (!(leaveFixed && /HA-spellcheck-fixed/.test(el.className))) {
- el.parentNode.insertBefore(el.firstChild, el);
- el.parentNode.removeChild(el);
- } else
- el.className = "HA-spellcheck-fixed";
- }
- return window.opener.HTMLArea.getHTML(frame.contentWindow.document.body, false, dialog.plugin.editor);
-};
-
-function recheckClicked() {
- document.getElementById("status").innerHTML = dialog.plugin.localize("Please wait: changing dictionary to") + ': "' + document.getElementById("f_dictionary").value + '".';
- var field = document.getElementById("f_content");
- field.value = makeCleanDoc(true);
- field.form.submit();
-};
-
-function saveClicked() {
- if (modified) {
- dialog.plugin.editor.setHTML(makeCleanDoc(false));
- }
- if ((to_p_dict.length || to_r_list.length) && dialog.plugin.enablePersonalDicts) {
- var data = {};
- for (var i = 0;i < to_p_dict.length;i++) {
- data['to_p_dict[' + i + ']'] = to_p_dict[i];
- }
- for (var i = 0;i < to_r_list.length;i++) {
- data['to_r_list[' + i + '][0]'] = to_r_list[i][0];
- data['to_r_list[' + i + '][1]'] = to_r_list[i][1];
- }
- data['cmd'] = 'learn';
- data['enablePersonalDicts'] = dialog.plugin.enablePersonalDicts;
- data['userUid'] = dialog.plugin.userUid;
- data['dictionary'] = dialog.plugin.contentISOLanguage;
- data['pspell_charset'] = dialog.plugin.contentCharset;
- data['pspell_mode'] = dialog.plugin.spellCheckerMode;
- window.opener.HTMLArea._postback(dialog.plugin.pageTSconfiguration.path, data);
- }
- window.close();
- return false;
-};
-
-function cancelClicked() {
- var ok = true;
- if (modified) {
- ok = confirm(dialog.plugin.localize("QUIT_CONFIRMATION"));
- }
- if (ok) {
- dialog.close();
- }
- return false;
-};
-
-function replaceWord(el) {
- var replacement = document.getElementById("v_replacement").value;
- var this_word_modified = (el.innerHTML != replacement);
- if (this_word_modified)
- modified = true;
- if (el) {
- el.className = el.className.replace(/\s*HA-spellcheck-(hover|fixed)\s*/g, " ");
- }
- el.className += " HA-spellcheck-fixed";
- el.__msh_fixed = true;
- if (!this_word_modified) {
- return false;
- }
- to_r_list.push([el.innerHTML, replacement]);
- el.innerHTML = replacement;
-};
-
-function replaceClicked() {
- replaceWord(currentElement);
- var start = currentElement.__msh_id;
- var index = start;
- do {
- ++index;
- if (index == wrongWords.length) index = 0;
- } while((index != start) && wrongWords[index].__msh_fixed);
- if (index == start) {
- index = 0;
- alert(dialog.plugin.localize("Finished list of mispelled words"));
- }
- wrongWords[index].__msh_wordClicked(true);
- return false;
-};
-
-function revertClicked() {
- document.getElementById("v_replacement").value = currentElement.__msh_origWord;
- replaceWord(currentElement);
- currentElement.className = "HA-spellcheck-error HA-spellcheck-current";
- return false;
-};
-
-function replaceAllClicked() {
- var replacement = document.getElementById("v_replacement").value;
- var ok = true;
- var spans = allWords[currentElement.__msh_origWord];
- if (spans.length == 0) {
- alert("An impossible condition just happened. Call FBI. ;-)");
- } else if (spans.length == 1) {
- replaceClicked();
- return false;
- }
- /*
- var message = "The word \"" + currentElement.__msh_origWord + "\" occurs " + spans.length + " times.\n";
- if (replacement == currentElement.__msh_origWord) {
- ok = confirm(message + "Ignore all occurrences?");
- } else {
- ok = confirm(message + "Replace all occurrences with \"" + replacement + "\"?");
- }
- */
- if (ok) {
- for (var i = 0; i < spans.length; ++i) {
- if (spans[i] != currentElement) {
- replaceWord(spans[i]);
- }
- }
- // replace current element the last, so that we jump to the next word ;-)
- replaceClicked();
- }
- return false;
-};
-
-function ignoreClicked() {
- document.getElementById("v_replacement").value = currentElement.__msh_origWord;
- replaceClicked();
- return false;
-};
-
-function ignoreAllClicked() {
- document.getElementById("v_replacement").value = currentElement.__msh_origWord;
- replaceAllClicked();
- return false;
-};
-
-function learnClicked() {
- to_p_dict.push(currentElement.__msh_origWord);
- return ignoreAllClicked();
-};
-
-function initDocument() {
- dialog.initialize();
- var plugin = dialog.plugin;
- var editor = plugin.editor;
-
- modified = false;
- document.title = dialog.plugin.localize("Spell Checker");
- document.getElementById("spellcheck_form").action = plugin.pageTSconfiguration.path;
- frame = document.getElementById("i_framecontent");
- var field = document.getElementById("f_content");
- field.value = HTMLArea.getHTML(editor._doc.body, false, editor);
- document.getElementById("f_init").value = "0";
- document.getElementById("f_dictionary").value = plugin.defaultDictionary ? plugin.defaultDictionary : plugin.contentISOLanguage;
- document.getElementById("f_charset").value = plugin.contentCharset;
- document.getElementById("f_pspell_mode").value = plugin.spellCheckerMode;
- document.getElementById("f_user_uid").value = plugin.userUid;
- document.getElementById("f_personal_dicts").value = plugin.enablePersonalDicts;
- document.getElementById("f_show_dictionaries").value = plugin.showDictionaries;
- document.getElementById("f_restrict_to_dictionaries").value = plugin.restrictToDictionaries;
- field.form.submit();
- // assign some global event handlers
- var select = document.getElementById("v_suggestions");
- select.onchange = function() {
- document.getElementById("v_replacement").value = this.value;
- };
- HTMLArea._addEvent(select, "dblclick", replaceClicked);
-
- document.getElementById("b_replace").onclick = replaceClicked;
- if (plugin.enablePersonalDicts) document.getElementById("b_learn").onclick = learnClicked;
- else document.getElementById("b_learn").style.display = 'none';
- document.getElementById("b_replall").onclick = replaceAllClicked;
- document.getElementById("b_ignore").onclick = ignoreClicked;
- document.getElementById("b_ignall").onclick = ignoreAllClicked;
- document.getElementById("b_recheck").onclick = recheckClicked;
- document.getElementById("b_revert").onclick = revertClicked;
- document.getElementById("b_info").onclick = displayInfo;
-
- document.getElementById("b_ok").onclick = saveClicked;
- document.getElementById("b_cancel").onclick = cancelClicked;
-
- select = document.getElementById("v_dictionaries");
- select.onchange = function() {
- document.getElementById("f_dictionary").value = this.value;
- };
-};
-
-function getAbsolutePos(el) {
- var r = { x: el.offsetLeft, y: el.offsetTop };
- if (el.offsetParent) {
- var tmp = getAbsolutePos(el.offsetParent);
- r.x += tmp.x;
- r.y += tmp.y;
- }
- return r;
-};
-
-function wordClicked(scroll) {
- var self = this;
- if (scroll) (function() {
- var pos = getAbsolutePos(self);
- var ws = { x: frame.offsetWidth - 4,
- y: frame.offsetHeight - 4 };
- var wp = { x: frame.contentWindow.document.body.scrollLeft,
- y: frame.contentWindow.document.body.scrollTop };
- pos.x -= Math.round(ws.x/2);
- if (pos.x < 0) pos.x = 0;
- pos.y -= Math.round(ws.y/2);
- if (pos.y < 0) pos.y = 0;
- frame.contentWindow.scrollTo(pos.x, pos.y);
- })();
- if (currentElement) {
- var a = allWords[currentElement.__msh_origWord];
- currentElement.className = currentElement.className.replace(/\s*HA-spellcheck-current\s*/g, " ");
- for (var i = 0; i < a.length; ++i) {
- var el = a[i];
- if (el != currentElement) {
- el.className = el.className.replace(/\s*HA-spellcheck-same\s*/g, " ");
- }
- }
- }
- currentElement = this;
- this.className += " HA-spellcheck-current";
- var a = allWords[currentElement.__msh_origWord];
- for (var i = 0; i < a.length; ++i) {
- var el = a[i];
- if (el != currentElement) {
- el.className += " HA-spellcheck-same";
- }
- }
- // document.getElementById("b_replall").disabled = (a.length <= 1);
- // document.getElementById("b_ignall").disabled = (a.length <= 1);
- var txt;
- var txt2;
- if (a.length == 1) {
- txt = dialog.plugin.localize("One occurrence");
- txt2 = dialog.plugin.localize("was found.");
- } else if (a.length == 2) {
- txt = dialog.plugin.localize("Two occurrences");
- txt2 = dialog.plugin.localize("were found.");
- } else {
- txt = a.length + " " + dialog.plugin.localize("occurrences");
- txt2 = dialog.plugin.localize("were found.");
- }
- var suggestions = suggested_words[this.__msh_origWord];
- if (suggestions) suggestions = suggestions.split(/,/);
- else suggestions = [];
- var select = document.getElementById("v_suggestions");
- document.getElementById("statusbar").innerHTML = txt + " " + dialog.plugin.localize("of the word") +
- ' "' + currentElement.__msh_origWord + ' "' + " " + txt2;
- for (var i = select.length; --i >= 0;) {
- select.remove(i);
- }
- for (var i = 0; i < suggestions.length; ++i) {
- var txt = suggestions[i];
- var option = document.createElement("option");
- option.value = txt;
- option.appendChild(document.createTextNode(txt));
- select.appendChild(option);
- }
- document.getElementById("v_currentWord").innerHTML = this.__msh_origWord;
- if (suggestions.length > 0) {
- select.selectedIndex = 0;
- select.onchange();
- } else {
- document.getElementById("v_replacement").value = this.innerHTML;
- }
- select.style.display = "none";
- select.style.display = "inline";
- return false;
-};
-
-function wordMouseOver() {
- this.className += " HA-spellcheck-hover";
-};
-
-function wordMouseOut() {
- this.className = this.className.replace(/\s*HA-spellcheck-hover\s*/g, " ");
-};
-
-function displayInfo() {
- var info = frame.contentWindow.spellcheck_info;
- if (!info)
- alert(dialog.plugin.localize("No information available"));
- else {
- var txt = dialog.plugin.localize("Document information") + "\n" ;
- for (var i in info) {
- txt += "\n" + dialog.plugin.localize(i) + " : " + info[i];
- }
- txt += " " + dialog.plugin.localize("seconds");
- alert(txt);
- }
- return false;
-};
-
-function finishedSpellChecking() {
- // initialization of global variables
- currentElement = null;
- wrongWords = null;
- allWords = {};
- fixedWords = [];
- suggested_words = frame.contentWindow.suggested_words;
-
- document.getElementById("status").innerHTML = dialog.plugin.localize("HTMLArea Spell Checker");
- var doc = frame.contentWindow.document;
- var spans = doc.getElementsByTagName("span");
- var sps = [];
- var id = 0;
- for (var i = 0; i < spans.length; ++i) {
- var el = spans[i];
- if (/HA-spellcheck-error/.test(el.className)) {
- sps.push(el);
- el.__msh_wordClicked = wordClicked;
- el.onclick = function(ev) {
- ev || (ev = window.event);
- ev && HTMLArea._stopEvent(ev);
- return this.__msh_wordClicked(false);
- };
- el.onmouseover = wordMouseOver;
- el.onmouseout = wordMouseOut;
- el.__msh_id = id++;
- var txt = (el.__msh_origWord = el.firstChild.data);
- el.__msh_fixed = false;
- if (typeof allWords[txt] == "undefined") {
- allWords[txt] = [el];
- } else {
- allWords[txt].push(el);
- }
- } else if (/HA-spellcheck-fixed/.test(el.className)) {
- fixedWords.push(el);
- }
- }
- wrongWords = sps;
- if (sps.length == 0) {
- if (!modified) {
- alert(dialog.plugin.localize("NO_ERRORS_CLOSING"));
- window.close();
- } else {
- alert(dialog.plugin.localize("NO_ERRORS"));
- }
- return false;
- }
- (currentElement = sps[0]).__msh_wordClicked(true);
- var as = doc.getElementsByTagName("a");
- for (var i = as.length; --i >= 0;) {
- var a = as[i];
- a.onclick = function() {
- if (confirm(dialog.plugin.localize("CONFIRM_LINK_CLICK") + ":\n" +
- this.href + "\n" + dialog.plugin.localize("I will open it in a new page."))) {
- window.open(this.href);
- }
- return false;
- };
- }
- var dicts = doc.getElementById("HA-spellcheck-dictionaries");
- if (dicts) {
- dicts.parentNode.removeChild(dicts);
- dicts = dicts.innerHTML.split(/,/);
- var select = document.getElementById("v_dictionaries");
- for (var i = select.length; --i >= 0;) {
- select.remove(i);
- }
- var selectedOptionIndex = 0;
- for (var i = 0; i < dicts.length; ++i) {
- var txt = dicts[i];
- var option = document.createElement("option");
- if (/^@(.*)$/.test(txt)) {
- txt = RegExp.$1;
- selectedOptionIndex = i;
- if (HTMLArea.is_ie) option.selected = true;
- document.getElementById("f_dictionary").value = txt;
- }
- option.value = txt;
- option.appendChild(document.createTextNode(txt));
- select.appendChild(option);
- }
- select.selectedIndex = selectedOptionIndex;
- }
-};
-
Index: typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-checker.js
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-checker.js (révision 7101)
+++ typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-checker.js (copie de travail)
@@ -33,54 +33,64 @@
* TYPO3 SVN ID: $Id$
*/
SpellChecker = 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.spellcheck;
this.contentISOLanguage = this.pageTSconfiguration.contentISOLanguage;
this.contentCharset = this.pageTSconfiguration.contentCharset;
this.spellCheckerMode = this.pageTSconfiguration.spellCheckerMode;
this.enablePersonalDicts = this.pageTSconfiguration.enablePersonalDicts;
this.userUid = this.editorConfiguration.userUid;
- this.defaultDictionary = (this.pageTSconfiguration.dictionaries && this.pageTSconfiguration.dictionaries[this.contentISOLanguage] && this.pageTSconfiguration.dictionaries[this.contentISOLanguage].defaultValue) ? this.pageTSconfiguration.dictionaries[this.contentISOLanguage].defaultValue : "";
- this.showDictionaries = (this.pageTSconfiguration.dictionaries && this.pageTSconfiguration.dictionaries.items) ? this.pageTSconfiguration.dictionaries.items : "";
- this.restrictToDictionaries = (this.pageTSconfiguration.dictionaries && this.pageTSconfiguration.dictionaries.restrictToItems) ? this.pageTSconfiguration.dictionaries.restrictToItems : "";
-
+ this.defaultDictionary = (this.pageTSconfiguration.dictionaries && this.pageTSconfiguration.dictionaries[this.contentISOLanguage] && this.pageTSconfiguration.dictionaries[this.contentISOLanguage].defaultValue) ? this.pageTSconfiguration.dictionaries[this.contentISOLanguage].defaultValue : '';
+ this.showDictionaries = (this.pageTSconfiguration.dictionaries && this.pageTSconfiguration.dictionaries.items) ? this.pageTSconfiguration.dictionaries.items : '';
+ this.restrictToDictionaries = (this.pageTSconfiguration.dictionaries && this.pageTSconfiguration.dictionaries.restrictToItems) ? this.pageTSconfiguration.dictionaries.restrictToItems : '';
/*
* Registering plugin "About" information
*/
var pluginInformation = {
- version : "2.2",
- developer : "Mihai Bazon & Stanislas Rolland",
- developerUrl : "http://dynarch.com/mishoo/",
- copyrightOwner : "Mihai Bazon & Stanislas Rolland",
- sponsor : "American Bible Society & SJBR",
- sponsorUrl : "http://www.sjbr.ca/",
- license : "GPL"
+ version : '3.0',
+ developer : 'Mihai Bazon & Stanislas Rolland',
+ developerUrl : 'http://www.sjbr.ca/',
+ copyrightOwner : 'Mihai Bazon & Stanislas Rolland',
+ sponsor : 'American Bible Society & SJBR',
+ sponsorUrl : 'http://www.sjbr.ca/',
+ license : 'GPL'
};
this.registerPluginInformation(pluginInformation);
-
/*
* Registering the button
*/
- var buttonId = "SpellCheck";
+ var buttonId = 'SpellCheck';
var buttonConfiguration = {
id : buttonId,
- tooltip : this.localize("SC-spell-check"),
- action : "onButtonPress",
+ tooltip : this.localize('SC-spell-check'),
+ action : 'onButtonPress',
dialog : true
};
this.registerButton(buttonConfiguration);
},
-
/*
+ * Sets of default configuration values for dialogue form fields
+ */
+ configDefaults: {
+ combo: {
+ editable: true,
+ typeAhead: true,
+ triggerAction: 'all',
+ forceSelection: true,
+ mode: 'local',
+ valueField: 'value',
+ displayField: 'text',
+ helpIcon: true,
+ tpl: '{text}
'
+ }
+ },
+ /*
* This function gets called when the button was pressed.
*
* @param object editor: the editor instance
@@ -88,17 +98,701 @@
*
* @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;
- switch (buttonId) {
- case "SpellCheck":
- var charset = (this.contentCharset.toLowerCase() == 'iso-8859-1') ? "-iso-8859-1" : "";
- this.dialog = this.openDialog(buttonId, this.makeUrlFromPopupName("spell-check-ui" + charset), null, null, {width:710, height:600});
- break;
+ // Open dialogue window
+ this.openDialogue(
+ buttonId,
+ 'Spell Checker',
+ this.getWindowDimensions(
+ {
+ width: 710,
+ height: 600
+ },
+ buttonId
+ )
+ );
+ return false;
+ },
+ /*
+ * Open the dialogue window
+ *
+ * @param string buttonId: the button id
+ * @param string title: the window title
+ * @param object dimensions: the opening dimensions of the window
+ *
+ * @return void
+ */
+ openDialogue: function (buttonId, title, dimensions) {
+ this.dialog = new Ext.Window({
+ title: this.localize(title),
+ cls: 'htmlarea-window',
+ bodyCssClass: 'spell-check',
+ 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: {
+ afterrender: {
+ fn: this.onWindowAfterRender,
+ scope: this
+ },
+ resize: {
+ fn: this.onWindowResize
+ },
+ close: {
+ fn: this.onClose,
+ scope: this
+ }
+ },
+ items: [{
+ // The hidden form
+ xtype: 'form',
+ method: 'POST',
+ itemId: 'spell-check-form',
+ url: this.pageTSconfiguration.path,
+ hidden: true,
+ standardSubmit: true,
+ items: [{
+ xtype: 'hidden',
+ name: 'editorId',
+ value: this.editor.editorId
+ },{
+ xtype: 'hidden',
+ itemId: 'content',
+ name: 'content',
+ value: this.editor.getHTML()
+ },{
+ xtype: 'hidden',
+ itemId: 'dictionary',
+ name: 'dictionary',
+ value: this.defaultDictionary ? this.defaultDictionary : this.contentISOLanguage
+ },{
+ xtype: 'hidden',
+ name: 'pspell_charset',
+ value: this.contentCharset
+ },{
+ xtype: 'hidden',
+ name: 'pspell_mode',
+ value: this.spellCheckerMode
+ },{
+ xtype: 'hidden',
+ name: 'userUid',
+ value: this.userUid
+ },{
+ xtype: 'hidden',
+ name:'enablePersonalDicts',
+ value: this.enablePersonalDicts
+ },{
+ xtype: 'hidden',
+ name:'showDictionaries',
+ value: this.showDictionaries
+ },{
+ xtype: 'hidden',
+ name:'restrictToDictionaries',
+ value: this.restrictToDictionaries
+ }
+ ]
+ },{
+ // The iframe
+ xtype: 'box',
+ itemId: 'spell-check-iframe',
+ width: dimensions.width - 225,
+ autoEl: {
+ name: 'contentframe',
+ tag: 'iframe',
+ cls: 'contentframe',
+ src: Ext.isGecko ? 'javascript:void(0);' : (Ext.isOpera ? _typo3_host_url : '') + _editor_url + 'popups/blank.html'
+ }
+ },{
+ // The original word
+ xtype: 'fieldset',
+ title: this.localize('Original word'),
+ cls: 'controls',
+ labelWidth: 0,
+ defaults: {
+ hideLabel: true,
+ disabled: true,
+ minWidth: 160
+ },
+ items: [{
+ xtype: 'textfield',
+ itemId: 'word',
+ disabled: false
+ },
+ this.buildButtonConfig('Revert', this.onRevertClick)
+ ]
+ },{
+ // The replacement word and actions
+ xtype: 'fieldset',
+ title: this.localize('Replacement'),
+ cls: 'controls',
+ defaultType: 'button',
+ labelWidth: 0,
+ defaults: {
+ hideLabel: true,
+ disabled: true,
+ minWidth: 160
+ },
+ items: [{
+ xtype: 'textfield',
+ disabled: false,
+ width: 160,
+ itemId: 'replacement'
+ },{
+ itemId: 'replace',
+ text: this.localize('Replace'),
+ listeners: {
+ click: {
+ fn: this.onReplaceClick,
+ scope: this
+ }
+ }
+ },{
+ itemId: 'replaceAll',
+ text: this.localize('Replace all'),
+ listeners: {
+ click: {
+ fn: this.onReplaceAllClick,
+ scope: this
+ }
+ }
+ },{
+ itemId: 'ignore',
+ text: this.localize('Ignore'),
+ listeners: {
+ click: {
+ fn: this.onIgnoreClick,
+ scope: this
+ }
+ }
+ },{
+ itemId: 'ignoreAll',
+ text: this.localize('Ignore all'),
+ listeners: {
+ click: {
+ fn: this.onIgnoreAllClick,
+ scope: this
+ }
+ }
+ },{
+ itemId: 'learn',
+ text: this.localize('Learn'),
+ hidden: !this.enablePersonalDicts,
+ listeners: {
+ click: {
+ fn: this.onLearnClick,
+ scope: this
+ }
+ }
+ }
+ ]
+ },{
+ // The suggestions
+ xtype: 'fieldset',
+ title: this.localize('Suggestions'),
+ cls: 'controls',
+ labelWidth: 0,
+ defaults: {
+ hideLabel: true,
+ minWidth: 160
+ },
+ items: [
+ Ext.apply({
+ xtype: 'combo',
+ itemId: 'suggestions',
+ store: new Ext.data.ArrayStore({
+ autoDestroy: true,
+ fields: [{name: 'text'}, {name: 'value'}],
+ data: []
+ }),
+ listeners: {
+ select: {
+ fn: this.onSuggestionSelect,
+ scope: this
+ }
+ }
+ }, this.configDefaults['combo'])
+ ]
+ },{
+ // The dictionaries
+ xtype: 'fieldset',
+ title: this.localize('Dictionary'),
+ cls: 'controls',
+ defaultType: 'button',
+ labelWidth: 0,
+ defaults: {
+ hideLabel: true,
+ disabled: true,
+ minWidth: 160
+ },
+ items: [
+ Ext.apply({
+ xtype: 'combo',
+ itemId: 'dictionaries',
+ disabled: false,
+ store: new Ext.data.ArrayStore({
+ autoDestroy: true,
+ fields: [{name: 'text'}, {name: 'value'}],
+ data: []
+ }),
+ listeners: {
+ select: {
+ fn: this.onDictionarySelect,
+ scope: this
+ }
+ }
+ }, this.configDefaults['combo']),
+ {
+ itemId: 'recheck',
+ text: this.localize('Re-check'),
+ listeners: {
+ click: {
+ fn: this.onRecheckClick,
+ scope: this
+ }
+ }
+ }
+ ]
+ }
+ ],
+ bbar: new Ext.ux.StatusBar({
+ id: this.editor.editorId + '-spell-check-status',
+ defaultText: this.localize('statusBarReady'),
+ defaultIconCls: 'status-ready',
+ text: this.localize('Please wait. Calling spell checker.'),
+ iconCls: 'status-wait',
+ defaults: {
+ minWidth: 100,
+ disabled: true
+ },
+ items: [
+ this.buildButtonConfig('OK', this.onOK),
+ this.buildButtonConfig('Info', this.onInfoClick),
+ this.buildButtonConfig('Cancel', this.onCancel)
+ ]
+ })
+ });
+ this.show();
+ },
+ /*
+ * Handler invoked after the window has been rendered
+ */
+ onWindowAfterRender: function () {
+ // True when some word has been modified
+ this.modified = false;
+ // Array of words to add to the personal dictionary
+ this.addToPersonalDictionary = [];
+ // List of word pairs to add to replacement list of the personal dictionary
+ this.addToReplacementList = [];
+ // Initial submit
+ this.dialog.getComponent('spell-check-form').getForm().getEl().set({
+ target: 'contentframe',
+ 'accept-charset': this.contentCharset.toUpperCase()
+ });
+ this.dialog.getComponent('spell-check-form').getForm().submit();
+ },
+ /*
+ * Handler invoked after the window is resized
+ */
+ onWindowResize: function (window, width, height) {
+ var frame = window.getComponent('spell-check-iframe').getEl();
+ if (frame) {
+ frame.setSize(width - 225, height - 75);
}
+ },
+ /*
+ * Handler invoked when the OK button is pressed
+ */
+ onOK: function () {
+ if (this.modified) {
+ this.editor.setHTML(this.cleanDocument(false));
+ }
+ // Post additions to the Aspell personal dictionary
+ if ((this.addToPersonalDictionary.length || this.addToReplacementList.length) && this.enablePersonalDicts) {
+ var data = {
+ cmd: 'learn',
+ enablePersonalDicts: this.enablePersonalDicts,
+ userUid: this.userUid,
+ dictionary: this.contentISOLanguage,
+ pspell_charset: this.contentCharset,
+ pspell_mode: this.spellCheckerMode
+ };
+ Ext.each(this.addToPersonalDictionary, function (word, index) {
+ data['to_p_dict[' + index + ']'] = word;
+ });
+ Ext.each(this.addToReplacementList, function (replacement, index) {
+ data['to_r_list[' + index + '][0]'] = replacement[0];
+ data['to_r_list[' + index + '][1]'] = replacement[1];
+ });
+ HTMLArea._postback(this.pageTSconfiguration.path, data);
+ }
+ this.close();
return false;
+ },
+ /*
+ * Handler invoked when the Cancel button is pressed
+ */
+ onCancel: function () {
+ if (this.modified) {
+ Ext.MessageBox.confirm('', this.localize('QUIT_CONFIRMATION'), function (button) {
+ if (button == 'yes') {
+ this.close();
+ }
+ }, this);
+ return false;
+ } else {
+ return this.base();
+ }
+ },
+ /*
+ * Clean away span elements from the text before leaving or re-submitting
+ *
+ * @param boolean leaveFixed: if true, span elements of corrected words will be left in the text (re-submit case)
+ *
+ * @return string cleaned-up html
+ */
+ cleanDocument: function (leaveFixed) {
+ var iframeDocument = this.dialog.getComponent('spell-check-iframe').getEl().dom.contentWindow.document;
+ Ext.each(this.misspelledWords.concat(this.correctedWords), function (element) {
+ element.onclick = null;
+ element.onmouseover = null;
+ element.onmouseout = null;
+ if (!leaveFixed || !HTMLArea._hasClass(element, 'htmlarea-spellcheck-fixed')) {
+ element.parentNode.insertBefore(element.firstChild, element);
+ element.parentNode.removeChild(element);
+ } else {
+ HTMLArea._removeClass(element, 'htmlarea-spellcheck-error');
+ HTMLArea._removeClass(element, 'htmlarea-spellcheck-same');
+ HTMLArea._removeClass(element, 'htmlarea-spellcheck-current');
+ }
+ }, this);
+ // Cleanup event handlers on links
+ Ext.each(iframeDocument.getElementsByTagName('a'), function (link) {
+ link.onclick = null;
+ }, this);
+ return HTMLArea.getHTML(iframeDocument.body, false, this.editor);
+ },
+ /*
+ * Handler invoked when the response from the server has finished loading
+ */
+ spellCheckComplete: function () {
+ var contentWindow = this.dialog.getComponent('spell-check-iframe').getEl().dom.contentWindow;
+ this.currentElement = null;
+ // Array of misspelled words
+ this.misspelledWords = [];
+ // Array of corrected words
+ this.correctedWords = [];
+ // Object containing array of occurrences of each misspelled word
+ this.allWords = {};
+ // Suggested words
+ this.suggestedWords = contentWindow.suggestedWords;
+ // Set status
+ Ext.getCmp(this.editor.editorId + '-spell-check-status').setStatus({
+ text: this.localize('statusBarReady'),
+ iconCls: 'status-ready',
+ clear: false
+ });
+ // Process all misspelled words
+ var id = 0;
+ var self = this;
+ Ext.each(contentWindow.document.getElementsByTagName('span'), function (span) {
+ if (HTMLArea._hasClass(span, 'htmlarea-spellcheck-error')) {
+ this.misspelledWords.push(span);
+ span.onclick = function (event) { self.setCurrentWord(this, false); };
+ span.onmouseover = function (event) { HTMLArea._addClass(this, 'htmlarea-spellcheck-hover'); };
+ span.onmouseout = function (event) { HTMLArea._removeClass(this, 'htmlarea-spellcheck-hover'); };
+ span.htmlareaId = id++;
+ span.htmlareaOriginalWord = span.firstChild.data;
+ span.htmlareaFixed = false;
+ if (typeof(this.allWords[span.htmlareaOriginalWord]) == 'undefined') {
+ this.allWords[span.htmlareaOriginalWord] = [];
+ }
+ this.allWords[span.htmlareaOriginalWord].push(span);
+ } else if (HTMLArea._hasClass(span, 'htmlarea-spellcheck-fixed')) {
+ this.correctedWords.push(span);
+ }
+ }, this);
+ // Do not open links in the iframe
+ Ext.each(contentWindow.document.getElementsByTagName('a'), function (link) {
+ link.onclick = function (event) { return false; };
+ }, this);
+ // Enable buttons
+ Ext.each(this.dialog.findByType('button'), function (button) {
+ button.setDisabled(false);
+ });
+ Ext.each(Ext.getCmp(this.editor.editorId + '-spell-check-status').findByType('button'), function (button) {
+ button.setDisabled(false);
+ });
+ if (this.misspelledWords.length) {
+ // Set current element to first misspelled word
+ this.currentElement = this.misspelledWords[0];
+ this.setCurrentWord(this.currentElement, true);
+ // Populate the dictionaries combo
+ var dictionaries = contentWindow.dictionaries.split(/,/);
+ if (dictionaries.length) {
+ var select = this.dialog.find('itemId', 'dictionaries')[0];
+ var store = select.getStore();
+ store.removeAll();
+ Ext.each(dictionaries, function (dictionary) {
+ store.add(new store.recordType({
+ text: dictionary,
+ value: dictionary
+ }));
+ });
+ select.setValue(contentWindow.selectedDictionary);
+ var selectedIndex = store.find('value', contentWindow.selectedDictionary);
+ select.fireEvent('select', select, store.getAt(selectedIndex), selectedIndex);
+ }
+ } else {
+ if (!this.modified) {
+ Ext.MessageBox.alert('', this.localize('NO_ERRORS_CLOSING'));
+ this.onOK();
+ } else {
+ Ext.MessageBox.alert('', this.localize('NO_ERRORS'));
+ }
+ return false;
+ }
+ },
+ /*
+ * Get absolute position of an element inside the iframe
+ */
+ getAbsolutePosition: function (element) {
+ var position = {
+ x: element.offsetLeft,
+ y: element.offsetTop
+ };
+ if (element.offsetParent) {
+ var tmp = this.getAbsolutePosition(element.offsetParent);
+ position.x += tmp.x;
+ position.y += tmp.y;
+ }
+ return position;
+ },
+ /*
+ * Update current word
+ */
+ setCurrentWord: function (element, scroll) {
+ // Scroll element into view
+ if (scroll) {
+ var frame = this.dialog.getComponent('spell-check-iframe').getEl().dom;
+ var position = this.getAbsolutePosition(element);
+ var frameSize = {
+ x: frame.offsetWidth - 4,
+ y: frame.offsetHeight - 4
+ };
+ position.x -= Math.round(frameSize.x/2);
+ if (position.x < 0) {
+ position.x = 0;
+ }
+ position.y -= Math.round(frameSize.y/2);
+ if (position.y < 0) {
+ position.y = 0;
+ }
+ frame.contentWindow.scrollTo(position.x, position.y);
+ }
+ // De-highlight all occurrences of current word
+ if (this.currentElement) {
+ HTMLArea._removeClass(this.currentElement, 'htmlarea-spellcheck-current');
+ Ext.each(this.allWords[this.currentElement.htmlareaOriginalWord], function (word) {
+ HTMLArea._removeClass(word, 'htmlarea-spellcheck-same');
+ });
+ }
+ // Highlight all occurrences of new current word
+ this.currentElement = element;
+ HTMLArea._addClass(this.currentElement, 'htmlarea-spellcheck-current');
+ var occurrences = this.allWords[this.currentElement.htmlareaOriginalWord];
+ Ext.each(occurrences, function (word) {
+ if (word != this.currentElement) {
+ HTMLArea._addClass(word, 'htmlarea-spellcheck-same');
+ }
+ }, this);
+ this.dialog.find('itemId', 'replaceAll')[0].setDisabled(occurrences.length <= 1);
+ this.dialog.find('itemId', 'ignoreAll')[0].setDisabled(occurrences.length <= 1);
+ // Display status
+ var txt;
+ var txt2;
+ if (occurrences.length == 1) {
+ txt = this.localize('One occurrence');
+ txt2 = this.localize('was found.');
+ } else if (occurrences.length == 2) {
+ txt = this.localize('Two occurrences');
+ txt2 = this.localize('were found.');
+ } else {
+ txt = occurrences.length + ' ' + this.localize('occurrences');
+ txt2 = this.localize('were found.');
+ }
+ Ext.getCmp(this.editor.editorId + '-spell-check-status').setStatus({
+ text: txt + ' ' + this.localize('of the word') + ' "' + this.currentElement.htmlareaOriginalWord + ' " ' + txt2,
+ iconCls: 'status-info',
+ clear: false
+ });
+ // Update suggestions
+ var suggestions = this.suggestedWords[this.currentElement.htmlareaOriginalWord];
+ if (suggestions) {
+ suggestions = suggestions.split(/,/);
+ } else {
+ suggestions = [];
+ }
+ var select = this.dialog.find('itemId', 'suggestions')[0];
+ var store = select.getStore();
+ store.removeAll();
+ Ext.each(suggestions, function (suggestion) {
+ store.add(new store.recordType({
+ text: suggestion,
+ value: suggestion
+ }));
+ });
+ // Update the current word
+ this.dialog.find('itemId', 'word')[0].setValue(this.currentElement.htmlareaOriginalWord);
+ if (suggestions.length > 0) {
+ select.setValue(store.getAt(0).get('value'));
+ select.fireEvent('select', select, store.getAt(0), 0);
+ } else {
+ this.dialog.find('itemId', 'replacement')[0].setVvalue(this.currentElement.innerHTML);
+ }
+ return false;
+ },
+ /*
+ * Handler invoked when the mouse moves over a misspelled word
+ */
+ onWordMouseOver: function (event, element) {
+ HTMLArea._addClass(element, 'htmlarea-spellcheck-hover');
+ },
+ /*
+ * Handler invoked when the mouse moves out of a misspelled word
+ */
+ onWordMouseOut: function (event, element) {
+ HTMLArea._removeClass(element, 'htmlarea-spellcheck-hover');
+ },
+ /*
+ * Handler invoked when a suggestion is selected
+ */
+ onSuggestionSelect: function (select, record, index) {
+ this.dialog.find('itemId', 'replacement')[0].setValue(record.get('value'));
+ },
+ /*
+ * Handler invoked when a dictionary is selected
+ */
+ onDictionarySelect: function (select, record, index) {
+ this.dialog.find('itemId', 'dictionary')[0].setValue(record.get('value'));
+ },
+ /*
+ * Handler invoked when the Revert button is clicked
+ */
+ onRevertClick: function () {
+ this.dialog.find('itemId', 'replacement')[0].setValue(this.currentElement.htmlareaOriginalWord);
+ this.replaceWord(this.currentElement);
+ HTMLArea._removeClass(this.currentElement, 'htmlarea-spellcheck-fixed');
+ HTMLArea._addClass(this.currentElement, 'htmlarea-spellcheck-error');
+ HTMLArea._addClass(this.currentElement, 'htmlarea-spellcheck-current');
+ return false;
+ },
+ /*
+ * Replace the word contained in the element
+ */
+ replaceWord: function (element) {
+ HTMLArea._removeClass(element, 'htmlarea-spellcheck-hover');
+ HTMLArea._addClass(element, 'htmlarea-spellcheck-fixed');
+ element.htmlareaFixed = true;
+ var replacement = this.dialog.find('itemId', 'replacement')[0].getValue();
+ if (element.innerHTML != replacement) {
+ this.addToReplacementList.push([element.innerHTML, replacement]);
+ element.innerHTML = replacement;
+ this.modified = true;
+ }
+ },
+ /*
+ * Handler invoked when the Replace button is clicked
+ */
+ onReplaceClick: function () {
+ this.replaceWord(this.currentElement);
+ var start = this.currentElement.htmlareaId;
+ var index = start;
+ do {
+ ++index;
+ if (index == this.misspelledWords.length) {
+ index = 0;
+ }
+ } while (index != start && this.misspelledWords[index].htmlareaFixed);
+ if (index == start) {
+ index = 0;
+ Ext.MessageBox.alert('', this.localize('Finished list of mispelled words'));
+ }
+ this.setCurrentWord(this.misspelledWords[index], true);
+ return false;
+ },
+ /*
+ * Handler invoked when the Replace all button is clicked
+ */
+ onReplaceAllClick: function () {
+ Ext.each(this.allWords[this.currentElement.htmlareaOriginalWord], function (element) {
+ if (element != this.currentElement) {
+ this.replaceWord(element);
+ }
+ }, this);
+ // Replace current element last, so that we jump to the next word
+ return this.onReplaceClick();
+ },
+ /*
+ * Handler invoked when the Ignore button is clicked
+ */
+ onIgnoreClick: function () {
+ this.dialog.find('itemId', 'replacement')[0].setValue(this.currentElement.htmlareaOriginalWord);
+ return this.onReplaceClick();
+ },
+ /*
+ * Handler invoked when the Ignore all button is clicked
+ */
+ onIgnoreAllClick: function () {
+ this.dialog.find('itemId', 'replacement')[0].setValue(this.currentElement.htmlareaOriginalWord);
+ return this.onReplaceAllClick();
+ },
+ /*
+ * Handler invoked when the Learn button is clicked
+ */
+ onLearnClick: function () {
+ this.addToPersonalDictionary.push(this.currentElement.htmlareaOriginalWord);
+ return this.onIgnoreAllClick();
+ },
+ /*
+ * Handler invoked when the Re-check button is clicked
+ */
+ onRecheckClick: function () {
+ // Disable buttons
+ Ext.each(this.dialog.findByType('button'), function (button) {
+ button.setDisabled(true);
+ });
+ Ext.each(Ext.getCmp(this.editor.editorId + '-spell-check-status').findByType('button'), function (button) {
+ button.setDisabled(true);
+ });
+ Ext.getCmp(this.editor.editorId + '-spell-check-status').setStatus({
+ text: this.localize('Please wait: changing dictionary to') + ': "' + this.dialog.find('itemId', 'dictionary')[0].getValue() + '".',
+ iconCls: 'status-wait',
+ clear: false
+ });
+ this.dialog.find('itemId', 'content')[0].setValue(this.cleanDocument(true));
+ this.dialog.getComponent('spell-check-form').getForm().submit();
+ },
+ /*
+ * Handler invoked when the Info button is clicked
+ */
+ onInfoClick: function () {
+ var info = this.dialog.getComponent('spell-check-iframe').getEl().dom.contentWindow.spellcheckInfo;
+ if (!info) {
+ Ext.MessageBox.alert('', this.localize('No information available'));
+ } else {
+ var txt = this.localize('Document information') + ' ';
+ Ext.iterate(info, function (key, value) {
+ txt += ' ' + this.localize(key) + ': ' + value;
+ }, this);
+ txt += ' ' + this.localize('seconds');
+ Ext.MessageBox.alert('', txt);
+ }
+ return false;
}
});
-
Index: typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css
===================================================================
--- typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css (révision 7101)
+++ typo3/sysext/rtehtmlarea/htmlarea/skins/default/htmlarea.css (copie de travail)
@@ -483,56 +483,23 @@
border: 1px solid #A2AAB8;
}
/* Selectors for the SpellChecker dialogue */
-.htmlarea-spell-check .dictionaries {
- float:right;
- padding:2px;
+.htmlarea-window .spell-check .controls {
+ text-align: center;
+ width: 175px;
+ margin: 3px;
}
-.htmlarea-spell-check .dictionaries #v_dictionaries {
- width:10em;
- margin-right:5px;
+.htmlarea-window .spell-check .controls .x-btn {
+ margin-top: 3px;
+ margin-left: 8px;
}
-.htmlarea-spell-check #b_recheck {
- vertical-align:middle;
- width:12em;
+.htmlarea-window .spell-check .contentframe {
+ float: right;
+ height: 450px;
+ margin: 9px 0px;
+ background-color: #FFF;
+ color: #000;
+ border: 1px solid #A2AAB8;
}
-.htmlarea-spell-check .status {
- font-weight:bold;
- padding:2px;
-}
-.htmlarea-spell-check .controls {
- width:14em;
- clear:right;float:left;
- text-align:center;
- margin:3px;
-}
-.htmlarea-spell-check .controls .sectitle {
- font-weight:bold;
- padding:2px 4px;
-}
-.htmlarea-spell-check .controls .secbody {
- margin-bottom:10px;
-}
-.htmlarea-spell-check .controls #v_currentWord {
- color:#F00;font-weight:bold;
- margin-bottom:2px;
-}
-.htmlarea-spell-check .controls #v_replacement {
- margin-bottom:3px;
-}
-.htmlarea-spell-check .controls #v_suggestions, .controls #v_replacement {
- width:12em;
-}
-.htmlarea-spell-check .contentframe {
- float:right; margin:3px;
-}
-.htmlarea-spell-check .contentframe #i_framecontent {
- background-color:#FFF;color:#000;
- height:450px;width:480px;
-}
-.htmlarea-spell-check .occurrences-found {
- padding:7px 0px 0px 5px;
- clear:both;
-}
/* Selectors for the ContextMenu plugin */
.htmlarea-context-menu {
background-color:#EFEFF4;
@@ -558,3 +525,57 @@
margin-bottom:0;
border-color:#A2AAB8;
}
+/* Window status bar selectors */
+.htmlarea-window .status-ready {
+ padding-left: 21px !important;
+ background-repeat: no-repeat;
+ background-image: url("images/dialog-ok.png");
+ background-position: 0px 2px;
+}
+.htmlarea-window .status-info {
+ padding-left: 21px !important;
+ background-repeat: no-repeat;
+ background-image: url("images/dialog-information.png");
+ background-position: 0px 2px;
+}
+.htmlarea-window .status-wait {
+ padding-left: 45px !important;
+ background-repeat: no-repeat;
+ background-image:url("images/loading-balls.gif");
+ background-position: 0px 6px;
+}
+.x-statusbar .x-btn {
+ margin-left: 5px;
+}
+.x-statusbar .x-status-text {
+ cursor: default;
+}
+
+/* Button background positioning in window status bar*/
+.x-statusbar .x-btn-tl{
+ background-position: 0 0;
+}
+.x-statusbar .x-btn-tr{
+ background-position: -3px 0;
+}
+.x-statusbar .x-btn-tc{
+ background-position: 0 -6px;
+}
+.x-statusbar .x-btn-ml{
+ background-position: 0 -24px;
+}
+.x-statusbar .x-btn-mr{
+ background-position: -3px -24px;
+}
+.x-statusbar .x-btn-mc{
+ background-position: 0 -1096px;
+}
+.x-statusbar .x-btn-bl{
+ background-position: 0 -3px;
+}
+.x-statusbar .x-btn-br{
+ background-position: -3px -3px;
+}
+.x-statusbar .x-btn-bc{
+ background-position: 0 -15px;
+}
Index: typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/dialog-information.png
===================================================================
Impossible d'afficher : fichier considéré comme binaire.
svn:mime-type = application/octet-stream
Modification de propriétés sur typo3\sysext\rtehtmlarea\htmlarea\skins\default\images\dialog-information.png
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Index: typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/dialog-ok.png
===================================================================
Impossible d'afficher : fichier considéré comme binaire.
svn:mime-type = application/octet-stream
Modification de propriétés sur typo3\sysext\rtehtmlarea\htmlarea\skins\default\images\dialog-ok.png
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Index: typo3/sysext/rtehtmlarea/htmlarea/skins/default/images/loading-balls.gif
===================================================================
Impossible d'afficher : fichier considéré comme binaire.
svn:mime-type = application/octet-stream
Modification de propriétés sur typo3\sysext\rtehtmlarea\htmlarea\skins\default\images\loading-balls.gif
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Index: typo3/sysext/rtehtmlarea/pi1/class.tx_rtehtmlarea_pi1.php
===================================================================
--- typo3/sysext/rtehtmlarea/pi1/class.tx_rtehtmlarea_pi1.php (révision 7101)
+++ typo3/sysext/rtehtmlarea/pi1/class.tx_rtehtmlarea_pi1.php (copie de travail)
@@ -2,7 +2,7 @@
/***************************************************************
* Copyright notice
*
-* (c) 2003-2009 Stanislas Rolland
+* (c) 2003-2010 Stanislas Rolland
* All rights reserved
*
* This script is part of the Typo3 project. The Typo3 project is
@@ -112,8 +112,6 @@
if (empty($this->dictionary) || !in_array($this->dictionary, $dictionaryArray)) {
$this->dictionary = 'en';
}
- $dictionaries = substr_replace($dictionaryList, '@'.$this->dictionary, strpos($dictionaryList, $this->dictionary), strlen($this->dictionary));
-
// Setting the pspell suggestion mode
$this->pspellMode = t3lib_div::_POST('pspell_mode')?t3lib_div::_POST('pspell_mode'): $this->pspellMode;
// Now sanitize $this->pspellMode
@@ -214,10 +212,9 @@
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-
+
';
- $this->result .= '';
+ $this->result .= '';
$this->result .= preg_replace('/'.preg_quote('').'['.preg_quote(chr(10).chr(13).chr(32)).']*/'.(($this->parserCharset == 'utf-8')?'u':''), '', $this->text);
- $this->result .= ''.$dictionaries.'
';
+ $this->result .= ''.$dictionaries.'
';
// Closing
$this->result .= '
@@ -355,7 +354,7 @@
unset($suggest);
}
if( !in_array($word, $incurrent) ) {
- $stringText = preg_replace('/\b'.$word.'\b/'.(($this->parserCharset == 'utf-8')?'u':''), ''.$word.' ', $stringText);
+ $stringText = preg_replace('/\b'.$word.'\b/'.(($this->parserCharset == 'utf-8')?'u':''), ''.$word.' ', $stringText);
$incurrent[] = $word;
}
}
@@ -391,7 +390,7 @@
unset($suggestions);
}
if (!in_array($word, $incurrent)) {
- $stringText = preg_replace('/\b'.$word.'\b/'.(($this->parserCharset == 'utf-8')?'u':''), ''.$word.' ', $stringText);
+ $stringText = preg_replace('/\b'.$word.'\b/'.(($this->parserCharset == 'utf-8')?'u':''), ''.$word.' ', $stringText);
$incurrent[] = $word;
}
}
Index: typo3/sysext/t3skin/rtehtmlarea/htmlarea.css
===================================================================
--- typo3/sysext/t3skin/rtehtmlarea/htmlarea.css (révision 7101)
+++ typo3/sysext/t3skin/rtehtmlarea/htmlarea.css (copie de travail)
@@ -490,56 +490,23 @@
border: 1px solid #A2AAB8;
}
/* Selectors for the SpellChecker dialogue */
-.htmlarea-spell-check .dictionaries {
- float:right;
- padding:2px;
+.htmlarea-window .spell-check .controls {
+ text-align: center;
+ width: 175px;
+ margin: 3px;
}
-.htmlarea-spell-check .dictionaries #v_dictionaries {
- width:10em;
- margin-right:5px;
+.htmlarea-window .spell-check .controls .x-btn {
+ margin-top: 3px;
+ margin-left: 8px;
}
-.htmlarea-spell-check #b_recheck {
- vertical-align:middle;
- width:12em;
+.htmlarea-window .spell-check .contentframe {
+ float: right;
+ height: 450px;
+ margin: 9px 0px;
+ background-color: #FFF;
+ color: #000;
+ border: 1px solid #A2AAB8;
}
-.htmlarea-spell-check .status {
- font-weight:bold;
- padding:2px;
-}
-.htmlarea-spell-check .controls {
- width:14em;
- clear:right;float:left;
- text-align:center;
- margin:3px;
-}
-.htmlarea-spell-check .controls .sectitle {
- font-weight:bold;
- padding:2px 4px;
-}
-.htmlarea-spell-check .controls .secbody {
- margin-bottom:10px;
-}
-.htmlarea-spell-check .controls #v_currentWord {
- color:#F00;font-weight:bold;
- margin-bottom:2px;
-}
-.htmlarea-spell-check .controls #v_replacement {
- margin-bottom:3px;
-}
-.htmlarea-spell-check .controls #v_suggestions, .controls #v_replacement {
- width:12em;
-}
-.htmlarea-spell-check .contentframe {
- float:right; margin:3px;
-}
-.htmlarea-spell-check .contentframe #i_framecontent {
- background-color:#FFF;color:#000;
- height:450px;width:480px;
-}
-.htmlarea-spell-check .occurrences-found {
- padding:7px 0px 0px 5px;
- clear:both;
-}
/* Selectors for the ContextMenu plugin */
.htmlarea-context-menu {
background-color:#EFEFF4;
@@ -565,3 +532,57 @@
margin-bottom:0;
border-color:#A2AAB8;
}
+/* Window status bar selectors */
+.htmlarea-window .status-ready {
+ padding-left: 21px !important;
+ background-repeat: no-repeat;
+ background-image: url("images/dialog-ok.png");
+ background-position: 0px 2px;
+}
+.htmlarea-window .status-info {
+ padding-left: 21px !important;
+ background-repeat: no-repeat;
+ background-image: url("images/dialog-information.png");
+ background-position: 0px 2px;
+}
+.htmlarea-window .status-wait {
+ padding-left: 45px !important;
+ background-repeat: no-repeat;
+ background-image:url("images/loading-balls.gif");
+ background-position: 0px 6px;
+}
+.x-statusbar .x-btn {
+ margin-left: 5px;
+}
+.x-statusbar .x-status-text {
+ cursor: default;
+}
+
+/* Button background positioning in window status bar*/
+.x-statusbar .x-btn-tl{
+ background-position: 0 0;
+}
+.x-statusbar .x-btn-tr{
+ background-position: -3px 0;
+}
+.x-statusbar .x-btn-tc{
+ background-position: 0 -6px;
+}
+.x-statusbar .x-btn-ml{
+ background-position: 0 -24px;
+}
+.x-statusbar .x-btn-mr{
+ background-position: -3px -24px;
+}
+.x-statusbar .x-btn-mc{
+ background-position: 0 -1096px;
+}
+.x-statusbar .x-btn-bl{
+ background-position: 0 -3px;
+}
+.x-statusbar .x-btn-br{
+ background-position: -3px -3px;
+}
+.x-statusbar .x-btn-bc{
+ background-position: 0 -15px;
+}
Index: typo3/sysext/t3skin/rtehtmlarea/images/dialog-information.png
===================================================================
Impossible d'afficher : fichier considéré comme binaire.
svn:mime-type = application/octet-stream
Modification de propriétés sur typo3\sysext\t3skin\rtehtmlarea\images\dialog-information.png
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Index: typo3/sysext/t3skin/rtehtmlarea/images/dialog-ok.png
===================================================================
Impossible d'afficher : fichier considéré comme binaire.
svn:mime-type = application/octet-stream
Modification de propriétés sur typo3\sysext\t3skin\rtehtmlarea\images\dialog-ok.png
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream
Index: typo3/sysext/t3skin/rtehtmlarea/images/loading-balls.gif
===================================================================
Impossible d'afficher : fichier considéré comme binaire.
svn:mime-type = application/octet-stream
Modification de propriétés sur typo3\sysext\t3skin\rtehtmlarea\images\loading-balls.gif
___________________________________________________________________
Ajouté : svn:mime-type
+ application/octet-stream