Bug 1492735 - Port Bug 1486147: Replace use of nsIUTF8StringEnumerator in msgIStructuredHeaders. r=mkmelin
☠☠ backed out by e386db4f34bd ☠ ☠
authorJorg K <jorgk@jorgk.com>
Wed, 26 Sep 2018 10:49:19 +0200
changeset 33233 3bc0fb310b8a55a282da9addf885f9beba0c8bac
parent 33232 9cbdc6469caf6126896fcee4803f920a316a8172
child 33234 6dfdc289650b385ba673e5887c29da3d2516f693
push id387
push userclokep@gmail.com
push dateMon, 10 Dec 2018 21:30:47 +0000
reviewersmkmelin
bugs1492735, 1486147
Bug 1492735 - Port Bug 1486147: Replace use of nsIUTF8StringEnumerator in msgIStructuredHeaders. r=mkmelin
mailnews/compose/test/unit/test_nsIMsgCompFields.js
mailnews/mime/public/msgIStructuredHeaders.idl
mailnews/mime/src/mimeJSComponents.js
mailnews/mime/test/unit/test_structured_headers.js
--- a/mailnews/compose/test/unit/test_nsIMsgCompFields.js
+++ b/mailnews/compose/test/unit/test_nsIMsgCompFields.js
@@ -5,18 +5,17 @@
 /// Test that nsIMsgCompFields works properly
 
 var nsMsgCompFields = Components.Constructor(
   "@mozilla.org/messengercompose/composefields;1",
   Ci.nsIMsgCompFields);
 
 function check_headers(enumerator, container) {
   let checkValues = new Set(container.map(header => header.toLowerCase()));
-  while (enumerator.hasMore()) {
-    let value = enumerator.getNext().toLowerCase();
+  for (let value of enumerator) {
     Assert.ok(checkValues.has(value));
     checkValues.delete(value);
   }
   Assert.equal(checkValues.size, 0);
 }
 
 function run_test() {
   let fields = new nsMsgCompFields;
--- a/mailnews/mime/public/msgIStructuredHeaders.idl
+++ b/mailnews/mime/public/msgIStructuredHeaders.idl
@@ -7,17 +7,17 @@
 %{C++
 #include "nsCOMArray.h"
 
 #define NS_ISTRUCTUREDHEADERS_CONTRACTID \
   "@mozilla.org/messenger/structuredheaders;1"
 %}
 
 interface msgIAddressObject;
-interface nsIUTF8StringEnumerator;
+interface nsIJSEnumerator;
 
 /**
  * A collection of MIME headers that are stored in a rich, structured format.
  *
  * The structured forms defined in this method use the structured decoder and
  * encoder functionality found in jsmime to interconvert between the raw string
  * forms found in the actual message text and the structured forms supported by
  * this interface. Extensions can register their own custom structured headers
@@ -90,17 +90,17 @@ interface msgIStructuredHeaders : nsISup
   AUTF8String getRawHeader(in string aHeaderName);
 
   /**
    * Retrieve an enumerator of the names of all headers in this set of headers.
    * The header names returned may be in different cases depending on the
    * precise implementation of this interface, so implementations should not
    * rely on an exact kind of case being returned.
    */
-  readonly attribute nsIUTF8StringEnumerator headerNames;
+  readonly attribute nsIJSEnumerator headerNames;
 
   /**
    * Retrieve the MIME representation of all of the headers.
    *
    * The header values are emitted in an ASCII form, unless internationalized
    * email addresses are involved. The extra CRLF indicating the end of headers
    * is not included in this representation.
    *
--- a/mailnews/mime/src/mimeJSComponents.js
+++ b/mailnews/mime/src/mimeJSComponents.js
@@ -7,44 +7,16 @@ ChromeUtils.import("resource:///modules/
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 function HeaderHandler() {
   this.value = "";
   this.deliverData = function (str) { this.value += str; };
   this.deliverEOF = function () {};
 }
 
-function StringEnumerator(iterator) {
-  this._iterator = iterator;
-  this._next = undefined;
-}
-StringEnumerator.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIUTF8StringEnumerator]),
-  [Symbol.iterator]: function () {
-    return this;
-  },
-  _setNext: function () {
-    if (this._next !== undefined)
-      return;
-    this._next = this._iterator.next();
-  },
-  hasMore: function () {
-    this._setNext();
-    return !this._next.done;
-  },
-  getNext: function () {
-    this._setNext();
-    let result = this._next;
-    this._next = undefined;
-    if (result.done)
-      throw Cr.NS_ERROR_UNEXPECTED;
-    return result.value;
-  }
-};
-
 /**
  * If we get XPConnect-wrapped objects for msgIAddressObjects, we will have
  * properties defined for 'group' that throws off jsmime. This function converts
  * the addresses into the form that jsmime expects.
  */
 function fixXpconnectAddresses(addrs) {
   return addrs.map((addr) => {
     // This is ideally !addr.group, but that causes a JS strict warning, if
@@ -102,17 +74,17 @@ MimeStructuredHeaders.prototype = {
     // Strip off the header name and trailing whitespace before returning...
     value = value.substring(aHeaderName.length + 2).trim();
     // ... as well as embedded newlines.
     value = value.replace(/\r\n/g, '');
     return value;
   },
 
   get headerNames() {
-    return new StringEnumerator(this._headers.keys());
+    return this._headers.keys();
   },
 
   buildMimeText: function () {
     if (this._headers.size == 0) {
       return "";
     }
     let handler = new HeaderHandler();
     let emitter = jsmime.headeremitter.makeStreamingEmitter(handler, {
@@ -174,19 +146,17 @@ MimeWritableStructuredHeaders.prototype 
     this._headers.set(aHeaderName.toLowerCase(), aValue);
   },
 
   deleteHeader: function (aHeaderName) {
     this._headers.delete(aHeaderName.toLowerCase());
   },
 
   addAllHeaders: function (aHeaders) {
-    let headerList = aHeaders.headerNames;
-    while (headerList.hasMore()) {
-      let header = headerList.getNext();
+    for (let header of aHeaders.headerNames) {
       this.setHeader(header, aHeaders.getHeader(header));
     }
   },
 
   setUnstructuredHeader: function (aHeaderName, aValue) {
     this.setHeader(aHeaderName, aValue);
   },
 
--- a/mailnews/mime/test/unit/test_structured_headers.js
+++ b/mailnews/mime/test/unit/test_structured_headers.js
@@ -116,28 +116,24 @@ add_task(async function check_raw() {
   Assert.equal(headers.getHeader("Not-Found-Anywhere"), 515);
   headers.deleteHeader("not-found-anywhere");
   Assert.equal(headers.getHeader("Not-Found-Anywhere"), undefined);
 
   // Check the enumeration of header values.
   headers.setHeader("unabashed-random-header", false);
   let headerList = ["Date", "Content-Description", "Subject",
     "Unabashed-Random-Header"];
-  let enumerator = headers.headerNames;
-  while (enumerator.hasMore()) {
-    let value = enumerator.getNext();
+  for (let value of headers.headerNames) {
     Assert.equal(value.toLowerCase(), headerList.shift().toLowerCase());
   }
 
   // Check that copying works
   let moreHeaders = new StructuredHeaders();
   moreHeaders.addAllHeaders(headers);
-  enumerator = headers.headerNames;
-  while (enumerator.hasMore()) {
-    let value = enumerator.getNext();
+  for (let value of headers.headerNames) {
     Assert.equal(moreHeaders.getHeader(value), headers.getHeader(value));
   }
   headers.deleteHeader("Date");
   Assert.ok(moreHeaders.hasHeader("Date"));
 })
 
 add_task(async function check_nsIMimeHeaders() {
   let headers = Cc["@mozilla.org/messenger/mimeheaders;1"]
@@ -150,19 +146,17 @@ add_task(async function check_nsIMimeHea
   Assert.equal(headers.getHeader("To")[0].email, "bugmail@example.org");
   Assert.equal(headers.getAddressingHeader("To").length, 1);
   Assert.equal(headers.getHeader("Content-Type").type, "text/html");
 
   let headerList = ["X-Mozilla-Status", "X-Mozilla-Status2", "X-Mozilla-Keys",
     "FCC", "BCC", "X-Identity-Key", "Message-ID", "Date", "From",
     "X-Mozilla-Draft-Info", "User-Agent", "MIME-Version", "To", "Subject",
     "Content-Type", "Content-Transfer-Encoding"];
-  let enumerator = headers.headerNames;
-  while (enumerator.hasMore()) {
-    let value = enumerator.getNext();
+  for (let value of headers.headerNames) {
     Assert.equal(value.toLowerCase(), headerList.shift().toLowerCase());
   }
 });
 
 add_task(async function checkBuildMimeText() {
   let headers = new StructuredHeaders();
   headers.setHeader("To", [{name: "François Smith", email: "user@☃.invalid"}]);
   headers.setHeader("From", [{name: "John Doe", email: "jdoe@test.invalid"}]);