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

source: chrome/content/v_identity/vI_storage.js @ f4784d

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

added switch to takeover stored identity while sending

  • Property mode set to 100644
File size: 18.7 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): Mike Krieger, Sebastian Apel
23 * ***** END LICENSE BLOCK ***** */
24 
25/**
26* some code copied and adapted from 'addressContext' and from 'Birthday Reminder'
27* thanks to Mike Krieger and Sebastian Apel
28*/
29
30var vI_storage = {
31    multipleRecipients : null,
32   
33    lastCheckedEmail : {},  // array of last checked emails per row,
34                // to prevent ugly double dialogs and time-consuming double-checks
35   
36    rdfService : Components.classes["@mozilla.org/rdf/rdf-service;1"]
37            .getService(Components.interfaces.nsIRDFService),
38
39    prefroot : Components.classes["@mozilla.org/preferences-service;1"]
40            .getService(Components.interfaces.nsIPrefService)
41            .getBranch(null).QueryInterface(Components.interfaces.nsIPrefBranch2),
42   
43    clean: function() {
44        vI_notificationBar.dump("## vI_storage: clean.\n");
45        vI_storage.multipleRecipients = null;
46        vI_storage.lastCheckedEmail = {};
47        vI_storage.firstUsedInputElement = null;
48        awSetInputAndPopupValue = vI_storage.original_functions.awSetInputAndPopupValue;
49    },
50   
51    original_functions : {
52        awSetInputAndPopupValue : null
53    },
54
55    replacement_functions : {
56        awSetInputAndPopupValue : function (inputElem, inputValue, popupElem, popupValue, rowNumber) {
57            vI_notificationBar.dump("## vI_storage: awSetInputAndPopupValue '" + inputElem.id +"'\n");
58            vI_storage.original_functions.awSetInputAndPopupValue(inputElem, inputValue, popupElem, popupValue, rowNumber);
59            vI_storage.updateVIdentityFromStorage(inputElem);
60        }
61    },
62       
63    awOnBlur : function (element) {
64        // only react on events triggered by addressCol2 - textinput Elements
65        if (!element || ! element.id.match(/^addressCol2*/)) return;
66        vI_notificationBar.dump("\n## vI_storage: awOnBlur '" + element.id +"'\n");
67        vI_storage.updateVIdentityFromStorage(element);
68    },
69
70    awPopupOnCommand : function (element) {
71        vI_notificationBar.dump("\n## vI_storage: awPopupOnCommand'" + element.id +"'\n");
72        vI_storage.updateVIdentityFromStorage(document.getElementById(element.id.replace(/^addressCol1/,"addressCol2")));
73        if (element.selectedItem.getAttribute("value") == "addr_reply") // if reply-to is manually entered disable AutoReplyToSelf
74            document.getElementById("autoReplyToSelfLabel").setAttribute("hidden", "true");
75
76    },
77   
78    initialized : null,
79    init: function() {
80        if (!vI_storage.initialized) {
81            // better approach would be to use te onchange event, but this one is not fired in any change case
82            // see https://bugzilla.mozilla.org/show_bug.cgi?id=355367
83            // same seems to happen with the ondragdrop event
84            if (top.MAX_RECIPIENTS == 0) top.MAX_RECIPIENTS = 1;
85            for (var row = 1; row <= top.MAX_RECIPIENTS ; row ++) {
86                var input = awGetInputElement(row);
87                if (input) {
88                    var oldBlur = input.getAttribute("onblur")
89                    input.setAttribute("onblur", (oldBlur?oldBlur+"; ":"") +
90                        "window.setTimeout(vI_storage.awOnBlur, 250, this.parentNode.parentNode.parentNode);")
91                }
92                var popup = awGetPopupElement(row);
93                if (popup) {
94                    var oldCommand = popup.getAttribute("oncommand")
95                    popup.setAttribute("oncommand", (oldCommand?oldCommand+"; ":"") +
96                        "window.setTimeout(vI_storage.awPopupOnCommand, 250, this);")
97                }
98            }
99            vI_storage.initialized = true;
100        }
101        vI_storage.original_functions.awSetInputAndPopupValue = awSetInputAndPopupValue;
102        awSetInputAndPopupValue = function (inputElem, inputValue, popupElem, popupValue, rowNumber) {
103            vI_storage.replacement_functions.awSetInputAndPopupValue (inputElem, inputValue, popupElem, popupValue, rowNumber) }
104
105        // reset unavailable storageExtras preferences
106        const enigmail_ID="{847b3a00-7ab1-11d4-8f02-006008948af5}"
107        if (!vI_helper.extensionActive(enigmail_ID)) {
108            vI.preferences.setBoolPref("storageExtras_openPGP_messageEncryption", false)
109            vI.preferences.setBoolPref("storageExtras_openPGP_messageSignature", false)
110            vI.preferences.setBoolPref("storageExtras_openPGP_PGPMIME", false)
111        }
112    },
113   
114   
115    firstUsedInputElement : null,   // this stores the first Element for which a Lookup in the Storage was successfull
116    updateVIdentityFromStorage: function(inputElement) {       
117        if (!vI.preferences.getBoolPref("storage"))
118            { vI_notificationBar.dump("## vI_storage: Storage deactivated\n"); return; }
119        vI_notificationBar.dump("## vI_storage: updateVIdentityFromStorage()\n");
120
121        var recipientType = document.getElementById(inputElement.id.replace(/^addressCol2/,"addressCol1"))
122            .selectedItem.getAttribute("value");
123        var row = inputElement.id.replace(/^addressCol2#/,"")
124        if (recipientType == "addr_reply" || recipientType == "addr_followup" || vI_storage.__isDoBcc(row)) {
125            // reset firstUsedInputElement if recipientType was changed (and don't care about doBcc fields)
126            if (vI_storage.firstUsedInputElement == inputElement)
127                vI_storage.firstUsedInputElement = null;
128            vI_notificationBar.dump("## vI_storage: field is a 'reply-to' or 'followup-to' or preconfigured 'doBcc'. not searched.\n")
129            return;
130        }
131       
132        if (inputElement.value == "") {
133            vI_notificationBar.dump("## vI_storage: no recipient found, not checked.\n"); return;
134        }
135       
136        var row = inputElement.id.replace(/^addressCol2#/,"")
137        if (vI_storage.lastCheckedEmail[row] && vI_storage.lastCheckedEmail[row] == inputElement.value) {
138            vI_notificationBar.dump("## vI_storage: same email than before, not checked again.\n"); return;
139        }
140        vI_storage.lastCheckedEmail[row] = inputElement.value;
141        var recipient = vI_storage.__getDescriptionAndType(inputElement.value, recipientType);
142
143        var matchResults = { storageData : {}, menuItem : {} };
144        matchResults.storageData[0] = vI_rdfDatasource.readVIdentityFromRDF(recipient.recDesc, recipient.recType),
145        matchResults.storageData[1] = vI_rdfDatasource.findMatchingFilter(recipient.recDesc);
146
147        var matchIndex = null;
148        for (var i = 0; i <= 1; i++) {
149            if (matchResults.storageData[i]) {
150                if (matchIndex == null) matchIndex = i;
151                matchResults.menuItem[i] = document.getElementById("msgIdentity_clone")
152                                .addIdentityToCloneMenu(matchResults.storageData[i]);
153            }
154        }
155        if (matchIndex == null) return;
156       
157        // found storageData, so store InputElement
158        if (!vI_storage.firstUsedInputElement) vI_storage.firstUsedInputElement = inputElement;
159       
160        vI_notificationBar.dump("## vI_storage: compare with current Identity\n");
161        if (vI.preferences.getBoolPref("storage_getOneOnly") &&
162            vI_storage.firstUsedInputElement &&
163            vI_storage.firstUsedInputElement != inputElement &&
164            !matchResults.storageData[matchIndex].equalsCurrentIdentity(false).equal)
165                vI_notificationBar.setNote(vI.elements.strings
166                    .getString("vident.smartIdentity.vIStorageCollidingIdentity"),
167                    "storage_notification");
168        // only update fields if new Identity is different than old one.
169        else {
170            var compResult = matchResults.storageData[matchIndex].equalsCurrentIdentity(true);
171            if (!compResult.equal) {
172                var warning = vI_storage.__getWarning("replaceVIdentity", recipient, compResult.compareMatrix);
173                var msgIdentityCloneElem = document.getElementById("msgIdentity_clone")
174                if (    !msgIdentityCloneElem.vid ||
175                    !vI.preferences.getBoolPref("storage_warn_vI_replace") ||
176                    (vI_storage.__askWarning(warning) == "accept")) {
177                        msgIdentityCloneElem.selectedMenuItem = matchResults.menuItem[matchIndex];
178                        if (msgIdentityCloneElem.vid)
179                            vI_notificationBar.setNote(vI.elements.strings.getString("vident.smartIdentity.vIStorageUsage") + ".",
180                            "storage_notification");
181                }
182            }
183        }
184    },
185   
186    __getDescriptionAndType : function (recipient, recipientType) {
187        if (recipientType == "addr_newsgroups") return { recDesc : recipient, recType : "newsgroup" }
188        else if (vI_storage.isMailingList(recipient))
189            return { recDesc : vI_storage.getMailListName(recipient), recType : "maillist" }
190        else 
191            return { recDesc : vI_helper.parseAddress(recipient).combinedName, recType : "email" }
192    },
193       
194    storeVIdentityToAllRecipients : function(msgType) {
195        if (msgType != nsIMsgCompDeliverMode.Now) return true;
196        vI_notificationBar.dump("## vI_storage: ----------------------------------------------------------\n")
197        if (!vI.preferences.getBoolPref("storage"))
198            { vI_notificationBar.dump("## vI_storage: Storage deactivated\n"); return true; }
199       
200        if (vI_statusmenu.objStorageSaveMenuItem.getAttribute("checked") != "true") {
201            vI_notificationBar.dump("## vI_storage: SaveMenuItem not checked.\n")
202            return true;
203        }
204       
205        vI_notificationBar.dump("## vI_storage: storeVIdentityToAllRecipients()\n");
206       
207        // check if there are multiple recipients
208        vI_storage.multipleRecipients = false;
209        var recipients = 0;
210        for (var row = 1; row <= top.MAX_RECIPIENTS; row ++) {
211            var recipientType = awGetPopupElement(row).selectedItem.getAttribute("value");
212            if (recipientType == "addr_reply" || recipientType == "addr_followup" || 
213                vI_storage.__isDoBcc(row) || awGetInputElement(row).value.match(/^\s*$/) ) continue;
214            if (recipients++ == 1) {
215                vI_storage.multipleRecipients = true
216                vI_notificationBar.dump("## vI_storage: multiple recipients found.\n")
217                break;
218            }
219        }           
220       
221        for (var row = 1; row <= top.MAX_RECIPIENTS; row ++) {
222            var recipientType = awGetPopupElement(row).selectedItem.getAttribute("value");
223            if (recipientType == "addr_reply" || recipientType == "addr_followup" || 
224                vI_storage.__isDoBcc(row) || awGetInputElement(row).value.match(/^\s*$/) ) continue;
225            if (!vI_storage.__updateStorageFromVIdentity(awGetInputElement(row).value, recipientType)) {
226                vI_notificationBar.dump("## vI_storage: --------------  aborted  ---------------------------------\n")
227                return false; // abort sending
228            }
229        }
230        vI_notificationBar.dump("## vI_storage: ----------------------------------------------------------\n");
231        return true;
232    },
233   
234    __getWarning : function(warningCase, recipient, compareMatrix) {
235        var warning = { title: null, recLabel : null, recipient : null, warning : null, css: null, query : null, class : null };
236        warning.title = vI.elements.strings.getString("vident." + warningCase + ".title")
237        warning.recLabel = vI.elements.strings.getString("vident." + warningCase + ".recipient") + " (" + recipient.recType + "):"
238        warning.recipient = recipient.recDesc;
239        warning.warning = 
240            "<table class='" + warningCase + "'><thead><tr><th class='col1'/>" +
241                "<th class='col2'>" + vI.elements.strings.getString("vident." + warningCase + ".currentIdentity") + "</th>" +
242                "<th class='col3'>" + vI.elements.strings.getString("vident." + warningCase + ".storedIdentity") + "</th>" +
243            "</tr></thead>" +
244            "<tbody>" + compareMatrix + "</tbody>" +
245            "</table>"
246        warning.css = "vI_DialogBrowser.css";
247        warning.query = vI.elements.strings.getString("vident." + warningCase + ".query");
248        warning.class = warningCase;
249        return warning;
250    },
251
252    __askWarning : function(warning) {
253        var retVar = { returnValue: null };
254        var answer = window.openDialog("chrome://v_identity/content/vI_Dialog.xul","",
255                    "chrome, dialog, modal, alwaysRaised, resizable=yes",
256                     warning, retVar)
257        return retVar.returnValue;
258    },
259   
260    __updateStorageFromVIdentity : function(recipient, recipientType) {
261        vI_notificationBar.dump("## vI_storage: __updateStorageFromVIdentity.\n")
262        var dontUpdateMultipleNoEqual = (vI.preferences.getBoolPref("storage_dont_update_multiple") &&
263                    vI_storage.multipleRecipients)
264        vI_notificationBar.dump("## vI_storage: __updateStorageFromVIdentity dontUpdateMultipleNoEqual='" + dontUpdateMultipleNoEqual + "'\n")
265        recipient = vI_storage.__getDescriptionAndType(recipient, recipientType);
266
267        var storageDataByType = vI_rdfDatasource.readVIdentityFromRDF(recipient.recDesc, recipient.recType);
268        var storageDataByFilter = vI_rdfDatasource.findMatchingFilter(recipient.recDesc);
269       
270        // update (storing) of data by type is required if there is
271        // no data stored by type (or different data stored) and no equal filter found
272        var storageDataByTypeCompResult = storageDataByType?storageDataByType.equalsCurrentIdentity(true):null;
273        var storageDataByTypeEqual = (storageDataByType && storageDataByTypeCompResult.equal);
274        var storageDataByFilterEqual = (storageDataByFilter && storageDataByFilter.equalsCurrentIdentity(false).equal);
275       
276        var doUpdate = "";
277        if (    (!storageDataByType && !storageDataByFilterEqual) ||
278            (!storageDataByTypeEqual && !storageDataByFilterEqual && !dontUpdateMultipleNoEqual) ) {
279            vI_notificationBar.dump("## vI_storage: __updateStorageFromVIdentity updating\n")
280            var doUpdate = "accept";
281            if (storageDataByType && !storageDataByTypeEqual && vI.preferences.getBoolPref("storage_warn_update")) {
282                vI_notificationBar.dump("## vI_storage: __updateStorageFromVIdentity overwrite warning\n");
283                doUpdate = vI_storage.__askWarning(vI_storage.__getWarning("updateStorage", recipient, storageDataByTypeCompResult.compareMatrix));
284                if (doUpdate == "takeover") {
285                    var msgIdentityCloneElem = document.getElementById("msgIdentity_clone");
286                    msgIdentityCloneElem.selectedMenuItem = msgIdentityCloneElem.addIdentityToCloneMenu(storageDataByType);
287                    return false;
288                }
289                if (doUpdate == "abort") return false;
290            }
291        }
292        if (doUpdate == "accept") vI_rdfDatasource.updateRDFFromVIdentity(recipient.recDesc, recipient.recType);
293        return true;
294    },
295       
296   
297    // --------------------------------------------------------------------
298    // the following function gets a queryString, a callFunction to call for every found Card related to the queryString
299    // and a returnVar, which is passed to the callFunction and returned at the end.
300    // this way the Storage-search is unified for all tasks
301    _walkTroughCards : function (queryString, callFunction, returnVar) {
302        var parentDir = vI_storage.rdfService.GetResource("moz-abdirectory://").QueryInterface(Components.interfaces.nsIAbDirectory);
303        var enumerator = parentDir.childNodes;
304        if (!enumerator) {vI_notificationBar.dump("## vI_storage: no addressbooks?\n"); return null;} // uups, no addressbooks?
305        while (enumerator && enumerator.hasMoreElements()) {
306            var addrbook = enumerator.getNext();  // an addressbook directory
307            addrbook.QueryInterface(Components.interfaces.nsIAbDirectory);
308            var searchUri = (addrbook.directoryProperties?addrbook.directoryProperties.URI:addrbook.URI) + queryString;
309           
310            // just try the following steps, they might fail if addressbook wasn't configured the right way
311            // not completely reproducible, but caused bug https://www.absorb.it/virtual-id/ticket/41
312            try {
313                var AbView = Components.classes["@mozilla.org/addressbook/abview;1"].createInstance(Components.interfaces.nsIAbView);
314                AbView.init(searchUri, true, null, "GeneratedName", "ascending");
315            } catch (ex) { break; };
316            var directory = AbView.directory;
317           
318            // directory will now be a subset of the addressbook containing only those cards that match the searchstring
319            if (!directory) break;
320            var childCards = null; var keepGoing = 1;
321            try { childCards = directory.childCards; childCards.first(); } catch (ex) { keepGoing = 0; }
322           
323            while (keepGoing == 1) {
324                var currentCard = childCards.currentItem();
325                currentCard.QueryInterface(Components.interfaces.nsIAbCard);
326                callFunction(addrbook, currentCard, returnVar);
327                try { childCards.next(); } catch (ex) { keepGoing = 0; }
328            }
329        }
330        return returnVar;
331    },
332       
333    // --------------------------------------------------------------------
334    // check if recipient is a mailing list.
335    // Similiar to Thunderbird, if there are muliple cards with the same displayName the mailinglist is preferred
336    // see also https://bugzilla.mozilla.org/show_bug.cgi?id=408575
337    isMailingList: function(recipient) {
338        var queryString = "?(or(DisplayName,c," + encodeURIComponent(vI_storage.getMailListName(recipient)) + "))"
339        var returnVar = vI_storage._walkTroughCards(queryString, vI_storage._isMailingListCard,
340            { mailListName : vI_storage.getMailListName(recipient), isMailList : false } )
341        return returnVar.isMailList;
342    }, 
343   
344    _isMailingListCard : function (addrbook, Card, returnVar) {
345    // returnVar = { mailListName : mailListName, isMailList : false }
346        returnVar.isMailList = (returnVar.isMailList ||
347            Card.isMailList && Card.displayName.toLowerCase() == returnVar.mailListName.toLowerCase() )
348    },
349   
350    // --------------------------------------------------------------------
351   
352    getMailListName : function(recipient) {
353        if (recipient.match(/<[^>]*>/) || recipient.match(/$/)) {
354            var mailListName = RegExp.leftContext + RegExp.rightContext
355            mailListName = mailListName.replace(/^\s+|\s+$/g,"")
356        }
357        return mailListName;
358    },
359   
360    __isDoBcc : function(row) {
361        var recipientType = awGetPopupElement(row).selectedItem.getAttribute("value");
362        if (recipientType != "addr_bcc" || !getCurrentIdentity().doBcc) return false
363        var doBccArray = gMsgCompose.compFields.SplitRecipients(getCurrentIdentity().doBccList, false);
364        for (var index = 0; index < doBccArray.count; index++ ) {
365            if (doBccArray.StringAt(index) == awGetInputElement(row).value) {
366                vI_notificationBar.dump("## vI_storage: ignoring doBcc field '" +
367                    doBccArray.StringAt(index) + "'.\n");
368                return true;
369            }
370        }       
371        return false
372    },
373
374    getVIdentityFromAllRecipients : function(allIdentities) {
375        if (!vI.preferences.getBoolPref("storage"))
376            { vI_notificationBar.dump("## vI_storage: Storage deactivated\n"); return; }
377        vI_notificationBar.dump("## vI_storage: getVIdentityFromAllRecipients()\n");
378
379        for (var row = 1; row <= top.MAX_RECIPIENTS; row ++) {
380            var recipientType = awGetPopupElement(row).selectedItem.getAttribute("value");
381            if (recipientType == "addr_reply" || recipientType == "addr_followup" || vI_storage.__isDoBcc(row)) continue;
382            vI_storage.lastCheckedEmail[row] = awGetInputElement(row).value;
383            var recipient = vI_storage.__getDescriptionAndType(awGetInputElement(row).value, recipientType);
384            var storageData = vI_rdfDatasource.readVIdentityFromRDF(recipient.recDesc, recipient.recType);
385            if (storageData) allIdentities.addWithoutDuplicates(storageData);
386            storageData = vI_rdfDatasource.findMatchingFilter(recipient.recDesc);
387            if (storageData) allIdentities.addWithoutDuplicates(storageData);
388        }
389        vI_notificationBar.dump("## vI_storage: found " + allIdentities.number + " address(es)\n")
390    }
391}
Note: See TracBrowser for help on using the repository browser.