From 1d0eb6678170580180864d385bc58308b721d170 Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Tue, 27 Nov 2012 10:37:14 -0500 Subject: [PATCH] Place caret at proper position in HTML replies Removed constraint in preferences module that would limit the reply placement of HTML mail to be before the quote. We now properly place the caret at the bottom, before the signature, when the user has chosen to start her reply bellow the quote in HTML mode. --- UI/WebServerResources/UIxMailEditor.js | 118 +++++++++++++++++------- UI/WebServerResources/UIxPreferences.js | 33 ++----- 2 files changed, 92 insertions(+), 59 deletions(-) diff --git a/UI/WebServerResources/UIxMailEditor.js b/UI/WebServerResources/UIxMailEditor.js index 830ab25b0..e544b0daf 100644 --- a/UI/WebServerResources/UIxMailEditor.js +++ b/UI/WebServerResources/UIxMailEditor.js @@ -141,16 +141,16 @@ function onValidateDone(onSuccess) { var toolbar = document.getElementById("toolbar"); if (!document.busyAnim) document.busyAnim = startAnimation(toolbar); - + var lastRow = $("lastRow"); lastRow.down("select").name = "popup_last"; - + window.shouldPreserve = true; - + document.pageform.action = "send"; AIM.submit($(document.pageform), {'onComplete' : onPostComplete}); - + if (typeof onSuccess == 'function') onSuccess(); @@ -351,6 +351,49 @@ function onTextMouseDown(event) { } } +function onHTMLFocus(event) { + if (MailEditor.textFirstFocus) { + var s = event.editor.getSelection(); + var selected_ranges = s.getRanges(); + var children = event.editor.document.getBody().getChildren(); + var node; + var caretAtTop = (UserDefaults["SOGoMailReplyPlacement"] == "above") + || !mailIsReply; // for forwards, place caret at top unconditionally + + if (caretAtTop) { + node = children.getItem(0); + } + else { + // Search for signature starting from bottom + node = children.getItem(children.count() - 1); + while (true) { + var x = node.getPrevious(); + if (x == null) { + break; + } + if (x.getText() == '--') { + node = x.getPrevious().getPrevious(); + break; + } + node = x; + } + } + + s.selectElement(node); + + // Place the caret + if (caretAtTop) + s.scrollIntoView(); // top + selected_ranges = s.getRanges(); + selected_ranges[0].collapse(true); + s.selectRanges(selected_ranges); + if (!caretAtTop) + s.scrollIntoView(); // bottom + + MailEditor.textFirstFocus = false; + } +} + function initAddresses() { var addressList = $("addressList"); var i = 1; @@ -395,29 +438,13 @@ function initMailEditor() { var textarea = $("text"); - var textContent = textarea.getValue(); - if (hasSignature()) { - var sigLimit = textContent.lastIndexOf("--"); - if (sigLimit > -1) - MailEditor.signatureLength = (textContent.length - sigLimit); - } - if (UserDefaults["SOGoMailReplyPlacement"] != "above") { - textarea.scrollTop = textarea.scrollHeight; - } - textarea.observe("focus", onTextFocus); - //textarea.observe("mousedown", onTextMouseDown); - textarea.observe("keydown", onTextKeyDown); - - if (Prototype.Browser.IE) { - var ieEvents = [ "click", "select", "keyup" ]; - for (var i = 0; i < ieEvents.length; i++) - textarea.observe(ieEvents[i], onTextIEUpdateCursorPos, false); - } - initAddresses(); - var focusField = (mailIsReply ? textarea : $("addr_0")); - focusField.focus(); + var focusField = textarea; + if (!mailIsReply) { + focusField = $("addr_0"); + focusField.focus(); + } initializePriorityMenu(); @@ -434,6 +461,7 @@ function initMailEditor() { var composeMode = UserDefaults["SOGoMailComposeMessageType"]; if (composeMode == "html") { + // HTML mode CKEDITOR.replace('text', { toolbar : @@ -447,8 +475,37 @@ function initMailEditor() { scayt_sLang : localeCode } ); + CKEDITOR.on('instanceReady', function(event) { + if (focusField == textarea) + // CKEditor reports being ready but it's still not focusable; + // we wait for a few more milliseconds + setTimeout("CKEDITOR.instances.text.focus()", 500); + }); + CKEDITOR.instances.text.on('focus', onHTMLFocus); + } + else { + // Plain text mode + var textContent = textarea.getValue(); + if (hasSignature()) { + var sigLimit = textContent.lastIndexOf("--"); + if (sigLimit > -1) + MailEditor.signatureLength = (textContent.length - sigLimit); + } + if (UserDefaults["SOGoMailReplyPlacement"] != "above") { + textarea.scrollTop = textarea.scrollHeight; + } + textarea.observe("focus", onTextFocus); + //textarea.observe("mousedown", onTextMouseDown); + textarea.observe("keydown", onTextKeyDown); + + if (Prototype.Browser.IE) { + var ieEvents = [ "click", "select", "keyup" ]; + for (var i = 0; i < ieEvents.length; i++) + textarea.observe(ieEvents[i], onTextIEUpdateCursorPos, false); + } + if (focusField == textarea) - focusCKEditor(); + textarea.focus(); } $("contactFolder").observe("change", onContactFolderChange); @@ -459,15 +516,6 @@ function initMailEditor() { onWindowResize.defer(); } -function focusCKEditor(event) { - if (CKEDITOR.status != 'basic_ready') - setTimeout("focusCKEditor()", 100); - else - // CKEditor reports being ready but it's still not focusable; - // we wait for a few more milliseconds - setTimeout("CKEDITOR.instances.text.focus()", 500); -} - function initializePriorityMenu() { var priority = $("priority").value.toUpperCase(); var priorityMenu = $("priorityMenu").childNodesWithTag("ul")[0]; diff --git a/UI/WebServerResources/UIxPreferences.js b/UI/WebServerResources/UIxPreferences.js index e19c07fb0..b9d61c7fd 100644 --- a/UI/WebServerResources/UIxPreferences.js +++ b/UI/WebServerResources/UIxPreferences.js @@ -127,10 +127,10 @@ function _setupEvents() { // We check for non-null elements as replyPlacementList and composeMessagesType // might not be present if ModulesConstraints disable those elements if ($("replyPlacementList")) - $("replyPlacementList").observe("change", onReplyPlacementListChange); + $("replyPlacementList").on("change", onReplyPlacementListChange); if ($("composeMessagesType")) - $("composeMessagesType").observe("change", onComposeMessagesTypeChange); + $("composeMessagesType").on("change", onComposeMessagesTypeChange); // Note: we also monitor changes to the calendar categories. // See functions endEditable and onColorPickerChoice. @@ -205,25 +205,9 @@ function initPreferences() { $("contactsCategoryDelete").observe("click", onContactsCategoryDelete); } - // Disable placement (after) if composing in HTML - var button = $("composeMessagesType"); - if (button) { - if (button.value == 1) { - $("replyPlacementList").value = 0; - $("replyPlacementList").disabled = true; - } - onReplyPlacementListChange(); - button.on("change", function(event) { - if (this.value == 0) - $("replyPlacementList").disabled = false; - else { - $("replyPlacementList").value = 0; - $("replyPlacementList").disabled = true; - } - }); - } + onReplyPlacementListChange(); - button = $("addDefaultEmailAddresses"); + var button = $("addDefaultEmailAddresses"); if (button) button.observe("click", addDefaultEmailAddresses); @@ -1029,13 +1013,14 @@ function serializeContactsCategories() { function onReplyPlacementListChange() { - // above = 0 if ($("replyPlacementList").value == 0) { - $("signaturePlacementList").disabled=false; + // Reply placement is above quote, signature can be place before of after quote + $("signaturePlacementList").disabled = false; } else { - $("signaturePlacementList").value=1; - $("signaturePlacementList").disabled=true; + // Reply placement is bellow quote, signature is unconditionally placed after quote + $("signaturePlacementList").value = 1; + $("signaturePlacementList").disabled = true; } }