From 83d040002c1ffca8efaa72737b492fc911f54573 Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Fri, 9 Apr 2021 11:21:09 -0300 Subject: [PATCH 1/8] Hotfix for the default email in the SMTP list when using the mailing list options --- modules/smtp/modules.php | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index 9c1bf4a547..109a4aa5c5 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -708,10 +708,28 @@ protected function output() { $res .= format_attachment_row($file, $this); } - // If compose_from GET parameter is set, force $recip replacement. - // This ensures any module can force the selected dropdown SMTP server + // If compose_from GET parameter is set, search for the correct smtp_id + // within the SMTP profiles. + // + // Added latency reduction 'break' for big smtp profile lists if ($from) { - $recip = $from; + $profiles = $this->module_output()['smtp_servers']; + foreach ($profiles as $id => $profile) { + if ($profile['user'] == $from) { + $smtp_id = $id; + break; + } + // Profile users without the domain + if ($profile['user'] == explode('@', $from)[0]) { + $smtp_id = $id; + break; + } + // Some users might use the profile name as the full email + if ($profile['name'] == $from) { + $smtp_id = $id; + break; + } + } } $res .= ''. From 6b55ae0fe4193a5b48f2c202fe6d6e5c6f744761 Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Fri, 9 Apr 2021 11:24:15 -0300 Subject: [PATCH 2/8] Removed excess breaks for better code readability --- modules/smtp/modules.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index 109a4aa5c5..90a3a77d61 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -717,16 +717,16 @@ protected function output() { foreach ($profiles as $id => $profile) { if ($profile['user'] == $from) { $smtp_id = $id; - break; } // Profile users without the domain if ($profile['user'] == explode('@', $from)[0]) { $smtp_id = $id; - break; } // Some users might use the profile name as the full email if ($profile['name'] == $from) { $smtp_id = $id; + } + if ($smtp_id) { break; } } From 81bf9fd1157bd6637a89c6de14a6e0232f1caf32 Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Fri, 9 Apr 2021 13:00:04 -0300 Subject: [PATCH 3/8] draft_smtp must be filtered as string and not float --- modules/smtp/setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/smtp/setup.php b/modules/smtp/setup.php index 6c7dcbe788..0789259886 100644 --- a/modules/smtp/setup.php +++ b/modules/smtp/setup.php @@ -134,7 +134,7 @@ 'draft_body' => FILTER_UNSAFE_RAW, 'draft_subject' => FILTER_UNSAFE_RAW, 'draft_to' => FILTER_UNSAFE_RAW, - 'draft_smtp' => FILTER_VALIDATE_FLOAT, + 'draft_smtp' => FILTER_SANITIZE_STRING, 'draft_cc' => FILTER_UNSAFE_RAW, 'draft_bcc' => FILTER_UNSAFE_RAW, 'draft_in_reply_to' => FILTER_UNSAFE_RAW, From b74ca2506d6ff49396a5de53efce60cfcbad723d Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Fri, 9 Apr 2021 14:01:45 -0300 Subject: [PATCH 4/8] Implemented the draft settings back to imap_folders --- modules/imap_folders/setup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/imap_folders/setup.php b/modules/imap_folders/setup.php index a91f75ab32..3fb8e4f490 100644 --- a/modules/imap_folders/setup.php +++ b/modules/imap_folders/setup.php @@ -26,7 +26,7 @@ add_output('folders', 'folders_trash_dialog', true, 'imap_folders', 'folders_delete_dialog', 'after'); add_output('folders', 'folders_sent_dialog', true, 'imap_folders', 'folders_trash_dialog', 'after'); add_output('folders', 'folders_archive_dialog', true, 'imap_folders', 'folders_sent_dialog', 'after'); -//add_output('folders', 'folders_draft_dialog', true, 'imap_folders', 'folders_sent_dialog', 'after'); +add_output('folders', 'folders_draft_dialog', true, 'imap_folders', 'folders_sent_dialog', 'after'); add_handler('compose', 'special_folders', true, 'imap_folders', 'load_user_data', 'after'); From e2cce196cc9473e05a24f0ecb49f9fa44b833c03 Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Fri, 9 Apr 2021 15:22:00 -0300 Subject: [PATCH 5/8] Base implementation for IMAP drafts --- modules/smtp/modules.php | 67 ++++++++++++++++++++++++++++++++++++++++ modules/smtp/setup.php | 1 + 2 files changed, 68 insertions(+) diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index 90a3a77d61..d5c8c390ff 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -166,6 +166,18 @@ public function process() { delete_draft($draft_id, $this->session); } else { + if ($this->module_is_supported('imap')) { + if (save_imap_draft(array('draft_smtp' => $smtp, 'draft_to' => $to, 'draft_body' => $body, + 'draft_subject' => $subject, 'draft_cc' => $cc, 'draft_bcc' => $bcc, + 'draft_in_reply_to' => $inreplyto), $draft_id, $this->session, + $this, $this->cache)) { + Hm_Msgs::add('Draft saved'); + } elseif ($draft_notice) { + Hm_Msgs::add('ERRYou must enter a subject to save a draft'); + } + return; + } + if (save_draft(array('draft_smtp' => $smtp, 'draft_to' => $to, 'draft_body' => $body, 'draft_subject' => $subject, 'draft_cc' => $cc, 'draft_bcc' => $bcc, 'draft_in_reply_to' => $inreplyto), $draft_id, $this->session) !== false) { @@ -1148,6 +1160,61 @@ function save_draft($atts, $id, $session) { return $id; }} +/** + * @subpackage smtp/functions + */ +if (!hm_exists('find_imap_by_smtp')) { +function find_imap_by_smtp($imap_profiles, $smtp_profile) +{ + foreach ($imap_profiles as $id => $profile) { + if ($smtp_profile['user'] == $profile['user']) { + return array_merge(['id' => $id], $profile); + } + if (explode('@', $smtp_profile['user'])[0] + == explode('@', $profile['user'])[0]) { + return array_merge(['id' => $id], $profile); + } + if ($smtp_profile['user'] == $profile['name']) { + return array_merge(['id' => $id], $profile); + } + } +}} + +/** + * @subpackage smtp/functions + */ +if (!hm_exists('save_imap_draft')) { +function save_imap_draft($atts, $id, $session, $mod, $mod_cache) { + $imap_profile = find_imap_by_smtp($mod->user_config->get('imap_servers'), + $mod->user_config->get('smtp_servers')[$atts['draft_smtp']]); + + $specials = $mod->user_config->get('special_imap_folders'); + + if (array_key_exists($imap_profile['id'], $specials) && + $specials[$imap_profile['id']]['draft']) { + $cache = Hm_IMAP_List::get_cache($mod_cache, $imap_profile['id']); + $imap = Hm_IMAP_List::connect($imap_profile['id'], $cache); + $draft_folder = $imap->select_mailbox($specials[$imap_profile['id']]['draft']); + + $mime = new Hm_MIME_Msg($atts['draft_to'], $atts['draft_subject'], $atts['draft_body'], + $mod->user_config->get('smtp_servers')[$atts['draft_smtp']]['user'], + 0, $atts['draft_cc'], $atts['draft_bcc'], $atts['draft_bcc'], $atts['draft_in_reply_to']); + + $msg = str_replace("\r\n", "\n", $mime->get_mime_msg()); + $msg = str_replace("\n", "\r\n", $msg); + $msg = rtrim($msg)."\r\n"; + + if ($imap->append_start($specials[$imap_profile['id']]['draft'], strlen($msg), true)) { + $imap->append_feed($msg."\r\n"); + if (!$imap->append_end()) { + Hm_Msgs::add('ERRAn error occurred saving the sent message'); + } + } + return 1; + } + return save_draft($atts, $id, $session); +}} + /** * @subpackage smtp/functions */ diff --git a/modules/smtp/setup.php b/modules/smtp/setup.php index 0789259886..8c255ec46e 100644 --- a/modules/smtp/setup.php +++ b/modules/smtp/setup.php @@ -50,6 +50,7 @@ add_handler('ajax_smtp_debug', 'http_headers', true, 'core'); /* save draft ajax request */ +add_handler('ajax_smtp_save_draft', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after'); add_handler('ajax_smtp_save_draft', 'login', false, 'core'); add_handler('ajax_smtp_save_draft', 'load_user_data', true, 'core'); add_handler('ajax_smtp_save_draft', 'smtp_save_draft', true); From cee45de7e570a907f7a12da222595d55ea1154a6 Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Fri, 9 Apr 2021 15:47:57 -0300 Subject: [PATCH 6/8] Fixed error messsage text in save_imap_draft when append_end return false --- modules/smtp/modules.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index d5c8c390ff..f0118ea581 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -1207,7 +1207,7 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache) { if ($imap->append_start($specials[$imap_profile['id']]['draft'], strlen($msg), true)) { $imap->append_feed($msg."\r\n"); if (!$imap->append_end()) { - Hm_Msgs::add('ERRAn error occurred saving the sent message'); + Hm_Msgs::add('ERRAn error occurred saving the draft message'); } } return 1; From 34e4fe1106365f06d19740c957b7efa21dd91c06 Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Fri, 16 Apr 2021 13:59:49 -0300 Subject: [PATCH 7/8] Draft compose and labels --- modules/core/message_list_functions.php | 4 ++ modules/imap/functions.php | 7 ++- modules/imap/hm-imap.php | 6 +- modules/smtp/modules.php | 74 ++++++++++++++++++++++++- modules/smtp/setup.php | 2 + 5 files changed, 88 insertions(+), 5 deletions(-) diff --git a/modules/core/message_list_functions.php b/modules/core/message_list_functions.php index 47ffd723a4..efbba7e2f5 100644 --- a/modules/core/message_list_functions.php +++ b/modules/core/message_list_functions.php @@ -296,6 +296,10 @@ function icon_callback($vals, $style, $output_mod) { $icons .= $show_icons ? ''.$output_mod->trans('Flagged').'' : ' F'; $title[] = $output_mod->trans('Flagged'); } + if (in_array('draft', $vals[0])) { + $icons .= $show_icons ? ''.$output_mod->trans('Draft').'' : ' D'; + $title[] = $output_mod->trans('Draft'); + } if (in_array('answered', $vals[0])) { $icons .= $show_icons ? ''.$output_mod->trans('Answered').'' : ' A'; $title[] = $output_mod->trans('Answered'); diff --git a/modules/imap/functions.php b/modules/imap/functions.php index f3033a2dc0..9af6cd734b 100644 --- a/modules/imap/functions.php +++ b/modules/imap/functions.php @@ -221,7 +221,7 @@ function format_imap_message_list($msg_list, $output_module, $parent_list=false, $from = preg_replace("/(\<.+\>)/U", '', $msg['to']); $icon = 'sent'; } - foreach (array('attachment', 'deleted', 'flagged', 'answered') as $flag) { + foreach (array('attachment', 'deleted', 'flagged', 'answered', 'draft') as $flag) { if (stristr($msg['flags'], $flag)) { $flags[] = $flag; } @@ -244,6 +244,11 @@ function format_imap_message_list($msg_list, $output_module, $parent_list=false, if (!$show_icons) { $icon = false; } + + if (in_array('draft', $flags)) { + $url = '?page=compose&list_path='.sprintf('imap_%s_%s', $msg['server_id'], $msg['folder']).'&uid='.$msg['uid'].'&imap_draft=1'; + } + if ($style == 'news') { $res[$id] = message_list_row(array( array('checkbox_callback', $id), diff --git a/modules/imap/hm-imap.php b/modules/imap/hm-imap.php index 45efffba87..dc8e65fd9c 100644 --- a/modules/imap/hm-imap.php +++ b/modules/imap/hm-imap.php @@ -897,7 +897,6 @@ private function parse_bodystructure_response($result) { * get content for a message part * @param int $uid a single IMAP message UID * @param string $message_part the IMAP message part number - * @param bool $raw flag to enabled fetching the entire message as text * @param int $max maximum read length to allow. * @param mixed $struct a message part structure array for decoding and * charset conversion. bool true for auto discovery @@ -1595,7 +1594,7 @@ public function message_action($action, $uids, $mailbox=false, $keyword=false) { * @param bool $seen flag to mark the message seen * $return bool true on success */ - public function append_start($mailbox, $size, $seen=true) { + public function append_start($mailbox, $size, $seen=true, $draft=false) { if (!$this->is_clean($mailbox, 'mailbox') || !$this->is_clean($size, 'uid')) { return false; } @@ -1605,6 +1604,9 @@ public function append_start($mailbox, $size, $seen=true) { else { $command = 'APPEND "'.$this->utf7_encode($mailbox).'" () {'.$size."}\r\n"; } + if ($draft) { + $command = 'APPEND "'.$this->utf7_encode($mailbox).'" (\Draft) {'.$size."}\r\n"; + } $this->send_command($command); $result = $this->fgets(); if (substr($result, 0, 1) == '+') { diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index f0118ea581..90e97b56b4 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -31,6 +31,50 @@ public function process() { } } +/** + * @subpackage smtp/handler + */ +class Hm_Handler_load_smtp_is_imap_draft extends Hm_Handler_Module { + public function process() { + if (!$this->module_is_supported('imap')) { + Hm_Msgs::add('ERRIMAP module unavailable.'); + return; + } + if (array_key_exists('imap_draft', $this->request->get) + && array_key_exists('list_path', $this->request->get) + && array_key_exists('uid', $this->request->get)) { + $path = explode('_', $this->request->get['list_path']); + + $imap = Hm_IMAP_List::connect($path[1]); + if ($imap->select_mailbox(hex2bin($path[2]))) { + $msg_struct = $imap->get_message_structure($this->request->get['uid']); + list($part, $msg_text) = $imap->get_first_message_part($this->request->get['uid'], 'text', 'plain', $msg_struct); + $msg_header = $imap->get_message_headers($this->request->get['uid']); + + $imap_draft = array( + 'From' => $msg_header['From'], + 'To' => $msg_header['To'], + 'Subject' => $msg_header['Subject'], + 'Message-Id' => $msg_header['Message-Id'], + 'Content-Type' => $msg_header['Content-Type'], + 'Body' => $msg_text + ); + + if (array_key_exists('Cc', $msg_header)) { + $imap_draft['Cc'] = $msg_header['Cc']; + } + + if ($imap_draft) { + $this->out('draft_id', $this->request->get['uid']); + $this->out('imap_draft', $imap_draft); + } + return; + } + Hm_Msgs::add('ERRCould not load the IMAP mailbox.'); + } + } +} + /** * @subpackage smtp/handler */ @@ -631,6 +675,7 @@ protected function output() { $draft = $this->get('compose_draft', array()); $reply = $this->get('reply_details', array()); + $imap_draft = $this->get('imap_draft', array()); $reply_type = $this->get('reply_type', ''); $html = $this->get('smtp_compose_type', 0); $msg_path = $this->get('list_path', ''); @@ -645,6 +690,7 @@ protected function output() { } $smtp_id = false; $draft_id = $this->get('compose_draft_id', 0); + if (!empty($reply)) { list($to, $cc, $subject, $body, $in_reply_to) = format_reply_fields( $reply['msg_text'], $reply['msg_headers'], $reply['msg_struct'], $html, $this, $reply_type); @@ -652,7 +698,8 @@ protected function output() { $recip = get_primary_recipient($this->get('compose_profiles', array()), $reply['msg_headers'], $this->get('smtp_servers', array())); } - elseif (!empty($draft)) { + + if (!empty($draft)) { if (array_key_exists('draft_to', $draft)) { $to = $draft['draft_to']; } @@ -675,6 +722,23 @@ protected function output() { $bcc = $draft['draft_bcc']; } } + + if ($imap_draft) { + if (array_key_exists('Body', $imap_draft)) { + $body= $imap_draft['Body']; + } + if (array_key_exists('To', $imap_draft)) { + $to= $imap_draft['To']; + } + if (array_key_exists('Subject', $imap_draft)) { + $subject= $imap_draft['Subject']; + } + if (array_key_exists('Cc', $imap_draft)) { + $cc= $imap_draft['Cc']; + } + $draft_id = $msg_uid; + } + $send_disabled = ''; if (count($this->get('smtp_servers', array())) == 0) { $send_disabled = 'disabled="disabled" '; @@ -1204,12 +1268,18 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache) { $msg = str_replace("\n", "\r\n", $msg); $msg = rtrim($msg)."\r\n"; - if ($imap->append_start($specials[$imap_profile['id']]['draft'], strlen($msg), true)) { + if ($imap->append_start($specials[$imap_profile['id']]['draft'], strlen($msg), false, true)) { $imap->append_feed($msg."\r\n"); if (!$imap->append_end()) { Hm_Msgs::add('ERRAn error occurred saving the draft message'); } } + + // Remove old version from the mailbox + if ($id) { + $imap->message_action('DELETE', array($id)); + } + return 1; } return save_draft($atts, $id, $session); diff --git a/modules/smtp/setup.php b/modules/smtp/setup.php index 8c255ec46e..cf29f22b64 100644 --- a/modules/smtp/setup.php +++ b/modules/smtp/setup.php @@ -7,6 +7,7 @@ add_module_to_all_pages('handler', 'smtp_default_server', true, 'smtp', 'load_user_data', 'after'); add_handler('compose', 'load_smtp_reply_to_details', true, 'smtp', 'load_user_data', 'after'); +add_handler('compose', 'load_smtp_is_imap_draft', true, 'smtp', 'load_user_data', 'after'); add_handler('compose', 'smtp_from_replace', true, 'smtp', 'load_user_data', 'after'); add_handler('compose', 'load_smtp_servers_from_config', true, 'smtp', 'load_smtp_reply_to_details', 'after'); add_handler('compose', 'add_smtp_servers_to_page_data', true, 'smtp', 'load_smtp_servers_from_config', 'after'); @@ -93,6 +94,7 @@ 'ajax_smtp_delete_draft' ), 'allowed_get' => array( + 'imap_draft' => FILTER_VALIDATE_INT, 'reply' => FILTER_VALIDATE_INT, 'reply_all' => FILTER_VALIDATE_INT, 'forward' => FILTER_VALIDATE_INT, From c5ef783af7caeede1133638e914a2cdaaabc2beb Mon Sep 17 00:00:00 2001 From: Henrique Borba Date: Tue, 27 Apr 2021 13:25:06 -0300 Subject: [PATCH 8/8] Draft editing implementation --- modules/smtp/hm-mime-message.php | 6 +++++- modules/smtp/modules.php | 25 +++++++++++++++++++------ modules/smtp/site.js | 11 +++++++---- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/modules/smtp/hm-mime-message.php b/modules/smtp/hm-mime-message.php index 6206c135f1..0c2c8dca8a 100644 --- a/modules/smtp/hm-mime-message.php +++ b/modules/smtp/hm-mime-message.php @@ -50,6 +50,11 @@ function __construct($to, $subject, $body, $from, $html=false, $cc='', $bcc='', $this->body = $body; } + /* return headers array */ + function get_headers() { + return $this->headers; + } + /* add attachments */ function add_attachments($files) { $this->attachments = $files; @@ -267,4 +272,3 @@ function qp_encode($string) { return str_replace('.', '=2E', quoted_printable_encode($string)); } } - diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index 90e97b56b4..a21b41c3a4 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -150,7 +150,7 @@ public function process() { if (!is_readable($file['tmp_name'])) { if($file['error'] == 1) { $upload_max_filesize = ini_get('upload_max_filesize'); - Hm_Msgs::add('ERRYour upload failed because you reached the limit of ' . $upload_max_filesize . '.'); + Hm_Msgs::add('ERRYour upload failed because you reached the limit of ' . $upload_max_filesize . '.'); return; } Hm_Msgs::add('ERRAn error occurred saving the uploaded file.'); @@ -211,11 +211,13 @@ public function process() { } else { if ($this->module_is_supported('imap')) { - if (save_imap_draft(array('draft_smtp' => $smtp, 'draft_to' => $to, 'draft_body' => $body, + $new_draft_id = save_imap_draft(array('draft_smtp' => $smtp, 'draft_to' => $to, 'draft_body' => $body, 'draft_subject' => $subject, 'draft_cc' => $cc, 'draft_bcc' => $bcc, 'draft_in_reply_to' => $inreplyto), $draft_id, $this->session, - $this, $this->cache)) { + $this, $this->cache); + if ($new_draft_id) { Hm_Msgs::add('Draft saved'); + $this->out('draft_id', $new_draft_id); } elseif ($draft_notice) { Hm_Msgs::add('ERRYou must enter a subject to save a draft'); } @@ -950,7 +952,7 @@ protected function output() { $res .= '
'; $res .= sprintf('
%s
%s/%d %s
', $this->html_safe($vals['name']), $this->html_safe($vals['server']), $this->html_safe($vals['port']), $vals['tls'] ? 'TLS' : '' ); - $res .= + $res .= '
'. ''. ' '. @@ -1272,15 +1274,26 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache) { $imap->append_feed($msg."\r\n"); if (!$imap->append_end()) { Hm_Msgs::add('ERRAn error occurred saving the draft message'); + return 0; } } + $mailbox_page = $imap->get_mailbox_page($specials[$imap_profile['id']]['draft'], 'ARRIVAL', true, 'DRAFT', 0, 10); + // Remove old version from the mailbox if ($id) { - $imap->message_action('DELETE', array($id)); + $imap->message_action('DELETE', array($id)); } - return 1; + foreach ($mailbox_page[1] as $mail) { + $msg_header = $imap->get_message_headers($mail['uid']); + if ($msg_header['Message-Id'] === $mime->get_headers()['Message-Id']) + { + return $mail['uid']; + } + } + + return 0; } return save_draft($atts, $id, $session); }} diff --git a/modules/smtp/site.js b/modules/smtp/site.js index 473a19006c..667f99fd21 100644 --- a/modules/smtp/site.js +++ b/modules/smtp/site.js @@ -127,6 +127,9 @@ var save_compose_state = function(no_files, notice) { function(res) { $('.smtp_send').prop('disabled', false); $('.smtp_send').removeClass('disabled_input'); + if (res.draft_id) { + $('.compose_draft_id').val(res.draft_id); + } if (res.draft_subject) { $('.draft_list .draft_'+draft_id+' a').text(res.draft_subject); } @@ -180,7 +183,7 @@ var upload_file = function(file) { xhr.open('POST', '', true); xhr.setRequestHeader('X-Requested-With', 'xmlhttprequest'); xhr.onreadystatechange = function() { - if (xhr.readyState == 4){ + if (xhr.readyState == 4){ if (hm_encrypt_ajax_requests()) { res = Hm_Utils.json_decode(xhr.responseText); res = Hm_Utils.json_decode(Hm_Crypt.decrypt(res.payload)); @@ -210,10 +213,10 @@ var delete_attachment = function(file, link) { return false; }; -var replace_cursor_positon = function (txtElement) { +var replace_cursor_positon = function (txtElement) { txtElement.val('\r\n\r\n\r\n'+txtElement.val()); txtElement.prop('selectionEnd',0); - txtElement.focus(); + txtElement.focus(); } $(function() { @@ -240,5 +243,5 @@ $(function() { save_compose_state(); }, 100); } - } + } });