program/js/app.js | ●●●●● patch | view | raw | blame | history | |
program/js/editor.js | ●●●●● patch | view | raw | blame | history | |
program/lib/Roundcube/rcube_spellchecker.php | ●●●●● patch | view | raw | blame | history | |
program/steps/mail/compose.inc | ●●●●● patch | view | raw | blame | history | |
program/steps/mail/sendmail.inc | ●●●●● patch | view | raw | blame | history | |
program/steps/utils/spell_html.inc | ●●●●● patch | view | raw | blame | history | |
skins/classic/common.css | ●●●●● patch | view | raw | blame | history | |
skins/classic/functions.js | ●●●●● patch | view | raw | blame | history | |
skins/larry/ui.js | ●●●●● patch | view | raw | blame | history |
program/js/app.js
@@ -3358,8 +3358,11 @@ { this.stop_spellchecking(); var flag = $('[name="_is_html"]'); if (props.mode == 'html') { this.plain2html($('#'+props.id).val(), props.id); flag.val(1); tinymce.execCommand('mceAddEditor', false, props.id); if (this.env.default_font) @@ -3376,6 +3379,8 @@ } this.html2plain(existingHtml, props.id); } flag.val(0); tinymce.execCommand('mceRemoveEditor', false, props.id); } program/js/editor.js
@@ -19,7 +19,6 @@ { var ret, conf = { selector: '.mce_editor', apply_source_formatting: true, theme: 'modern', language: config.lang, content_css: config.skin_path + '/editor_content.css', @@ -28,10 +27,11 @@ extended_valid_elements: 'font[face|size|color|style],span[id|class|align|style]', relative_urls: false, remove_script_host: false, gecko_spellcheck: true, convert_urls: false, // #1486944 external_image_list: window.rcmail_editor_images, //TODO rc_client: rcmail image_list: window.rcmail_editor_images, image_description: false, paste_webkit_style: "color font-size font-family", paste_data_images: true }; if (config.mode == 'identity') @@ -43,21 +43,21 @@ }); else { // mail compose $.extend(conf, { plugins: ['charmap code directionality emoticons link image media nonbreaking paste table tabfocus textcolor searchreplace' + (config.spellcheck ? ' spellchecker' : '')], plugins: ['charmap code directionality emoticons link image media nonbreaking' + ' paste table tabfocus textcolor searchreplace' + (config.spellcheck ? ' spellchecker' : '')], toolbar: 'bold italic underline | alignleft aligncenter alignright alignjustify' + ' | bullist numlist outdent indent ltr rtl blockquote | forecolor backcolor | fontselect fontsizeselect' + ' | link unlink table | emoticons charmap image media | code searchreplace 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&_remote=1', spellchecker_enable_learn_rpc: config.spelldict, spellchecker_rpc_url: '../../../../../?_task=utils&_action=spell_html&_remote=1', spellchecker_enable_learn_rpc: config.spelldict, //TODO accessibility_focus: false }); conf.setup = function(ed) { ed.on('init', rcmail_editor_callback); // add handler for spellcheck button state update ed.on('SetProgressState', function(args) { if (!args.active) ed.on('ProgressState', function(args) { if (!args.state) rcmail.spellcheck_state(); }); ed.on('keypress', function() { @@ -90,7 +90,10 @@ $(tinymce.get(rcmail.env.composebody).getBody()).css(css); if (elem && elem.type == 'select-one') { // insert signature (only for the first time) if (!rcmail.env.identities_initialized) rcmail.change_identity(elem); // Focus previously focused element if (fe && fe.id != rcmail.env.composebody) { // use setTimeout() for IE9 (#1488541) @@ -103,8 +106,8 @@ // set tabIndex and set focus to element that was focused before rcmail_editor_tabindex(fe && fe.id == rcmail.env.composebody); // Trigger resize (needed for proper editor resizing in some browsers using default skin) $(window).resize(); // Trigger resize (needed for proper editor resizing in some browsers) window.setTimeout(function() { $(window).resize(); }, 100); } // set tabIndex on tinymce editor @@ -113,8 +116,9 @@ if (rcmail.env.task == 'mail') { var editor = tinymce.get(rcmail.env.composebody); if (editor) { var textarea = editor.getElement(); var node = editor.getContentAreaContainer().childNodes[0]; var textarea = editor.getElement(), node = editor.getContentAreaContainer().childNodes[0]; if (textarea && node) node.tabIndex = textarea.tabIndex; if (focus) @@ -124,49 +128,37 @@ } // switch html/plain mode function rcmail_toggle_editor(select, textAreaId, flagElement) function rcmail_toggle_editor(select, textAreaId) { var flag, ishtml; var ishtml = select.tagName != 'SELECT' ? select.checked : select.value == 'html', res = rcmail.command('toggle-editor', {id: textAreaId, mode: ishtml ? 'html' : 'plain'}); if (select.tagName != 'SELECT') ishtml = select.checked; else ishtml = select.value == 'html'; var res = rcmail.command('toggle-editor', {id:textAreaId, mode:ishtml?'html':'plain'}); if (ishtml) { // #1486593 setTimeout("rcmail_editor_tabindex(true);", 500); if (flagElement && (flag = rcube_find_object(flagElement))) flag.value = '1'; } else if (res) { if (flagElement && (flag = rcube_find_object(flagElement))) flag.value = '0'; if (rcmail.env.composebody) rcube_find_object(rcmail.env.composebody).focus(); } else { // !res if (!res) { if (select.tagName == 'SELECT') select.value = 'html'; else if (select.tagName == 'INPUT') select.checked = true; } else if (ishtml) { // #1486593 setTimeout("rcmail_editor_tabindex(true);", 500); } else if (rcmail.env.composebody) { rcube_find_object(rcmail.env.composebody).focus(); } } // editor callbeck for images listing function rcmail_editor_images() // editor callback for images listing function rcmail_editor_images(callback) { var i, files = rcmail.env.attachments, list = []; var i, file, list = []; for (i in files) { att = files[i]; if (att.complete && att.mimetype.startsWith('image/')) { list.push([att.name, rcmail.env.comm_path+'&_id='+rcmail.env.compose_id+'&_action=display-attachment&_file='+i]); for (i in rcmail.env.attachments) { file = rcmail.env.attachments[i]; if (file.complete && file.mimetype.startsWith('image/')) { list.push({title: file.name, value: rcmail.env.comm_path+'&_id='+rcmail.env.compose_id+'&_action=display-attachment&_file='+i}); } } return list; }; callback(list); } program/lib/Roundcube/rcube_spellchecker.php
@@ -226,7 +226,18 @@ else { $word = mb_substr($this->content, $item[1], $item[2], RCUBE_CHARSET); } $result[$word] = is_array($item[4]) ? implode("\t", $item[4]) : $item[4]; if (is_array($item[4])) { $suggestions = $item[4]; } else if (empty($item[4])) { $suggestions = array(); } else { $suggestions = explode("\t", $item[4]); } $result[$word] = $suggestions; } return $result; program/steps/mail/compose.inc
@@ -1675,7 +1675,7 @@ if (empty($attrib['name'])) $attrib['name'] = 'editorSelect'; $attrib['onchange'] = "return rcmail_toggle_editor(this, '".$attrib['editorid']."', '_is_html')"; $attrib['onchange'] = "return rcmail_toggle_editor(this, '".$attrib['editorid']."')"; $select = new html_select($attrib); program/steps/mail/sendmail.inc
@@ -273,9 +273,10 @@ } // append doctype and html/body wrappers $message_body = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">' . "\r\n<html><body" . (!empty($bstyle) ? " style='" . implode($bstyle, '; ') . "'" : '') . ">\r\n" . $message_body; $bstyle = !empty($bstyle) ? (" style='" . implode($bstyle, '; ') . "'") : ''; $message_body = '<html><head>' . '<meta http-equiv="Content-Type" content="text/html; charset=' . $message_charset . '" /></head>' . "<body" . $bstyle . ">\r\n" . $message_body; } if (!$savedraft) { program/steps/utils/spell_html.inc
@@ -19,30 +19,22 @@ +-----------------------------------------------------------------------+ */ // read input data $data = file_get_contents('php://input'); // Decode JSON input $request = json_decode($data, true); $lang = rcube_utils::get_input_value('lang', rcube_utils::INPUT_POST); $data = rcube_utils::get_input_value('text', rcube_utils::INPUT_POST); $data = html_entity_decode($data, ENT_QUOTES, RCUBE_CHARSET); $result = array(); $lang = $request['params'][0]; $data = $request['params'][1]; $data = implode("\n", (array) $data); $result['id'] = $request['id']; $spellchecker = new rcube_spellchecker($lang); if ($request['method'] == 'checkWords') { $result['result'] = $spellchecker->get_words($data); } else if ($request['method'] == 'getSuggestions') { $result['result'] = $spellchecker->get_suggestions($data); } else if ($request['method'] == 'learnWord') { if ($method == 'learnWord') { $spellchecker->add_word($data); $result['result'] = true; } else if ($data) { if (!$spellchecker->check($data)) { $result['words'] = $spellchecker->get(); } } if ($error = $spellchecker->error()) { @@ -51,12 +43,12 @@ 'message' => sprintf("Spell check engine error: " . $error)), true, false); echo '{"error":{"errstr":"' . addslashes($error) . '","errfile":"","errline":null,"errcontext":"","level":"FATAL"}}'; echo json_encode(array('error' => $error)); exit; } // send output header("Content-Type: text/xml; charset=".RCUBE_CHARSET); header("Content-Type: application/json; charset=".RCUBE_CHARSET); echo json_encode($result); exit; skins/classic/common.css
@@ -597,6 +597,10 @@ height: 16px; } .mce-btn button { height: 28px; } /***** common table settings ******/ table.records-table thead tr td skins/classic/functions.js
@@ -543,10 +543,9 @@ w = div.width() - 2, h = div.height(), x = bw.ie || bw.opera ? 4 : 0; $('#compose-body_tbl').width((w+3)+'px').height(''); $('#compose-body_ifr').width((w+3)+'px').height((h-54)+'px'); $('#compose-body').width((w-x)+'px').height(h+'px'); $('#googie_edit_layer').height(h+'px'); $('#compose-body_ifr').width(w+3).height(h-2 - $('div.mce-toolbar').height()); $('#compose-body').width(w-x).height(h); $('#googie_edit_layer').height(h); }, resize_compose_body_ev: function() skins/larry/ui.js
@@ -528,7 +528,7 @@ body.width(w).height(h); $('#composebodycontainer > div').width(w+8).css('margin-top', '1px'); $('#composebody_ifr').height(h + 4 - $('.mce-toolbar-grp').height()); $('#composebody_ifr').height(h + 4 - $('div.mce-toolbar').height()); $('#googie_edit_layer').height(h - 8); // $('#composebodycontainer')[(btns ? 'addClass' : 'removeClass')]('buttons'); // $('#composeformbuttons')[(btns ? 'show' : 'hide')]();