Project

General

Profile

Feature #22303 ยป rtehtmlarea_feature_13870.patch

Administrator Admin, 2010-03-20 21:49

View differences:

typo3/sysext/rtehtmlarea/htmlarea/htmlarea.js (copie de travail)
}
});
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
* <p>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.</p>
* <pre><code>
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
</code></pre>
* @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:
* <pre><code>
// 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']
})
});
</code></pre>
*/
/**
* @cfg {String} defaultText
* The default {@link #text} value. This will be used anytime the status bar is cleared with the
* <tt>useDefaults:true</tt> 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 <tt>useDefaults:true</tt> option (defaults to '').
*/
/**
* @cfg {String} text
* A string that will be <b>initially</b> 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 <code>{@link #defaultText}</code>
* will be used.
*/
/**
* @cfg {String} iconCls
* A CSS class that will be <b>initially</b> set as the status bar icon and is
* expected to provide a background image (defaults to '').
* Example usage:<pre><code>
// 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'
});
</code></pre>
*/
/**
* @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 <code>{@link #iconCls}</code> applied when calling
* <code>{@link #showBusy}</code> (defaults to <tt>'x-status-busy'</tt>).
* It can be overridden at any time by passing the <code>iconCls</code>
* argument into <code>{@link #showBusy}</code>.
*/
busyIconCls : 'x-status-busy',
/**
* @cfg {String} busyText
* The default <code>{@link #text}</code> applied when calling
* <code>{@link #showBusy}</code> (defaults to <tt>'Loading...'</tt>).
* It can be overridden at any time by passing the <code>text</code>
* argument into <code>{@link #showBusy}</code>.
*/
busyText : 'Loading...',
/**
* @cfg {Number} autoClear
* The number of milliseconds to wait after setting the status via
* <code>{@link #setStatus}</code> before automatically clearing the status
* text and icon (defaults to <tt>5000</tt>). Note that this only applies
* when passing the <tt>clear</tt> argument to <code>{@link #setStatus}</code>
* since that is the only way to defer clearing the status. This can
* be overridden by specifying a different <tt>wait</tt> value in
* <code>{@link #setStatus}</code>. Calls to <code>{@link #clearStatus}</code>
* 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
* <tt>'&nbsp;'</tt>). If there are no other items in the toolbar using
* an empty string (<tt>''</tt>) for this value would end up in the toolbar
* height collapsing since the empty string will not maintain the toolbar
* height. Use <tt>''</tt> if the toolbar should collapse in height
* vertically when no text is specified and there are no other items in
* the toolbar.
*/
emptyText : '&nbsp;',
// 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:<ul>
* <li><tt>text</tt> {String} : (optional) The status text to display. If not specified, any current
* status text will remain unchanged.</li>
* <li><tt>iconCls</tt> {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.</li>
* <li><tt>clear</tt> {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 <tt>true</tt> 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:<ul>
* <li><tt>wait</tt> {Number} : (optional) The number of milliseconds to wait before clearing
* (defaults to {@link #autoClear}).</li>
* <li><tt>anim</tt> {Number} : (optional) False to clear the status immediately once the callback
* executes (defaults to true which fades the status out).</li>
* <li><tt>useDefaults</tt> {Number} : (optional) False to completely clear the status text and iconCls
* (defaults to true which uses {@link #defaultText} and {@link #defaultIconCls}).</li>
* </ul></li></ul>
* Example usage:<pre><code>
// 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
}
});
</code></pre>
* @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:<ul>
* <li><tt>anim</tt> {Boolean} : (optional) True to clear the status by fading out the status element (defaults
* to false which clears immediately).</li>
* <li><tt>useDefaults</tt> {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).</li>
* </ul>
* @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
* <tt>text</tt> and/or <tt>iconCls</tt> 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
*/
......
* Dialogue window onClose handler
*/
onClose: function () {
this.editor.focus();
this.restoreSelection();
this.editor.updateToolbar();
},
......
*/
onCancel: function () {
this.dialog.close();
this.editor.focus();
},
/*
* Save selection
typo3/sysext/rtehtmlarea/htmlarea/locallang_dialogs.xml (copie de travail)
<label index="No language mark">No language</label>
<label index="Remove language mark">Remove language</label>
<label index="statusBarStyle">Style</label>
<label index="statusBarReady">Ready</label>
</languageKey>
</data>
<orig_hash type="array">
typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/locallang.xml (copie de travail)
<label index="HTMLArea Spell Checker">HTMLArea Spell Checker</label>
<label index="QUIT_CONFIRMATION">This will drop changes and quit spell checker. Please confirm.</label>
<label index="Re-check">Re-check</label>
<label index="Replacement">Replacement</label>
<label index="Replace all">Replace all</label>
<label index="Replace with">Replace with</label>
<label index="Replace">Replace</label>
......
<label index="of the word">of the word</label>
<label index="was found.">was found.</label>
<label index="were found.">were found.</label>
<label index="Info">Info</label>
<label index="Document information">Document information</label>
<label index="No information available">No information available</label>
<label index="Total words">Total words</label>
typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/popups/spell-check-ui-iso-8859-1.html (copie de travail)
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?xml version="1.0" encoding="iso-8859-1"?>
<html>
<!--
/***************************************************************
* Copyright notice
*
* (c) 2003 dynarch.com. Authored by Mihai Bazon, sponsored by www.americanbible.org.
* (c) 2004-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!
***************************************************************/
/*
* Spell Checker Plugin for TYPO3 htmlArea RTE
*
* TYPO3 SVN ID: $Id$
*/
-->
<head>
<title>Spell Checker</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript" src="../spell-check-ui.js"></script>
</head>
<body class="popupwin htmlarea-spell-check" onload="initDocument();">
<div id="content">
<form id="spellcheck_form" style="display: none;" action="" method="post" target="framecontent" accept-charset="ISO-8859-1">
<input type="hidden" name="content" id="f_content" />
<input type="hidden" name="dictionary" id="f_dictionary" />
<input type="hidden" name="pspell_charset" id="f_charset" />
<input type="hidden" name="pspell_mode" id="f_pspell_mode" />
<input type="hidden" name="userUid" id="f_user_uid" />
<input type="hidden" name="enablePersonalDicts" id="f_personal_dicts" />
<input type="hidden" name="showDictionaries" id="f_show_dictionaries" />
<input type="hidden" name="restrictToDictionaries" id="f_restrict_to_dictionaries" />
<input type="hidden" name="init" id="f_init" value="1" />
</form>
<div class="title">Spell Checker</div>
<div class="dictionaries">
<label for="v_dictionaries">Dictionary</label>
<select id="v_dictionaries" name="v_dictionaries"></select>
<button id="b_recheck">Re-check</button>
</div>
<div class="status" id="status">Please wait. Calling spell checker.</div>
<div class="controls">
<div class="sectitle">Original word</div>
<div class="secbody" id="v_currentWord">pliz weit ;-)</div>
<div class="secbody">
<button id="b_revert" class="long-button">Revert</button>
</div>
<div class="sectitle"><label for="v_replacement">Replace with</label></div>
<div class="secbody">
<input type="text" id="v_replacement" name="v_replacement"/>
<button id="b_replace" class="long-button">Replace</button>
<button id="b_replall" class="long-button">Replace all</button>
<button id="b_ignore" class="long-button">Ignore</button>
<button id="b_ignall" class="long-button">Ignore all</button>
<button id="b_learn" class="long-button">Learn</button>
</div>
<div class="sectitle"><label for="v_suggestions">Suggestions</label></div>
<div class="secbody">
<select size="11" id="v_suggestions"></select>
</div>
<div class="secbody">
<button id="b_info">Info</button>
</div>
</div>
<div class="contentframe">
<iframe src="../../../popups/blank.html" id="i_framecontent" name="framecontent"></iframe>
</div>
<div id="statusbar" class="occurrences-found">&nbsp;</div>
<div class="space"></div>
<div class="buttons">
<button type="button" id="b_ok">OK</button>
<button type="button" id="b_cancel">Cancel</button>
</div>
</div>
</body>
</html>
typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/popups/spell-check-ui.html (copie de travail)
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<?xml version="1.0" encoding="utf-8"?>
<html>
<!--
/***************************************************************
* Copyright notice
*
* (c) 2003 dynarch.com. Authored by Mihai Bazon, sponsored by www.americanbible.org.
* (c) 2004-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!
***************************************************************/
/*
* Spell Checker Plugin for TYPO3 htmlArea RTE
*
* TYPO3 SVN ID: $Id$
*/
-->
<head>
<title>Spell Checker</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="../spell-check-ui.js"></script>
</head>
<body class="popupwin htmlarea-spell-check" onload="initDocument();">
<div id="content" class="spellcheck">
<form id="spellcheck_form" style="display: none;" action="" method="post" target="framecontent" accept-charset="UTF-8">
<input type="hidden" name="content" id="f_content" />
<input type="hidden" name="dictionary" id="f_dictionary" />
<input type="hidden" name="pspell_charset" id="f_charset" />
<input type="hidden" name="pspell_mode" id="f_pspell_mode" />
<input type="hidden" name="userUid" id="f_user_uid" />
<input type="hidden" name="enablePersonalDicts" id="f_personal_dicts" />
<input type="hidden" name="showDictionaries" id="f_show_dictionaries" />
<input type="hidden" name="restrictToDictionaries" id="f_restrict_to_dictionaries" />
<input type="hidden" name="init" id="f_init" value="1" />
</form>
<div class="title">Spell Checker</div>
<div class="dictionaries">
<label for="v_dictionaries">Dictionary</label>
<select id="v_dictionaries" name="v_dictionaries"></select>
<button id="b_recheck">Re-check</button>
</div>
<div class="status" id="status">Please wait. Calling spell checker.</div>
<div class="controls">
<div class="sectitle">Original word</div>
<div class="secbody" id="v_currentWord">pliz weit ;-)</div>
<div class="secbody">
<button id="b_revert" class="long-button">Revert</button>
</div>
<div class="sectitle"><label for="v_replacement">Replace with</label></div>
<div class="secbody">
<input type="text" id="v_replacement" name="v_replacement"/>
<button id="b_replace" class="long-button">Replace</button>
<button id="b_replall" class="long-button">Replace all</button>
<button id="b_ignore" class="long-button">Ignore</button>
<button id="b_ignall" class="long-button">Ignore all</button>
<button id="b_learn" class="long-button">Learn</button>
</div>
<div class="sectitle"><label for="v_suggestions">Suggestions</label></div>
<div class="secbody">
<select size="11" id="v_suggestions"></select>
</div>
<div class="secbody">
<button id="b_info">Info</button>
</div>
</div>
<div class="contentframe">
<iframe src="../../../popups/blank.html" id="i_framecontent" name="framecontent"></iframe>
</div>
<div id="statusbar" class="occurrences-found">&nbsp;</div>
<div class="space"></div>
<div class="buttons">
<button type="button" id="b_ok">OK</button>
<button type="button" id="b_cancel">Cancel</button>
</div>
</div>
</body>
</html>
typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-check-style.css (copie de travail)
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;
}
typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-check-ui.js (copie de travail)
/***************************************************************
* Copyright notice
*
* (c) 2003 dynarch.com. Authored by Mihai Bazon, sponsored by www.americanbible.org.
* (c) 2004-2009 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!
***************************************************************/
/*
* 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") +
' "<b>' + currentElement.__msh_origWord + '</b>"' + " " + 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;
}
};
typo3/sysext/rtehtmlarea/htmlarea/plugins/SpellChecker/spell-checker.js (copie de travail)
* 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: '<tpl for="."><div ext:qtip="{value}" style="text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
}
},
/*
* This function gets called when the button was pressed.
*
* @param object editor: the editor instance
......
*
* @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: [
... This diff was truncated because it exceeds the maximum size that can be displayed.
    (1-1/1)