This is just some static backup of the original site, don't expect every link to work!

source: modules/vI_identityData.js @ 509348

ng_0.9
Last change on this file since 509348 was 509348, checked in by rene <rene@…>, 8 years ago

code formatting (no code changes)

  • Property mode set to 100644
File size: 19.4 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2    This program is free software; you can redistribute it and/or modify
3    it under the terms of the GNU General Public License as published by
4    the Free Software Foundation; either version 2 of the License, or
5    (at your option) any later version.
6
7    This program is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU General Public License for more details.
11
12    You should have received a copy of the GNU General Public License
13    along with this program; if not, write to the Free Software
14    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15
16    The Original Code is the Virtual Identity Extension.
17
18    The Initial Developer of the Original Code is Rene Ejury.
19    Portions created by the Initial Developer are Copyright (C) 2007
20    the Initial Developer. All Rights Reserved.
21
22    Contributor(s):
23 * ***** END LICENSE BLOCK ***** */
24
25var EXPORTED_SYMBOLS = ["identityCollection", "identityData", "identityDataExtras", "DEFAULT_SMTP_TAG", "NO_SMTP_TAG"]
26
27const DEFAULT_SMTP_TAG = "vI_useDefaultSMTP"
28const NO_SMTP_TAG = "vI_noStoredSMTP"
29
30Components.utils.import("resource://v_identity/vI_log.js");
31let Log = setupLogging("virtualIdentity.identityData");
32Components.utils.import("resource://v_identity/vI_prefs.js");
33Components.utils.import("resource://v_identity/vI_accountUtils.js");
34
35Components.utils.import("resource://v_identity/vI_identityDataExtras.js");
36Components.utils.import("resource://v_identity/identityDataExtras/returnReceipt.js");
37Components.utils.import("resource://v_identity/identityDataExtras/fccSwitch.js");
38Components.utils.import("resource://v_identity/identityDataExtras/messageFormat.js");
39Components.utils.import("resource://v_identity/identityDataExtras/characterEncoding.js");
40Components.utils.import("resource://v_identity/identityDataExtras/sMimeEncryption.js");
41Components.utils.import("resource://v_identity/identityDataExtras/sMimeSignature.js");
42Components.utils.import("resource://v_identity/identityDataExtras/PGPEncryption.js");
43Components.utils.import("resource://v_identity/identityDataExtras/PGPSignature.js");
44Components.utils.import("resource://v_identity/identityDataExtras/PGPMIME.js");
45
46function identityData(email, fullName, id, smtp, extras, sideDescription, existingID) {
47  this._email = email ? email : "";
48  this._emailParsed = false;
49  this._fullName = fullName ? fullName : "";
50  this.id = new idObj(id);
51  this.smtp = new smtpObj(smtp);
52  if (extras) this.extras = extras;
53  else this.extras = new identityDataExtras();
54  this.comp = { // holds the results of the last comparison for later creation of a compareMatrix
55    compareID: null,
56    equals: {
57      fullName: {},
58      email: {},
59      smtp: {},
60      id: {},
61      extras: {}
62    }
63  }
64  if (sideDescription) this.sideDescription = sideDescription;
65  if (existingID) this.existingID = existingID;
66  else if (this.id.value) this.sideDescription = " - " + this.id.value;
67  this.stringBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
68    .getService(Components.interfaces.nsIStringBundleService)
69    .createBundle("chrome://v_identity/locale/v_identity.properties");
70}
71identityData.prototype = {
72  _email: null, // internal email-field might contain combinedName (until first queried via email)
73  _fullName: null,
74  _emailParsed: null,
75  id: null,
76  smtp: null,
77  extras: null,
78  sideDescription: null,
79  existingID: null, // indicates that this is a pre-defined Identity, which might handled slightly differently
80
81  stringBundle: null,
82  comp: null,
83
84  parseEmail: function () {
85    if (this._emailParsed) return;
86    // parse email and move any additional parts to fullName
87    if (this._email.match(/<\s*[^>\s]*@[^>\s]*\s*>/) || this._email.match(/<?\s*[^>\s]*@[^>\s]*\s*>?/) || this._email.match(/$/)) {
88      this._fullName += RegExp.leftContext + RegExp.rightContext;
89      this._email = RegExp.lastMatch;
90      //            Log.debug("parseEmail _fullName = '" + this._fullName + "'");
91      //            Log.debug("parseEmail _email =    '" + this._email + "'");
92    }
93    this._emailParsed = true;
94  },
95  get email() {
96    this.parseEmail();
97    return (this._email ? this._email.replace(/\s+|<|>/g, "") : "");
98  },
99  set email(email) {
100    this._email = email;
101    this._emailParsed = false;
102  },
103
104  cleanName: function (fullName) {
105    //      Log.debug("cleanName init '" + fullName + "'");
106    var _fullName = fullName.replace(/^\s+|\s+$/g, "");
107    if (_fullName.search(/^\".+\"$|^'.+'$/g) != -1) {
108      _fullName = this.cleanName(_fullName.replace(/^\"(.+)\"$|^'(.+)'$/g, "$1$2"));
109    }
110    //      Log.debug("cleanName done '" + _fullName + "'");
111    return _fullName;
112  },
113
114  get fullName() {
115    this.parseEmail();
116    return (this._fullName ? this.cleanName(this._fullName) : "")
117  },
118  set fullName(fullName) {
119    this._fullName = fullName;
120  },
121
122  get combinedName() {
123    var fullName = this.fullName;
124    var email = this.email;
125    return fullName ? fullName + (email ? " <" + email + ">" : "") : email
126  },
127  set combinedName(combinedName) {
128    this._email = combinedName;
129    this._fullName = "";
130    this._emailParsed = false;
131  },
132
133  __makeHtml: function (string) {
134    return string ? string.replace(/>/g, "&gt;").replace(/</g, "&lt;") : ""
135  },
136  get idHtml() {
137    return this.__makeHtml(this.id.value);
138  },
139  get smtpHtml() {
140    return this.__makeHtml(this.smtp.value);
141  },
142  get fullNameHtml() {
143    return this.__makeHtml(this.fullName);
144  },
145  get emailHtml() {
146    return this.__makeHtml(this.email);
147  },
148  get combinedNameHtml() {
149    return this.__makeHtml(this.combinedName);
150  },
151
152  get idLabel() {
153    return this.stringBundle.GetStringFromName("vident.identityData.baseID")
154  },
155  get smtpLabel() {
156    return this.stringBundle.GetStringFromName("vident.identityData.SMTP")
157  },
158  get fullNameLabel() {
159    return this.stringBundle.GetStringFromName("vident.identityData.Name")
160  },
161  get emailLabel() {
162    return this.stringBundle.GetStringFromName("vident.identityData.Address")
163  },
164
165  // creates an Duplicate of the current IdentityData, cause usually we are working with a pointer
166  getDuplicate: function () {
167    return new identityData(this.email, this.fullName, this.id.key, this.smtp.key, this.extras ? this.extras.getDuplicate() : null, this.sideDescription, this.existingID);
168  },
169
170  // copys all values of an identity. This way we can create a new object with a different document-context
171  copy: function (identityData) {
172    this.email = identityData.email;
173    this.fullName = identityData.fullName;
174    this.id.key = identityData.id.key;
175    this.smtp.key = identityData.smtp.key;
176    this.sideDescription = identityData.sideDescription;
177    if (this.extras) this.extras.copy(identityData.extras);
178  },
179
180  // dependent on MsgComposeCommands, should/will only be called in ComposeDialog
181  isExistingIdentity: function (ignoreFullNameWhileComparing) {
182    Log.debug("isExistingIdentity: ignoreFullNameWhileComparing='" + ignoreFullNameWhileComparing + "'");
183    //      Log.debug("base: fullName.toLowerCase()='" + this.fullName + "' email.toLowerCase()='" + this.email + "' smtp='" + this.smtp.key + "'");
184
185    var ignoreFullNameMatchKey = null;
186    var accounts = getAccountsArray();
187    for (let acc = 0; acc < accounts.length; acc++) {
188      let account = accounts[acc];
189      try {
190        prefroot.getBoolPref("mail.account." + account.key + ".vIdentity");
191        continue;
192      } catch (e) {};
193      let identities = getIdentitiesArray(account);
194      for (let i = 0; i < identities.length; i++) {
195        let identity = identities[i];
196        //              Log.debug("comp: fullName.toLowerCase()='" + identity.fullName.toLowerCase() + "' email.toLowerCase()='" + identity.email.toLowerCase() + "' smtp='" + identity.smtpServerKey + "'");
197        var email = this.email ? this.email : ""; // might be null if no identity is set
198        var idEmail = identity.email ? identity.email : ""; // might be null if no identity is set
199        if ((email.toLowerCase() == idEmail.toLowerCase()) &&
200          this.smtp.equal(new smtpObj(identity.smtpServerKey))) {
201          // if fullName matches, than this is a final match
202          if (this.fullName.toLowerCase() == identity.fullName.toLowerCase()) {
203            Log.debug("isExistingIdentity: " + this.combinedName + " found, id='" + identity.key + "'");
204            return identity.key; // return key and stop searching
205          }
206          // if fullNames don't match, remember the key but continue to search for full match
207          else if (!ignoreFullNameMatchKey) ignoreFullNameMatchKey = identity.key;
208        }
209      }
210    }
211
212    if (ignoreFullNameWhileComparing && ignoreFullNameMatchKey) {
213      Log.debug("isExistingIdentity: " + this.combinedName + " found, id='" + ignoreFullNameMatchKey + "'");
214      return ignoreFullNameMatchKey;
215    }
216
217    Log.debug("isExistingIdentity: " + this.combinedName + " not found");
218    return null;
219  },
220
221  // dependent on MsgComposeCommands, should/will only be called in ComposeDialog
222  hasMatchingDomainIdentity: function () {
223    Log.debug("hasMatchingDomainIdentity");
224
225    var domainArray = this.email.match(/@[^@]+$/);
226    if (!domainArray) {
227      Log.debug("hasMatchingDomainIdentity found no domain for email " + this.email);
228      return;
229    }
230    Log.debug("hasMatchingDomainIdentity searching for domain " + domainArray[0]);
231
232    var accounts = getAccountsArray();
233    for (let acc = 0; acc < accounts.length; acc++) {
234      let account = accounts[acc];
235      try {
236        prefroot.getBoolPref("mail.account." + account.key + ".vIdentity");
237        continue;
238      } catch (e) {};
239      let identities = getIdentitiesArray(account);
240      for (let i = 0; i < identities.length; i++) {
241        let identity = identities[i];
242        var idDomainArray = identity.email.match(/@[^@]+$/);
243        if (!idDomainArray) continue;
244        //                 Log.debug("comp: domain.toLowerCase()='" + domainArray[0].toLowerCase() + "' idDomain.toLowerCase()='" + idDomainArray[0].toLowerCase() + "'");
245        if (domainArray[0].toLowerCase() == idDomainArray[0].toLowerCase()) {
246          // if domain matches, everything is perfect!
247          Log.debug("hasMatchingDomainIdentity: found matching id for domain '" + domainArray[0] + "'");
248          return identity.key; // return key and stop searching
249        }
250      }
251    }
252    Log.debug("hasMatchingDomainIdentity: '" + domainArray[0] + "' not found");
253    return null;
254  },
255
256  equals: function (compareIdentityData) {
257    this.comp.compareID = compareIdentityData;
258
259    this.comp.equals.fullName = (((this.fullName) ? this.fullName.toLowerCase() : null) == ((compareIdentityData.fullName) ? compareIdentityData.fullName.toLowerCase() : null));
260    if (!this.comp.equals.fullName) {
261      //       Log.debug("fullName not equal ('" + ((this.fullName)?this.fullName.toLowerCase():null) + "' != '" + ((compareIdentityData.fullName)?compareIdentityData.fullName.toLowerCase():null) + "')");
262    }
263    this.comp.equals.email = (((this.email) ? this.email.toLowerCase() : null) == ((compareIdentityData.email) ? compareIdentityData.email.toLowerCase() : null));
264    if (!this.comp.equals.email) {
265      //       Log.debug("email not equal ('" + ((this.email)?this.email.toLowerCase():null) + "' != '" + ((compareIdentityData.email)?compareIdentityData.email.toLowerCase():null) + "')");
266    }
267
268    this.comp.equals.smtp = this.smtp.equal(compareIdentityData.smtp);
269    this.comp.equals.id = this.id.equal(compareIdentityData.id);
270    this.comp.equals.extras = this.extras ? this.extras.equal(compareIdentityData.extras) : true;
271
272    return (this.comp.equals.fullName && this.comp.equals.email && this.comp.equals.smtp && this.comp.equals.id && this.comp.equals.extras);
273  },
274
275  equalsIdentity: function (compareIdentityData, getCompareMatrix) {
276    var equal = this.equals(compareIdentityData);
277    var compareMatrix = null;
278    // generate CompareMatrix only if asked and non-equal
279    if (getCompareMatrix && !equal) compareMatrix = this.getCompareMatrix();
280    return {
281      equal: equal,
282      compareMatrix: compareMatrix
283    };
284  },
285
286  getCompareMatrix: function () {
287    const Items = Array("fullName", "email", "smtp", "id");
288    var string = "";
289    var saveBaseId = vIprefs.get("storage_store_base_id");
290    var saveSMTP = vIprefs.get("storage_store_SMTP");
291    for each(let item in Items) {
292      var classEqual = (this.comp.equals[item]) ? "equal" : "unequal";
293      var classIgnore = (((!saveBaseId) && (item == "id")) || ((!saveSMTP) && (item == "smtp"))) ? " ignoreValues" : ""
294      string += "<tr>" +
295        "<td class='col1 " + classEqual + "'>" + this[item + "Label"] + "</td>" +
296        "<td class='col2 " + classEqual + classIgnore + "'>" + this.comp.compareID[item + "Html"] + "</td>" +
297        "<td class='col3 " + classEqual + classIgnore + "'>" + this[item + "Html"] + "</td>" +
298        "</tr>"
299    }
300    string += this.extras ? this.extras.getCompareMatrix() : "";
301    return string;
302  },
303
304  getMatrix: function () {
305    const Items = Array("smtp", "id");
306    var string = "";
307    for each(var item in Items) if (this[item + "Html"])
308        string += "<tr><td class='col1'>" + this[item + "Label"] + ":</td>" +
309        "<td class='col2'>" + this[item + "Html"] + "</td></tr>"
310    string += this.extras ? this.extras.getMatrix() : "";
311    return string;
312  }
313}
314
315function identityCollection() {
316  this.number = 0;
317  this.identityDataCollection = {};
318  this.menuItems = {};
319}
320identityCollection.prototype = {
321  number: null,
322  identityDataCollection: null,
323  menuItems: null,
324
325  mergeWithoutDuplicates: function (addIdentityCollection) {
326    for (var index = 0; index < addIdentityCollection.number; index++)
327      this.addWithoutDuplicates(addIdentityCollection.identityDataCollection[index])
328  },
329
330  dropIdentity: function (index) {
331    Log.debug("dropping address from inputList: " + this.identityDataCollection[index].combinedName);
332    while (index < (this.number - 1)) {
333      this.identityDataCollection[index] = this.identityDataCollection[++index];
334    };
335    this.identityDataCollection[--this.number] = null;
336  },
337
338  addWithoutDuplicates: function (identityData) {
339    if (!identityData) return;
340    for (var index = 0; index < this.number; index++) {
341      if (this.identityDataCollection[index].email == identityData.email &&
342        (!this.identityDataCollection[index].id.key || !identityData.id.key ||
343          (this.identityDataCollection[index].id.key == identityData.id.key &&
344            this.identityDataCollection[index].smtp.key == identityData.smtp.key))) {
345        // found, so check if we can use the Name of the new field
346        if (this.identityDataCollection[index].fullName == "" && identityData.fullName != "") {
347          this.identityDataCollection[index].fullName = identityData.fullName;
348          Log.debug("added fullName '" + identityData.fullName + "' to stored email '" + this.identityDataCollection[index].email + "'")
349        }
350        // check if id_key, smtp_key or extras can be used
351        // only try this once, for the first Identity where id is set)
352        if (!this.identityDataCollection[index].id.key && identityData.id.key) {
353          this.identityDataCollection[index].id.key = identityData.id.key;
354          this.identityDataCollection[index].smtp.key = identityData.smtp.key;
355          this.identityDataCollection[index].extras = identityData.extras;
356          Log.debug("added id '" + identityData.id.value + "' smtp '" + identityData.smtp.value + "' (+extras) to stored email '" + this.identityDataCollection[index].email + "'")
357        }
358        return;
359      }
360    }
361    Log.debug("add new address to result: " + identityData.combinedName)
362    this.identityDataCollection[index] = identityData;
363    this.number = index + 1;
364  },
365
366  // this is used to completely use the conten of another identityCollection, but without changing all pointers
367  // see for instance vI.smartIdentity.__filterAddresses
368  takeOver: function (newIdentityCollection) {
369    this.number = newIdentityCollection.number
370    this.identityDataCollection = newIdentityCollection.identityDataCollection
371  }
372};
373
374function smtpObj(key) {
375  this._key = key;
376  this.DEFAULT_TAG = Components.classes["@mozilla.org/intl/stringbundle;1"]
377    .getService(Components.interfaces.nsIStringBundleService)
378    .createBundle("chrome://messenger/locale/messenger.properties").
379  GetStringFromName("defaultServerTag");
380}
381smtpObj.prototype = {
382  DEFAULT_TAG: null,
383  _key: null,
384  _value: null,
385
386  set key(key) {
387    this._key = key;
388    this._value = null;
389  },
390  get key() {
391    var dummy = this.value; // just to be sure key is adapted if SMTP is not available
392    return this._key
393  },
394  get keyNice() { // the same as key but with "" for DEFAULT_SMTP_TAG
395    if (this.key == DEFAULT_SMTP_TAG) return ""; // this is the key used for default server
396    return this.key
397  },
398  get value() {
399    if (this._value == null) {
400      this._value = "";
401      if (this._key == null || this._key == "") this._key = DEFAULT_SMTP_TAG;
402      if (this._key == DEFAULT_SMTP_TAG) this._value = this.DEFAULT_TAG;
403      else if (!this._key) this._value = null;
404      else if (this._key) {
405        var servers, smtpService = Components.classes["@mozilla.org/messengercompose/smtp;1"]
406          .getService(Components.interfaces.nsISmtpService);
407        // check for new https://hg.mozilla.org/comm-central/rev/fab9e5145cd4 smtpService
408        if (typeof (smtpService.servers) == "object") servers = smtpService.servers;
409        else servers = smtpService.smtpServers;
410
411        while (servers && servers.hasMoreElements()) {
412          var server = servers.getNext();
413          if (server instanceof Components.interfaces.nsISmtpServer &&
414            !server.redirectorType && this._key == server.key) {
415            this._value = server.description ? server.description : server.hostname;
416            break;
417          }
418        }
419      }
420    }
421    if (!this._value) this._key = NO_SMTP_TAG; // if non-existant SMTP handle like non available
422    return this._value;
423  },
424  equal: function (compareSmtpObj) {
425    if (this.key == NO_SMTP_TAG || compareSmtpObj.key == NO_SMTP_TAG) return true;
426    if (this.keyNice != compareSmtpObj.keyNice) {
427      //       Log.debug("smtp not equal ('" + this.keyNice + "' != '" + compareSmtpObj.keyNice + "')");
428    }
429    return (this.keyNice == compareSmtpObj.keyNice);
430  },
431  hasNoDefinedSMTP: function () {
432    return (this.key == NO_SMTP_TAG);
433  }
434}
435
436function idObj(key) {
437  this._key = key;
438}
439idObj.prototype = {
440  _key: null,
441  _value: null,
442
443  set key(key) {
444    this._key = key;
445    this._value = null;
446  },
447  get key() {
448    if (this._value == null) var dummy = this.value;
449    return this._key
450  },
451  get value() {
452    if (this._value == null) {
453      this._value = "";
454      // if this worked we are having at least seamonkey 1.17
455      let accounts = getAccountsArray();
456      for (let acc = 0; acc < accounts.length; acc++) {
457        let account = accounts[acc];
458        let identities = getIdentitiesArray(account);
459        if (identities.length == 0)
460          continue;
461        for (let i = 0; i < identities.length; i++) {
462          let identity = identities[i];
463          if (this._key == identity.key) {
464            this._value = identity.identityName;
465            break;
466          }
467        }
468      }
469      if (!this._value) this._key = null;
470    }
471    return this._value;
472  },
473  equal: function (compareIdObj) {
474    if (!this.key || !compareIdObj.key) return true;
475    if (this.key != compareIdObj.key) {
476      //       Log.debug("id not equal ('" + this.key + "' != '" + compareIdObj.key + "')");
477    }
478    return (this.key == compareIdObj.key);
479  }
480}
Note: See TracBrowser for help on using the repository browser.