- Unified (single) spellchecker button

pull/1/head
alecpl 12 years ago
parent 84d6e279e3
commit 4be86f3a37

@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
- Unified (single) spellchecker button
- Fix encoding of attachment with comma in name (#1488389)
- Scroll long lists on drag&drop (#1485946)
- Fix handling of % character in IMAP protocol (#1488382)

@ -261,11 +261,9 @@ function rcube_webmail()
$.merge(this.env.compose_commands, ['add-recipient', 'firstpage', 'previouspage', 'nextpage', 'lastpage']);
if (this.env.spellcheck) {
this.env.spellcheck.spelling_state_observer = function(s){ ref.set_spellcheck_state(s); };
this.env.spellcheck.spelling_state_observer = function(s) { ref.spellcheck_state(); };
this.env.compose_commands.push('spellcheck')
this.set_spellcheck_state('ready');
if ($("input[name='_is_html']").val() == '1')
this.display_spellcheck_controls(false);
this.enable_command('spellcheck', true);
}
document.onmouseup = function(e){ return p.doc_mouse_up(e); };
@ -898,13 +896,18 @@ function rcube_webmail()
break;
case 'spellcheck':
if (window.tinyMCE && tinyMCE.get(this.env.composebody)) {
tinyMCE.execCommand('mceSpellCheck', true);
if (this.spellcheck_state()) {
this.stop_spellchecking();
}
else if (this.env.spellcheck && this.env.spellcheck.spellCheck && this.spellcheck_ready) {
this.env.spellcheck.spellCheck();
this.set_spellcheck_state('checking');
else {
if (window.tinyMCE && tinyMCE.get(this.env.composebody)) {
tinyMCE.execCommand('mceSpellCheck', true);
}
else if (this.env.spellcheck && this.env.spellcheck.spellCheck) {
this.env.spellcheck.spellCheck();
}
}
this.spellcheck_state();
break;
case 'savedraft':
@ -3116,8 +3119,9 @@ function rcube_webmail()
this.toggle_editor = function(props)
{
this.stop_spellchecking();
if (props.mode == 'html') {
this.display_spellcheck_controls(false);
this.plain2html($('#'+props.id).val(), props.id);
tinyMCE.execCommand('mceAddControl', false, props.id);
@ -3128,8 +3132,6 @@ function rcube_webmail()
}
else {
var thisMCE = tinyMCE.get(props.id), existingHtml;
if (thisMCE.plugins.spellchecker && thisMCE.plugins.spellchecker.active)
thisMCE.execCommand('mceSpellCheck', false);
if (existingHtml = thisMCE.getContent()) {
if (!confirm(this.get_label('editorwarning'))) {
@ -3138,7 +3140,6 @@ function rcube_webmail()
this.html2plain(existingHtml, props.id);
}
tinyMCE.execCommand('mceRemoveControl', false, props.id);
this.display_spellcheck_controls(true);
}
return true;
@ -3147,43 +3148,52 @@ function rcube_webmail()
this.stop_spellchecking = function()
{
var ed;
if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody))) {
if (ed.plugins.spellchecker && ed.plugins.spellchecker.active)
ed.execCommand('mceSpellCheck');
}
else if ((ed = this.env.spellcheck) && !this.spellcheck_ready) {
$(ed.spell_span).trigger('click');
this.set_spellcheck_state('ready');
else if (ed = this.env.spellcheck) {
if (ed.state && ed.state != 'ready' && ed.state != 'no_error_found')
$(ed.spell_span).trigger('click');
}
this.spellcheck_state();
};
this.display_spellcheck_controls = function(vis)
this.spellcheck_state = function()
{
if (this.env.spellcheck) {
// stop spellchecking process
if (!vis)
this.stop_spellchecking();
var ed, active;
$(this.env.spellcheck.spell_container)[vis ? 'show' : 'hide']();
}
};
if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody)) && ed.plugins.spellchecker)
active = ed.plugins.spellchecker.active;
else if ((ed = this.env.spellcheck) && ed.state)
active = ed.state != 'ready' && ed.state != 'no_error_found';
this.set_spellcheck_state = function(s)
{
this.spellcheck_ready = (s == 'ready' || s == 'no_error_found');
this.enable_command('spellcheck', this.spellcheck_ready);
$('#'+rcmail.buttons.spellcheck[0].id)[active ? 'addClass' : 'removeClass']('selected');
return active;
};
// get selected language
this.spellcheck_lang = function()
{
var ed;
if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody)) && ed.plugins.spellchecker) {
if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody)) && ed.plugins.spellchecker)
return ed.plugins.spellchecker.selectedLang;
}
else if (this.env.spellcheck) {
else if (this.env.spellcheck)
return GOOGIE_CUR_LANG;
}
};
this.spellcheck_lang_set = function(lang)
{
var editor;
if (window.tinyMCE && (editor = tinyMCE.get(this.env.composebody)))
editor.plugins.spellchecker.selectedLang = lang;
else if (this.env.spellcheck)
this.env.spellcheck.setCurrentLanguage(lang);
};
// resume spellchecking, highlight provided mispellings without new ajax request
@ -3202,6 +3212,8 @@ function rcube_webmail()
sp.prepare(false, true);
sp.processData(data);
}
this.spellcheck_state();
}
this.set_draft_id = function(id)

@ -44,11 +44,11 @@ function rcmail_editor_init(config)
theme_advanced_buttons1: 'bold,italic,underline,strikethrough,justifyleft,justifycenter,justifyright,justifyfull,separator,outdent,indent,charmap,hr,link,unlink,code,forecolor',
theme_advanced_buttons2: ',fontselect,fontsizeselect'
});
else // mail compose
else { // mail compose
$.extend(conf, {
plugins: 'paste,emotions,media,nonbreaking,table,searchreplace,visualchars,directionality,tabfocus' + (config.spellcheck ? ',spellchecker' : ''),
theme_advanced_buttons1: 'bold,italic,underline,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,outdent,indent,ltr,rtl,blockquote,|,forecolor,backcolor,fontselect,fontsizeselect',
theme_advanced_buttons2: 'link,unlink,table,|,emotions,charmap,image,media,|,code,search' + (config.spellcheck ? ',spellchecker' : '') + ',undo,redo',
theme_advanced_buttons2: 'link,unlink,table,|,emotions,charmap,image,media,|,code,search,undo,redo',
spellchecker_languages: (rcmail.env.spellcheck_langs ? rcmail.env.spellcheck_langs : 'Dansk=da,Deutsch=de,+English=en,Espanol=es,Francais=fr,Italiano=it,Nederlands=nl,Polski=pl,Portugues=pt,Suomi=fi,Svenska=sv'),
spellchecker_rpc_url: '?_task=utils&_action=spell_html',
spellchecker_enable_learn_rpc: config.spelldict,
@ -56,6 +56,15 @@ function rcmail_editor_init(config)
oninit: 'rcmail_editor_callback'
});
// add handler for spellcheck button state update
conf.setup = function(ed) {
ed.onSetProgressState.add(function(ed, active) {
if (!active)
rcmail.spellcheck_state();
});
}
}
// support external configuration settings e.g. from skin
if (window.rcmail_editor_settings)
$.extend(conf, window.rcmail_editor_settings);

@ -813,6 +813,9 @@ function rcmail_compose_body($attrib)
if (!$spellcheck_langs[$lang])
$lang = 'en';
$OUTPUT->set_env('spell_langs', $spellcheck_langs);
$OUTPUT->set_env('spell_lang', $lang);
$editor_lang_set = array();
foreach ($spellcheck_langs as $key => $name) {
$editor_lang_set[] = ($key == $lang ? '+' : '') . JQ($name).'='.JQ($key);
@ -830,7 +833,7 @@ function rcmail_compose_body($attrib)
"googie.lang_learn_word = \"%s\";\n".
"googie.setLanguages(%s);\n".
"googie.setCurrentLanguage('%s');\n".
"googie.setSpellContainer('spellcheck-control');\n".
"googie.setDecoration(false);\n".
"googie.decorateTextarea('%s');\n".
"%s.set_env('spellcheck', googie);",
$RCMAIL->output->get_skin_path(),

@ -495,6 +495,7 @@ body.iframe .boxtitle
padding: 2px 10px;
text-decoration: none;
min-height: 14px;
background: transparent;
}
.popupmenu li a.active,
@ -504,7 +505,8 @@ body.iframe .boxtitle
color: #333;
}
.popupmenu li a.active:hover
.popupmenu li a.active:hover,
.popupmenu.selectable li a.selected:hover
{
color: #fff;
background-color: #c00;
@ -515,6 +517,16 @@ body.iframe .boxtitle
float: left;
}
.popupmenu.selectable li a.selected
{
background: url(images/messageicons.png) 2px -372px no-repeat;
}
.popupmenu.selectable li a
{
padding-left: 20px;
}
.darkbg
{
background-color: #F2F2F2 !important;

@ -102,6 +102,7 @@ function rcube_mail_ui()
groupmenu: {id:'groupoptionsmenu', above:1},
mailboxmenu: {id:'mailboxoptionsmenu', above:1},
composemenu: {id:'composeoptionsmenu', editable:1, overlap:1},
spellmenu: {id:'spellmenu'},
// toggle: #1486823, #1486930
uploadmenu: {id:'attachment-form', editable:1, above:1, toggle:!bw.ie&&!bw.linux },
uploadform: {id:'upload-form', editable:1, toggle:!bw.ie&&!bw.linux }
@ -351,6 +352,43 @@ save_listmenu: function()
rcmail.set_list_options(cols, sort, ord, thread == 'thread' ? 1 : 0);
},
spellmenu: function(show)
{
var link, li,
lang = rcmail.spellcheck_lang(),
menu = this.popups.spellmenu.obj,
ul = $('ul', menu);
if (!ul.length) {
ul = $('<ul>');
for (i in rcmail.env.spell_langs) {
li = $('<li>');
link = $('<a href="#">').text(rcmail.env.spell_langs[i])
.addClass('active').data('lang', i)
.click(function() {
rcmail.spellcheck_lang_set($(this).data('lang'));
});
link.appendTo(li);
li.appendTo(ul);
}
ul.appendTo(menu);
}
// select current language
$('li', ul).each(function() {
var el = $('a', this);
if (el.data('lang') == lang)
el.addClass('selected');
else if (el.hasClass('selected'))
el.removeClass('selected');
});
this.show_popupmenu('spellmenu', show);
},
body_mouseup: function(evt, p)
{
var i, target = rcube_event.get_target(evt);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

@ -38,6 +38,17 @@
opacity: 0.35;
}
#messagetoolbar a.button.selected {
background-color: #ddd;
margin-left: 4px;
margin-right: 4px;
margin-top: -1px;
border: 1px solid #ccc;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#messagetoolbar a.checkmailSel {
background-position: 0 -32px;
}

@ -3,7 +3,9 @@
<head>
<title><roundcube:object name="productname" /> :: <roundcube:label name="compose" /></title>
<roundcube:include file="/includes/links.html" />
<roundcube:if condition="config:enable_spellcheck" />
<link rel="stylesheet" type="text/css" href="/googiespell.css" />
<roundcube:endif />
<script type="text/javascript" src="/functions.js"></script>
<script type="text/javascript" src="/splitter.js"></script>
<style type="text/css">
@ -23,7 +25,12 @@
<div id="messagetoolbar">
<roundcube:button command="list" type="link" class="button back" classAct="button back" classSel="button backSel" title="backtolist" content=" " />
<roundcube:button command="send" type="link" class="buttonPas send" classAct="button send" classSel="button sendSel" title="sendmessage" content=" " />
<roundcube:button command="spellcheck" type="link" class="buttonPas spellcheck" classAct="button spellcheck" classSel="button spellcheckSel" title="checkspelling" content=" " />
<roundcube:if condition="config:enable_spellcheck" />
<span class="dropbutton">
<roundcube:button command="spellcheck" type="link" class="buttonPas spellcheck" classAct="button spellcheck" classSel="button spellcheckSel" title="checkspelling" content=" " />
<span id="spellmenulink" onclick="rcmail_ui.show_popup('spellmenu');return false"></span>
</span>
<roundcube:endif />
<roundcube:button name="addattachment" type="link" class="button attach" classAct="button attach" classSel="button attachSel" title="addattachment" onclick="rcmail_ui.show_popup('uploadmenu', true);return false" content=" " />
<roundcube:button command="insert-sig" type="link" class="buttonPas insertsig" classAct="button insertsig" classSel="button insertsigSel" title="insertsignature" content=" " />
<roundcube:button command="savedraft" type="link" class="buttonPas savedraft" classAct="button savedraft" classSel="button savedraftSel" title="savemessage" content=" " />
@ -111,7 +118,6 @@
<roundcube:button type="input" command="list" class="button" label="cancel" tabindex="11" />
</div>
<div id="compose-editorfooter">
<span id="spellcheck-control" style="margin-right:10px"></span>
<roundcube:if condition="!in_array('htmleditor', (array)config:dont_override)" />
<span>
<label><roundcube:label name="editortype" /></label>
@ -143,6 +149,8 @@
</table>
</div>
<div id="spellmenu" class="popupmenu selectable"></div>
</form>
<roundcube:object name="composeAttachmentForm" id="attachment-form" attachmentFieldSize="40" class="popupmenu" />

@ -1166,11 +1166,12 @@ div.message-part blockquote blockquote blockquote {
#composebody {
position: absolute;
top: 24px;
top: 1px;
left: 0;
bottom: 0;
width: 99%;
border: 0;
border-radius: 0;
padding: 8px 0 8px 8px;
box-shadow: none;
resize: none;
@ -1195,11 +1196,6 @@ div.message-part blockquote blockquote blockquote {
overflow: auto;
}
#spellcheck-control {
margin: 6px 8px;
text-align: right;
}
.defaultSkin table.mceLayout,
.defaultSkin table.mceLayout tr.mceLast td {
border: 0 !important;

@ -1390,7 +1390,8 @@ ul.proplist li {
}
.toolbar a.button.spellcheck {
background-position: center -930px;
min-width: 64px;
background-position: left -930px;
}
.toolbar a.button.insertsig {
@ -1574,10 +1575,15 @@ select.decorated option[selected='selected'] {
background: linear-gradient(top, #00aad6 0%, #008fc9 100%);
}
ul.toolbarmenu.iconized li a {
ul.toolbarmenu.iconized li a,
ul.toolbarmenu.selectable li a {
padding-left: 30px;
}
ul.toolbarmenu.selectable li a.selected {
background: url(images/messages.png) 4px -27px no-repeat;
}
ul.toolbarmenu li label {
display: block;
color: #fff;

@ -3,7 +3,9 @@
<head>
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
<roundcube:if condition="config:enable_spellcheck" />
<link rel="stylesheet" type="text/css" href="/googiespell.css" />
<roundcube:endif />
</head>
<body class="noscroll">
@ -38,7 +40,12 @@
<!-- toolbar -->
<div id="messagetoolbar" class="fullwidth">
<div id="mailtoolbar" class="toolbar">
<roundcube:button command="spellcheck" type="link" class="button spellcheck disabled" classAct="button spellcheck" classSel="button spellcheck pressed" label="spellcheck" title="checkspelling" />
<roundcube:if condition="config:enable_spellcheck" />
<span class="dropbutton">
<roundcube:button command="spellcheck" type="link" class="button spellcheck disabled" classAct="button spellcheck" classSel="button spellcheck pressed" label="spellcheck" title="checkspelling" />
<span class="dropbuttontip" id="spellmenulink" onclick="UI.show_popup('spellmenu');return false"></span>
</span>
<roundcube:endif />
<roundcube:button name="addattachment" type="link" class="button attach" classAct="button attach" classSel="button attach pressed" label="attach" title="addattachment" onclick="UI.show_uploadform();return false" />
<roundcube:button command="insert-sig" type="link" class="button insertsig disabled" classAct="button insertsig" classSel="button insertsig pressed" label="signature" title="insertsignature" />
<roundcube:container name="toolbar" id="compose-toolbar" />
@ -142,7 +149,6 @@
<!-- message compose body -->
<div id="composeview-bottom">
<div id="composebodycontainer">
<div id="spellcheck-control"></div>
<roundcube:object name="composeBody" id="composebody" form="form" cols="70" rows="20" tabindex="9" />
</div>
<div id="compose-attachments" class="rightcol">
@ -171,6 +177,8 @@
</div>
</div>
<div id="spellmenu" class="popupmenu"></div>
<roundcube:include file="/includes/footer.html" />
</body>

@ -24,6 +24,7 @@ function rcube_mail_ui()
groupmenu: { above:1 },
mailboxmenu: { above:1 },
composeoptionsmenu: { editable:1, overlap:1 },
spellmenu: { callback: spellmenu },
// toggle: #1486823, #1486930
'attachment-form': { editable:1, above:1, toggle:!bw.ie&&!bw.linux },
'upload-form': { editable:1, toggle:!bw.ie&&!bw.linux }
@ -338,13 +339,13 @@ function rcube_mail_ui()
bottom.css('height', (form.height() - bottom.position().top) + 'px');
w = body.parent().width() - 6;
h = body.parent().height() - 36;
w = body.parent().width() - 5;
h = body.parent().height() - 16;
body.width(w).height(h);
if (window.tinyMCE && tinyMCE.get('composebody')) {
$('#composebody_tbl').width((w+10)+'px').height('').css('margin-top', '1px');
$('#composebody_ifr').width((w+10)+'px').height((h-22)+'px');
$('#composebody_tbl').width((w+8)+'px').height('').css('margin-top', '1px');
$('#composebody_ifr').width((w+8)+'px').height((h-40)+'px');
}
else {
$('#googie_edit_layer').height(h+'px');
@ -425,7 +426,7 @@ function rcube_mail_ui()
$('select').css('visibility', show?'hidden':'inherit');
$('select', obj).css('visibility', 'inherit');
}
return show;
}
@ -554,6 +555,42 @@ function rcube_mail_ui()
}
function spellmenu(show)
{
var link, li,
lang = rcmail.spellcheck_lang(),
menu = popups.spellmenu,
ul = $('ul', menu);
if (!ul.length) {
ul = $('<ul class="toolbarmenu selectable">');
for (i in rcmail.env.spell_langs) {
li = $('<li>');
link = $('<a href="#">').text(rcmail.env.spell_langs[i])
.addClass('active').data('lang', i)
.click(function() {
rcmail.spellcheck_lang_set($(this).data('lang'));
});
link.appendTo(li);
li.appendTo(ul);
}
ul.appendTo(menu);
}
// select current language
$('li', ul).each(function() {
var el = $('a', this);
if (el.data('lang') == lang)
el.addClass('selected');
else if (el.hasClass('selected'))
el.removeClass('selected');
});
}
/**
*
*/

Loading…
Cancel
Save