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 @ 75af75

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

reimplemented autoReplyTo

  • Property mode set to 100644
File size: 17.6 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   
106   
107    firstUsedInputElement : null,   // this stores the first Element for which a Lookup in the Storage was successfull
108    updateVIdentityFromStorage: function(inputElement) {       
109        if (!vI.preferences.getBoolPref("storage"))
110            { vI_notificationBar.dump("## vI_storage: Storage deactivated\n"); return; }
111        vI_notificationBar.dump("## vI_storage: updateVIdentityFromStorage()\n");
112
113        var recipientType = document.getElementById(inputElement.id.replace(/^addressCol2/,"addressCol1"))
114            .selectedItem.getAttribute("value");
115        var row = inputElement.id.replace(/^addressCol2#/,"")
116        if (recipientType == "addr_reply" || recipientType == "addr_followup" || vI_storage.__isDoBcc(row)) {
117            // reset firstUsedInputElement if recipientType was changed (and don't care about doBcc fields)
118            if (vI_storage.firstUsedInputElement == inputElement)
119                vI_storage.firstUsedInputElement = null;
120            vI_notificationBar.dump("## vI_storage: field is a 'reply-to' or 'followup-to' or preconfigured 'doBcc'. not searched.\n")
121            return;
122        }
123       
124        if (inputElement.value == "") {
125            vI_notificationBar.dump("## vI_storage: no recipient found, not checked.\n"); return;
126        }
127       
128        var row = inputElement.id.replace(/^addressCol2#/,"")
129        if (vI_storage.lastCheckedEmail[row] && vI_storage.lastCheckedEmail[row] == inputElement.value) {
130            vI_notificationBar.dump("## vI_storage: same email than before, not checked again.\n"); return;
131        }
132        vI_storage.lastCheckedEmail[row] = inputElement.value;
133        var recipient = vI_storage.__getDescriptionAndType(inputElement.value, recipientType);
134
135        var matchResults = { storageData : {}, menuItem : {} };
136        matchResults.storageData[0] = vI_rdfDatasource.readVIdentityFromRDF(recipient.recDesc, recipient.recType),
137        matchResults.storageData[1] = vI_rdfDatasource.findMatchingFilter(recipient.recDesc);
138
139        var matchIndex = null;
140        for (var i = 0; i <= 1; i++) {
141            if (matchResults.storageData[i]) {
142                if (matchIndex == null) matchIndex = i;
143                matchResults.menuItem[i] = document.getElementById("msgIdentity_clone")
144                                .addIdentityToCloneMenu(matchResults.storageData[i]);
145            }
146        }
147        if (matchIndex == null) return;
148       
149        // found storageData, so store InputElement
150        if (!vI_storage.firstUsedInputElement) vI_storage.firstUsedInputElement = inputElement;
151       
152        vI_notificationBar.dump("## vI_storage: compare with current Identity\n");
153        if (vI.preferences.getBoolPref("storage_getOneOnly") &&
154            vI_storage.firstUsedInputElement &&
155            vI_storage.firstUsedInputElement != inputElement &&
156            !matchResults.storageData[matchIndex].equalsCurrentIdentity(false).equal)
157                vI_notificationBar.setNote(vI.elements.strings
158                    .getString("vident.smartIdentity.vIStorageCollidingIdentity"),
159                    "storage_notification");
160        // only update fields if new Identity is different than old one.
161        else {
162            var compResult = matchResults.storageData[matchIndex].equalsCurrentIdentity(true);
163            if (!compResult.equal) {
164                var warning = vI_storage.__getWarning("replaceVIdentity", recipient, compResult.compareMatrix);
165                var msgIdentityCloneElem = document.getElementById("msgIdentity_clone")
166                if (    !msgIdentityCloneElem.vid ||
167                    !vI.preferences.getBoolPref("storage_warn_vI_replace") ||
168                    (vI_storage.__askWarning(warning) == "accept")) {
169                        msgIdentityCloneElem.selectedMenuItem = matchResults.menuItem[matchIndex];
170                        if (msgIdentityCloneElem.vid)
171                            vI_notificationBar.setNote(vI.elements.strings.getString("vident.smartIdentity.vIStorageUsage") + ".",
172                            "storage_notification");
173                }
174            }
175        }
176    },
177   
178    __getDescriptionAndType : function (recipient, recipientType) {
179        if (recipientType == "addr_newsgroups") return { recDesc : recipient, recType : "newsgroup" }
180        else if (vI_storage.isMailingList(recipient))
181            return { recDesc : vI_storage.getMailListName(recipient), recType : "maillist" }
182        else 
183            return { recDesc : vI_helper.parseAddress(recipient).combinedName, recType : "email" }
184    },
185       
186    storeVIdentityToAllRecipients : function(msgType) {
187        if (msgType != nsIMsgCompDeliverMode.Now) return true;
188        vI_notificationBar.dump("## vI_storage: ----------------------------------------------------------\n")
189        if (!vI.preferences.getBoolPref("storage"))
190            { vI_notificationBar.dump("## vI_storage: Storage deactivated\n"); return true; }
191       
192        if (vI_statusmenu.objStorageSaveMenuItem.getAttribute("checked") != "true") {
193            vI_notificationBar.dump("## vI_storage: SaveMenuItem not checked.\n")
194            return true;
195        }
196       
197        vI_notificationBar.dump("## vI_storage: storeVIdentityToAllRecipients()\n");
198       
199        // check if there are multiple recipients
200        vI_storage.multipleRecipients = false;
201        var recipients = 0;
202        for (var row = 1; row <= top.MAX_RECIPIENTS; row ++) {
203            var recipientType = awGetPopupElement(row).selectedItem.getAttribute("value");
204            if (recipientType == "addr_reply" || recipientType == "addr_followup" || 
205                vI_storage.__isDoBcc(row) || awGetInputElement(row).value.match(/^\s*$/) ) continue;
206            if (recipients++ == 1) {
207                vI_storage.multipleRecipients = true
208                vI_notificationBar.dump("## vI_storage: multiple recipients found.\n")
209                break;
210            }
211        }           
212       
213        for (var row = 1; row <= top.MAX_RECIPIENTS; row ++) {
214            var recipientType = awGetPopupElement(row).selectedItem.getAttribute("value");
215            if (recipientType == "addr_reply" || recipientType == "addr_followup" || 
216                vI_storage.__isDoBcc(row) || awGetInputElement(row).value.match(/^\s*$/) ) continue;
217            if (!vI_storage.__updateStorageFromVIdentity(awGetInputElement(row).value, recipientType)) {
218                vI_notificationBar.dump("## vI_storage: --------------  aborted  ---------------------------------\n")
219                return false; // abort sending
220            }
221        }
222        vI_notificationBar.dump("## vI_storage: ----------------------------------------------------------\n");
223        return true;
224    },
225   
226    __getWarning : function(warningCase, recipient, compareMatrix) {
227        var warning = { title: null, recLabel : null, recipient : null, warning : null, css: null, query : null, class : null };
228        warning.title = vI.elements.strings.getString("vident." + warningCase + ".title")
229        warning.recLabel = vI.elements.strings.getString("vident." + warningCase + ".recipient") + " (" + recipient.recType + "):"
230        warning.recipient = recipient.recDesc;
231        warning.warning = 
232            "<table class='" + warningCase + "'><thead><tr><th class='col1'/>" +
233                "<th class='col2'>" + vI.elements.strings.getString("vident." + warningCase + ".currentIdentity") + "</th>" +
234                "<th class='col3'>" + vI.elements.strings.getString("vident." + warningCase + ".storedIdentity") + "</th>" +
235            "</tr></thead>" +
236            "<tbody>" + compareMatrix + "</tbody>" +
237            "</table>"
238        warning.css = "vI_DialogBrowser.css";
239        warning.query = vI.elements.strings.getString("vident." + warningCase + ".query");
240        warning.class = warningCase;
241        return warning;
242    },
243
244    __askWarning : function(warning) {
245        var retVar = { returnValue: null };
246        var answer = window.openDialog("chrome://v_identity/content/vI_Dialog.xul",0,
247                    "chrome, dialog, modal, alwaysRaised, resizable=yes",
248                     warning, retVar)
249        return retVar.returnValue;
250    },
251   
252    __updateStorageFromVIdentity : function(recipient, recipientType) {
253        vI_notificationBar.dump("## vI_storage: __updateStorageFromVIdentity.\n")
254        var dontUpdateMultipleNoEqual = (vI.preferences.getBoolPref("storage_dont_update_multiple") &&
255                    vI_storage.multipleRecipients)
256       
257        recipient = vI_storage.__getDescriptionAndType(recipient, recipientType);
258
259        var matchResults = { storageData : {} };
260        matchResults.storageData[0] = vI_rdfDatasource.readVIdentityFromRDF(recipient.recDesc, recipient.recType),
261        matchResults.storageData[1] = vI_rdfDatasource.findMatchingFilter(recipient.recDesc);
262
263        for (var i = 0; i <= 1; i++) {
264            if (matchResults.storageData[i]) {
265                var compResult = matchResults.storageData[i].equalsCurrentIdentity(true);
266                if (compResult.equal) return true;
267                else if (!dontUpdateMultipleNoEqual) {
268                    var warning = vI_storage.__getWarning("updateStorage", recipient, compResult.compareMatrix);
269                    vI_notificationBar.dump("## vI_storage: " + warning + ".\n")
270                    var doUpdate = "accept";
271                    if (i == 0 && vI.preferences.getBoolPref("storage_warn_update")) doUpdate = vI_storage.__askWarning(warning);
272                    switch(doUpdate) {
273                        case "abort":
274                            return false;
275                        case "accept":
276                            vI_rdfDatasource.updateRDFFromVIdentity(recipient.recDesc, recipient.recType);
277                            return true;
278                    }
279                }
280            }
281        }
282        vI_rdfDatasource.updateRDFFromVIdentity(recipient.recDesc, recipient.recType);
283        return true;
284    },
285       
286   
287    // --------------------------------------------------------------------
288    // the following function gets a queryString, a callFunction to call for every found Card related to the queryString
289    // and a returnVar, which is passed to the callFunction and returned at the end.
290    // this way the Storage-search is unified for all tasks
291    _walkTroughCards : function (queryString, callFunction, returnVar) {
292        var parentDir = vI_storage.rdfService.GetResource("moz-abdirectory://").QueryInterface(Components.interfaces.nsIAbDirectory);
293        var enumerator = parentDir.childNodes;
294        if (!enumerator) {vI_notificationBar.dump("## vI_storage: no addressbooks?\n"); return null;} // uups, no addressbooks?
295        while (enumerator && enumerator.hasMoreElements()) {
296            var addrbook = enumerator.getNext();  // an addressbook directory
297            addrbook.QueryInterface(Components.interfaces.nsIAbDirectory);
298            var searchUri = (addrbook.directoryProperties?addrbook.directoryProperties.URI:addrbook.URI) + queryString;
299           
300            // just try the following steps, they might fail if addressbook wasn't configured the right way
301            // not completely reproducible, but caused bug https://www.absorb.it/virtual-id/ticket/41
302            try {
303                var AbView = Components.classes["@mozilla.org/addressbook/abview;1"].createInstance(Components.interfaces.nsIAbView);
304                AbView.init(searchUri, true, null, "GeneratedName", "ascending");
305            } catch (ex) { break; };
306            var directory = AbView.directory;
307           
308            // directory will now be a subset of the addressbook containing only those cards that match the searchstring
309            if (!directory) break;
310            var childCards = null; var keepGoing = 1;
311            try { childCards = directory.childCards; childCards.first(); } catch (ex) { keepGoing = 0; }
312           
313            while (keepGoing == 1) {
314                var currentCard = childCards.currentItem();
315                currentCard.QueryInterface(Components.interfaces.nsIAbCard);
316                callFunction(addrbook, currentCard, returnVar);
317                try { childCards.next(); } catch (ex) { keepGoing = 0; }
318            }
319        }
320        return returnVar;
321    },
322       
323    // --------------------------------------------------------------------
324    // check if recipient is a mailing list.
325    // Similiar to Thunderbird, if there are muliple cards with the same displayName the mailinglist is preferred
326    // see also https://bugzilla.mozilla.org/show_bug.cgi?id=408575
327    isMailingList: function(recipient) {
328        var queryString = "?(or(DisplayName,c," + encodeURIComponent(vI_storage.getMailListName(recipient)) + "))"
329        var returnVar = vI_storage._walkTroughCards(queryString, vI_storage._isMailingListCard,
330            { mailListName : vI_storage.getMailListName(recipient), isMailList : false } )
331        return returnVar.isMailList;
332    }, 
333   
334    _isMailingListCard : function (addrbook, Card, returnVar) {
335    // returnVar = { mailListName : mailListName, isMailList : false }
336        returnVar.isMailList = (returnVar.isMailList ||
337            Card.isMailList && Card.displayName.toLowerCase() == returnVar.mailListName.toLowerCase() )
338    },
339   
340    // --------------------------------------------------------------------
341   
342    getMailListName : function(recipient) {
343        if (recipient.match(/<[^>]*>/) || recipient.match(/$/)) {
344            var mailListName = RegExp.leftContext + RegExp.rightContext
345            mailListName = mailListName.replace(/^\s+|\s+$/g,"")
346        }
347        return mailListName;
348    },
349   
350    __isDoBcc : function(row) {
351        var recipientType = awGetPopupElement(row).selectedItem.getAttribute("value");
352        if (recipientType != "addr_bcc" || !getCurrentIdentity().doBcc) return false
353        var doBccArray = gMsgCompose.compFields.SplitRecipients(getCurrentIdentity().doBccList, false);
354        for (var index = 0; index < doBccArray.count; index++ ) {
355            if (doBccArray.StringAt(index) == awGetInputElement(row).value) {
356                vI_notificationBar.dump("## vI_storage: ignoring doBcc field '" +
357                    doBccArray.StringAt(index) + "'.\n");
358                return true;
359            }
360        }       
361        return false
362    },
363
364    getVIdentityFromAllRecipients : function(allIdentities) {
365        if (!vI.preferences.getBoolPref("storage"))
366            { vI_notificationBar.dump("## vI_storage: Storage deactivated\n"); return; }
367        vI_notificationBar.dump("## vI_storage: getVIdentityFromAllRecipients()\n");
368
369        for (var row = 1; row <= top.MAX_RECIPIENTS; row ++) {
370            var recipientType = awGetPopupElement(row).selectedItem.getAttribute("value");
371            if (recipientType == "addr_reply" || recipientType == "addr_followup" || vI_storage.__isDoBcc(row)) continue;
372            vI_storage.lastCheckedEmail[row] = awGetInputElement(row).value;
373            var recipient = vI_storage.__getDescriptionAndType(awGetInputElement(row).value, recipientType);
374            var storageData = vI_rdfDatasource.readVIdentityFromRDF(recipient.recDesc, recipient.recType);
375            if (storageData) allIdentities.addWithoutDuplicates(storageData);
376            storageData = vI_rdfDatasource.findMatchingFilter(recipient.recDesc);
377            if (storageData) allIdentities.addWithoutDuplicates(storageData);
378        }
379        vI_notificationBar.dump("## vI_storage: found " + allIdentities.number + " address(es)\n")
380    }
381}
Note: See TracBrowser for help on using the repository browser.