Bug 201581 - Top-signature results in body being deleted. Option to not strip sigs on reply. r=benb
authorMagnus Melin <mkmelin+mozilla@iki.fi>
Wed, 11 Dec 2013 21:36:33 +0200
changeset 17077 c8a8ba69b2be7e96e661301361133db469f1903d
parent 17076 840b157215fa6d7411ccacd5938eace862bfa6e9
child 17078 e979c0479a3430c8eaf16ef2a6c201cf350f01a6
push idunknown
push userunknown
push dateunknown
reviewersbenb
bugs201581
Bug 201581 - Top-signature results in body being deleted. Option to not strip sigs on reply. r=benb
mail/test/mozmill/composition/test-reply-signature.js
mailnews/mailnews.js
mailnews/mime/src/mimetpfl.cpp
mailnews/mime/src/mimetpfl.h
mailnews/mime/src/mimetpla.cpp
mailnews/mime/src/mimetpla.h
new file mode 100644
--- /dev/null
+++ b/mail/test/mozmill/composition/test-reply-signature.js
@@ -0,0 +1,106 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Tests the mail.strip_sig_on_reply pref.
+ */
+
+// make SOLO_TEST=composition/test-reply-signature.js mozmill-one
+
+const MODULE_NAME = "test-reply-signature";
+
+const RELATIVE_ROOT = "../shared-modules";
+const MODULE_REQUIRES = ["folder-display-helpers", "compose-helpers", "window-helpers",
+                         "message-helpers"];
+var jumlib = {};
+Components.utils.import("resource://mozmill/modules/jum.js", jumlib);
+var elib = {};
+Components.utils.import("resource://mozmill/modules/elementslib.js", elib);
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+const sig = "roses are red";
+var folder;
+
+function setupModule(module) {
+    for (let req of MODULE_REQUIRES) {
+    collector.getModule(req).installInto(module);
+  }
+
+  folder = create_folder("SigStripTest");
+
+  let msg = create_message({
+    subject: "msg with signature; format=flowed",
+    body: {
+      body: "get with the flow! get with the flow! get with the flow! " +
+        "get with the \n flow! get with the flow!\n-- \n" + sig + "\n",
+      contentType: "text/plain",
+      charset: "UTF-8",
+      format: "flowed"
+    }
+  });
+  add_message_to_folder(folder, msg);
+  let msg2 = create_message({
+    subject: "msg with signature; format not flowed",
+    body: {
+      body: "not flowed! not flowed! not flowed! \n" +
+        "not flowed!\n-- \n" + sig + "\n",
+      contentType: "text/plain",
+      charset: "UTF-8",
+      format: ""
+    }
+  });
+  add_message_to_folder(folder, msg2);
+};
+
+/** Test sig strip true for format flowed. */
+function test_sig_strip_true_ff() {
+  Services.prefs.setBoolPref("mail.strip_sig_on_reply", true);
+  check_sig_strip_works(0, true);
+  Services.prefs.clearUserPref("mail.strip_sig_on_reply");
+}
+
+/** Test sig strip false for format flowed. */
+function test_sig_strip_false_ff() {
+  Services.prefs.setBoolPref("mail.strip_sig_on_reply", false);
+  check_sig_strip_works(0, false);
+  Services.prefs.clearUserPref("mail.strip_sig_on_reply");
+}
+
+/** Test sig strip true for non-format flowed. */
+function test_sig_strip_true_nonff() {
+  Services.prefs.setBoolPref("mail.strip_sig_on_reply", true);
+  check_sig_strip_works(1, true);
+  Services.prefs.clearUserPref("mail.strip_sig_on_reply");
+}
+
+/** Test sig strip false for non-format flowed. */
+function test_sig_strip_false_nonff() {
+  Services.prefs.setBoolPref("mail.strip_sig_on_reply", false);
+  check_sig_strip_works(1, false);
+  Services.prefs.clearUserPref("mail.strip_sig_on_reply");
+}
+
+/**
+ * Helper function to check signature stripping works as it should.
+ * @param aRow the row index of the message to test
+ * @param aShouldStrip true if the signature should be stipped
+ */
+function check_sig_strip_works(aRow, aShouldStrip) {
+  be_in_folder(folder);
+  let msg = select_click_row(aRow);
+  assert_selected_and_displayed(mc, msg);
+
+  let rwc = open_compose_with_reply();
+  let body = get_compose_body(rwc);
+
+  if (aShouldStrip && body.textContent.contains(sig)) {
+    throw new Error("signature was not stripped; body=" + body.textContent);
+  }
+  else if (!aShouldStrip && !body.textContent.contains(sig)) {
+    throw new Error("signature stripped; body=" + body.textContent);
+  }
+  close_compose_window(rwc);
+}
+
+
--- a/mailnews/mailnews.js
+++ b/mailnews/mailnews.js
@@ -109,16 +109,17 @@ pref("mail.imap.hdr_chunk_size", 200);
 // identity when acting on messages in other users folders.
 pref("mail.imap.delegateOtherUsersFolders", false);
 pref("mail.thread_without_re",              false); // if false, only thread by subject if Re:
 pref("mail.strict_threading",               true);  // if true, don't thread by subject at all
 pref("mail.correct_threading",              true);  // if true, makes sure threading works correctly always (see bug 181446)
 pref("mail.pop3.deleteFromServerOnMove",    false);
 pref("mail.fixed_width_messages",           true);
 pref("mail.citation_color",                 "#000000"); // quoted color
+pref("mail.strip_sig_on_reply", true); // If true, remove the everything after the "-- \n" signature delimiter when replying.
 pref("mail.quoted_style",                   0); // 0=plain, 1=bold, 2=italic, 3=bolditalic
 pref("mail.quoted_size",                    0); // 0=normal, 1=big, 2=small
 pref("mail.quoted_graphical",               true); // use HTML-style quoting for displaying plain text
 pref("mail.quoteasblock",                   true); // use HTML-style quoting for quoting plain text
 pref("mail.strictly_mime",                  false);
 pref("mail.strictly_mime_headers",          true);
 // 0/1 (name param is encoded in a legacy way), 2(RFC 2231 only)
 // 0 the name param is never separated to multiple lines.
--- a/mailnews/mime/src/mimetpfl.cpp
+++ b/mailnews/mime/src/mimetpfl.cpp
@@ -107,23 +107,25 @@ MimeInlineTextPlainFlowed_parse_begin (M
 
   // Get Prefs for viewing
 
   exdata->fixedwidthfont = false;
   //  Quotes
   text->mQuotedSizeSetting = 0;   // mail.quoted_size
   text->mQuotedStyleSetting = 0;  // mail.quoted_style
   text->mCitationColor = nullptr;  // mail.citation_color
+  text->mStripSig = true; // mail.strip_sig_on_reply
 
   nsIPrefBranch *prefBranch = GetPrefBranch(obj->options);
   if (prefBranch)
   {
     prefBranch->GetIntPref("mail.quoted_size", &(text->mQuotedSizeSetting));
     prefBranch->GetIntPref("mail.quoted_style", &(text->mQuotedStyleSetting));
     prefBranch->GetCharPref("mail.citation_color", &(text->mCitationColor));
+    prefBranch->GetBoolPref("mail.strip_sig_on_reply", &(text->mStripSig));
     nsresult rv = prefBranch->GetBoolPref("mail.fixed_width_messages",
                                           &(exdata->fixedwidthfont));
     NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get pref");
          // Check at least the success of one
   }
 
   // Get font
   // only used for viewing (!plainHTML)
@@ -305,17 +307,17 @@ MimeInlineTextPlainFlowed_parse_line (co
     index--;
   }
   if (index > linep - line && ' ' == line[index])
        /* Ignore space stuffing, i.e. lines with just
           (quote marks and) a space count as empty */
   {
     flowed = true;
     sigSeparator = (index - (linep - line) + 1 == 3) && !strncmp(linep, "-- ", 3);
-    if (((MimeInlineTextPlainFlowed *) obj)->delSp && ! sigSeparator)
+    if (((MimeInlineTextPlainFlowed *) obj)->delSp && !sigSeparator)
        /* If line is flowed and DelSp=yes, logically
           delete trailing space. Line consisting of
           dash dash space ("-- "), commonly used as
           signature separator, gets special handling
           (RFC 3676) */
     {
       length--;
       line[index] = '\0';
@@ -390,21 +392,22 @@ MimeInlineTextPlainFlowed_parse_line (co
   if((quoteleveldiff != 0) && flowed && exdata->inflow) {
     // From RFC 2646 4.5
     // The receiver SHOULD handle this error by using the 'quote-depth-wins' rule,
     // which is to ignore the flowed indicator and treat the line as fixed.  That
     // is, the change in quote depth ends the paragraph.
 
     // We get that behaviour by just going on.
   }
+
+  // Cast so we have access to the prefs we need.
+  MimeInlineTextPlainFlowed *tObj = (MimeInlineTextPlainFlowed *) obj;
   while(quoteleveldiff>0) {
     quoteleveldiff--;
     preface += "<blockquote type=cite";
-    // This is to have us observe the user pref settings for citations
-    MimeInlineTextPlainFlowed *tObj = (MimeInlineTextPlainFlowed *) obj;
 
     nsAutoCString style;
     MimeTextBuildPrefixCSS(tObj->mQuotedSizeSetting, tObj->mQuotedStyleSetting,
                            tObj->mCitationColor, style);
     if (!plainHTML && !style.IsEmpty())
     {
       preface += " style=\"";
       preface += style;
@@ -445,34 +448,33 @@ MimeInlineTextPlainFlowed_parse_line (co
                             !plainHTML && !obj->options->wrap_long_lines_p
                               /* If wrap, convert all spaces but the last in
                                  a row into nbsp, otherwise all. */,
                             lineResult2);
     lineResult2.AppendLiteral("<br>");
     exdata->inflow = false;
   } // End Fixed line
 
-  if (!(exdata->isSig && quoting))
+  if (!(exdata->isSig && quoting && tObj->mStripSig))
   {
     status = MimeObject_write(obj, preface.get(), preface.Length(), true);
     if (status < 0) return status;
     nsAutoCString outString;
     if (obj->options->format_out != nsMimeOutput::nsMimeMessageSaveAs ||
         !mailCharset || !*mailCharset)
       CopyUTF16toUTF8(lineResult2, outString);
     else
     { // convert back to mailCharset before writing.
       rv = nsMsgI18NConvertFromUnicode(mailCharset, lineResult2, outString);
       NS_ENSURE_SUCCESS(rv, -1);
     }
     status = MimeObject_write(obj, outString.get(), outString.Length(), true);
     return status;
   }
-  else
-    return 0;
+  return 0;
 }
 
 
 /**
  * Maintains a small state machine with three states. "Not in tag",
  * "In tag, but not in quote" and "In quote inside a tag". It also
  * remembers what character started the quote (" or '). The state
  * variables are kept outside this function and are included as
--- a/mailnews/mime/src/mimetpfl.h
+++ b/mailnews/mime/src/mimetpfl.h
@@ -25,16 +25,17 @@ struct MimeInlineTextPlainFlowedClass {
 extern MimeInlineTextPlainFlowedClass mimeInlineTextPlainFlowedClass;
 
 struct MimeInlineTextPlainFlowed {
   MimeInlineText  text;
   bool            delSp;                // DelSp=yes (RFC 3676)
   int32_t         mQuotedSizeSetting;   // mail.quoted_size
   int32_t         mQuotedStyleSetting;  // mail.quoted_style
   char            *mCitationColor;      // mail.citation_color
+  bool            mStripSig;            // mail.strip_sig_on_reply
 };
 
 
 /*
  * Made to contain information to be kept during the whole message parsing.
  */
 struct MimeInlineTextPlainFlowedExData {
   struct MimeObject *ownerobj; /* The owner of this struct */
--- a/mailnews/mime/src/mimetpla.cpp
+++ b/mailnews/mime/src/mimetpla.cpp
@@ -110,24 +110,26 @@ MimeInlineTextPlain_parse_begin (MimeObj
 
       // Quoting
       text->mBlockquoting = true; // mail.quoteasblock
 
       // Viewing
       text->mQuotedSizeSetting = 0;   // mail.quoted_size
       text->mQuotedStyleSetting = 0;  // mail.quoted_style
       text->mCitationColor = nullptr;  // mail.citation_color
+      text->mStripSig = true; // mail.strip_sig_on_reply
       bool graphicalQuote = true; // mail.quoted_graphical
 
       nsIPrefBranch *prefBranch = GetPrefBranch(obj->options);
       if (prefBranch)
       {
         prefBranch->GetIntPref("mail.quoted_size", &(text->mQuotedSizeSetting));
         prefBranch->GetIntPref("mail.quoted_style", &(text->mQuotedStyleSetting));
         prefBranch->GetCharPref("mail.citation_color", &(text->mCitationColor));
+        prefBranch->GetBoolPref("mail.strip_sig_on_reply", &(text->mStripSig));
         prefBranch->GetBoolPref("mail.quoted_graphical", &graphicalQuote);
         prefBranch->GetBoolPref("mail.quoteasblock", &(text->mBlockquoting));
       }
 
       if (!rawPlainText)
       {
         // Get font
         // only used for viewing (!plainHTML)
@@ -412,17 +414,17 @@ MimeInlineTextPlain_parse_line (const ch
     /* This is the main TXT to HTML conversion:
        escaping (very important), eventually recognizing etc. */
     nsString lineResultUnichar;
 
     rv = conv->ScanTXT(lineSourceStr.get() + logicalLineStart,
                        whattodo, getter_Copies(lineResultUnichar));
     NS_ENSURE_SUCCESS(rv, -1);
 
-    if (!(text->mIsSig && quoting))
+    if (!(text->mIsSig && quoting && text->mStripSig))
     {
       status = MimeObject_write(obj, prefaceResultStr.get(), prefaceResultStr.Length(), true);
       if (status < 0) return status;
       nsAutoCString outString;
       if (obj->options->format_out != nsMimeOutput::nsMimeMessageSaveAs ||
           !mailCharset || !*mailCharset)
         CopyUTF16toUTF8(lineResultUnichar, outString);
       else
--- a/mailnews/mime/src/mimetpla.h
+++ b/mailnews/mime/src/mimetpla.h
@@ -24,12 +24,13 @@ extern MimeInlineTextPlainClass mimeInli
 struct MimeInlineTextPlain {
   MimeInlineText text;
   uint32_t mCiteLevel;
   bool            mBlockquoting;
   //bool            mInsideQuote;
   int32_t         mQuotedSizeSetting;   // mail.quoted_size
   int32_t         mQuotedStyleSetting;  // mail.quoted_style
   char            *mCitationColor;      // mail.citation_color
+  bool            mStripSig;            // mail.strip_sig_on_reply
   bool            mIsSig;
 };
 
 #endif /* _MIMETPLA_H_ */