home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / mozil06.zip / bin / chrome / messenger.jar / content / messenger / AccountManager.js < prev    next >
Text File  |  2001-03-23  |  23KB  |  785 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  * The contents of this file are subject to the Netscape Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/NPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is Mozilla Communicator client code, released
  13.  * March 31, 1998.
  14.  * 
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation. Portions created by Netscape are
  17.  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  */
  20.  
  21. /*
  22.  * here's how this dialog works:
  23.  * The main dialog contains a tree on the left (accounttree) and a
  24.  * deck on the right. Each card in the deck on the right contains an
  25.  * IFRAME which loads a particular preference document (such as am-main.xul)
  26.  *
  27.  * when the user clicks on items in the tree on the right, two things have
  28.  * to be determined before the UI can be updated:
  29.  * - the relevant account
  30.  * - the relevant page
  31.  *
  32.  * when both of these are known, this is what happens:
  33.  * - every form element of the previous page is saved in the account value
  34.  *   hashtable for the previous account
  35.  * - the card containing the relevant page is brought to the front
  36.  * - each form element in the page is filled in with an appropriate value
  37.  *   from the current account's hashtable
  38.  * - in the IFRAME inside the page, if there is an onInit() method,
  39.  *   it is called. The onInit method can further update this page based
  40.  *   on values set in the previous step.
  41.  */
  42.  
  43.  
  44. var accountArray;
  45. var accounttree;
  46.  
  47. var currentServerId;
  48. var currentPageId;
  49.  
  50. var pendingServerId;
  51. var pendingPageId;
  52. var Bundle = srGetStrBundle("chrome://messenger/locale/prefs.properties");
  53.  
  54. // services used
  55. var RDF;
  56. var accountManager;
  57. var smtpService;
  58.  
  59. // widgets
  60. var duplicateButton;
  61. var deleteButton;
  62. var newAccountButton;
  63. var setDefaultButton;
  64.  
  65. // called when the whole document loads
  66. // perform initialization here
  67. function onLoad() {
  68.   
  69.   var selectedAccount;
  70.   if (window.arguments && window.arguments[0])
  71.     selectedServer = window.arguments[0].server;
  72.   
  73.   accountArray = new Array;
  74.   RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  75.  
  76.   accountManager = Components.classes["@mozilla.org/messenger/account-manager;1"].getService(Components.interfaces.nsIMsgAccountManager);
  77.  
  78.   smtpService =
  79.     Components.classes["@mozilla.org/messengercompose/smtp;1"].getService(Components.interfaces.nsISmtpService);
  80.   accounttree = document.getElementById("accounttree");
  81.   
  82.   doSetOKCancel(onOk, 0);
  83.  
  84.   newAccountButton = document.getElementById("newAccountButton");
  85.   duplicateButton = document.getElementById("duplicateButton");
  86.   deleteButton = document.getElementById("deleteButton");
  87.   setDefaultButton = document.getElementById("setDefaultButton");
  88.  
  89.   sortAccountList(accounttree);
  90.   selectServer(selectedServer)
  91. }
  92.  
  93. function sortAccountList(accounttree)
  94. {
  95.   var xulSortService = Components.classes["@mozilla.org/rdf/xul-sort-service;1"].getService(Components.interfaces.nsIXULSortService);
  96.   
  97.   xulSortService.Sort(accounttree, 'http://home.netscape.com/NC-rdf#FolderTreeName?sort=true', 'ascending');
  98. }
  99.  
  100. function selectServer(server)
  101. {
  102.   var selectedItem;
  103.   
  104.   if (server)
  105.     selectedItem = document.getElementById(server.serverURI);
  106.  
  107.   if (!selectedItem)
  108.     selectedItem = getFirstAccount();
  109.   
  110.   accounttree.selectItem(selectedItem);
  111.   
  112.   var result = getServerIdAndPageIdFromTree(accounttree);
  113.   if (result) {
  114.     updateButtons(accounttree,result.serverId);
  115.   }
  116. }
  117.  
  118. function getFirstAccount()
  119. {
  120.   var tree = document.getElementById("accounttree");
  121.   var firstItem = findFirstTreeItem(tree);
  122.  
  123.   return firstItem;
  124. }
  125.  
  126. function findFirstTreeItem(tree) {
  127.   var children = tree.childNodes;
  128.   
  129.   var treechildren;
  130.   for (var i=0;i<children.length; i++) {
  131.     if (children[i].localName == "treechildren") {
  132.       treechildren = children[i];
  133.       break;
  134.     }
  135.   }
  136.  
  137.   var children = treechildren.childNodes;
  138.   for (var i=0; i<children.length; i++) {
  139.     if (children[i].localName == "treeitem")
  140.       return children[i];
  141.   }
  142. }
  143.  
  144. function onOk() {
  145.   onSave();
  146.     // hack hack - save the prefs file NOW in case we crash
  147.     try {
  148.         var prefs = Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPref);
  149.         prefs.SavePrefFile();
  150.     } catch (ex) {
  151.         dump("Error saving prefs!\n");
  152.     }
  153.   return true;
  154. }
  155.  
  156. function onSave() {
  157.  
  158.   if (pendingPageId) {
  159.     dump("ERROR: " + pendingPageId + " hasn't loaded yet! Not saving.\n");
  160.     return;
  161.   }
  162.   
  163.   // make sure the current visible page is saved
  164.   savePage(currentServerId);
  165.  
  166.   for (var accountid in accountArray) {
  167.     var account = getAccountFromServerId(accountid);
  168.     var accountValues = accountArray[accountid];
  169.  
  170.     saveAccount(accountValues, account);
  171.   }
  172. }
  173.  
  174. function onNewAccount() {
  175.   MsgAccountWizard();
  176. }
  177.  
  178. function onDuplicateAccount() {
  179.     //dump("onDuplicateAccount\n");
  180.  
  181.     if (duplicateButton.getAttribute("disabled") == "true") return;
  182.  
  183.     var result = getServerIdAndPageIdFromTree(accounttree);
  184.     if (result) {
  185.         var canDuplicate = true;
  186.         var account = getAccountFromServerId(result.serverId);
  187.         if (account) {
  188.             var server = account.incomingServer;
  189.             var type = server.type;
  190.  
  191.             var protocolinfo = Components.classes["@mozilla.org/messenger/protocol/info;1?type=" + type].getService(Components.interfaces.nsIMsgProtocolInfo);
  192.             canDuplicate = protocolinfo.canDuplicate;
  193.         }
  194.         else {
  195.             canDuplicate = false;
  196.         }
  197.  
  198.         if (canDuplicate) {
  199.             try {
  200.               accountManager.duplicateAccount(account);
  201.             }
  202.             catch (ex) {
  203.                 var alertText = Bundle.GetStringFromName("failedDuplicateAccount");
  204.                 window.alert(alertText); 
  205.             }
  206.         }
  207.     }
  208. }         
  209.  
  210. function onSetDefault(event) {
  211.   if (event.target.getAttribute("disabled") == "true") return;
  212.  
  213.   var result = getServerIdAndPageIdFromTree(accounttree);
  214.   if (!result) return;
  215.   
  216.   var account = getAccountFromServerId(result.serverId);
  217.   if (!account) return;
  218.  
  219.   accountManager.defaultAccount = account;
  220. }
  221.  
  222. function onDeleteAccount(event) {
  223.     //dump("onDeleteAccount\n");
  224.  
  225.     if (event.target.getAttribute("disabled") == "true") return;
  226.  
  227.     var result = getServerIdAndPageIdFromTree(accounttree);
  228.     if (!result) return;
  229.     
  230.     var account = getAccountFromServerId(result.serverId);
  231.     if (!account) return;
  232.  
  233.     var server = account.incomingServer;
  234.     var type = server.type; 
  235.  
  236.     var protocolinfo = Components.classes["@mozilla.org/messenger/protocol/info;1?type=" + type].getService(Components.interfaces.nsIMsgProtocolInfo);
  237.     if (!protocolinfo.canDelete) return;
  238.  
  239.     var confirmDeleteAccount =
  240.       Bundle.GetStringFromName("confirmDeleteAccount");
  241.     if (!window.confirm(confirmDeleteAccount)) return;
  242.     
  243.     try {
  244.       // clear cached data out of the account array
  245.       if (accountArray[result.serverId])
  246.         accountArray[result.serverId] = null;
  247.       currentServerId = currentPageId = null;
  248.       
  249.       accountManager.removeAccount(account);
  250.       selectServer(null);
  251.     }
  252.     catch (ex) {
  253.       dump("failure to delete account: " + ex + "\n");
  254.       var alertText = Bundle.GetStringFromName("failedDeleteAccount");
  255.       window.alert(alertText);
  256.     }
  257. }
  258.  
  259. function saveAccount(accountValues, account)
  260. {
  261.   var identity = null;
  262.   var server = null;
  263.   
  264.   if (account) {
  265.     identity = account.defaultIdentity;
  266.     server = account.incomingServer;
  267.   }
  268.  
  269.   for (var type in accountValues) {
  270.     var typeArray = accountValues[type];
  271.  
  272.     for (var slot in typeArray) {
  273.       var dest;
  274.       try {
  275.       if (type == "identity")
  276.         dest = identity;
  277.       else if (type == "server")
  278.         dest = server;
  279.       else if (type == "pop3")
  280.         dest = server.QueryInterface(Components.interfaces.nsIPop3IncomingServer);
  281.       
  282.       else if (type == "imap")
  283.         dest = server.QueryInterface(Components.interfaces.nsIImapIncomingServer);
  284.       
  285.       else if (type == "none")
  286.         dest = server.QueryInterface(Components.interfaces.nsINoIncomingServer); 
  287.       
  288.       else if (type == "nntp")
  289.         dest = server.QueryInterface(Components.interfaces.nsINntpIncomingServer);
  290.       else if (type == "smtp")
  291.         dest = smtpService.defaultServer;
  292.       
  293.       } catch (ex) {
  294.         // don't do anything, just means we don't support that
  295.       }
  296.       if (dest == undefined) continue;
  297.  
  298.       if (dest[slot] != typeArray[slot]) {
  299.         try {
  300.           dest[slot] = typeArray[slot];
  301.         } catch (ex) {
  302.           // hrm... need to handle special types here
  303.         }
  304.       }
  305.     }
  306.   }
  307. }
  308.  
  309.  
  310. function updateButtons(tree,serverId) {
  311.   var canDuplicate = true;
  312.   var canDelete = true;
  313.   var canSetDefault = true;
  314.  
  315.   //dump("updateButtons\n");
  316.   //dump("serverId = " + serverId + "\n");
  317.   var account = getAccountFromServerId(serverId);
  318.   //dump("account = " + account + "\n");
  319.  
  320.   if (account) {
  321.     var server = account.incomingServer;
  322.     var type = server.type;
  323.  
  324.     if (account.identities.Count() < 1)
  325.       canSetDefault = false;
  326.     
  327.     //dump("servertype = " + type + "\n");
  328.  
  329.     var protocolinfo = Components.classes["@mozilla.org/messenger/protocol/info;1?type=" + type].getService(Components.interfaces.nsIMsgProtocolInfo);
  330.     canDuplicate = protocolinfo.canDuplicate;
  331.     canDelete = protocolinfo.canDelete;
  332.  
  333.   }
  334.   else {
  335.     // HACK
  336.     // if account is null, we have either selected a SMTP server, or there is a problem
  337.     // either way, we don't want the user to be able to delete it or duplicate it
  338.     canSetDefault = false;
  339.     canDelete = false;
  340.     canDuplicate = false;
  341.   }
  342.  
  343.   if (tree.selectedItems.length < 1)
  344.     canDuplicate = canSetDefault = canDelete = false;
  345.   
  346.   setEnabled(duplicateButton, canDuplicate);
  347.   setEnabled(setDefaultButton, canSetDefault);
  348.   setEnabled(deleteButton, canDelete);
  349.   
  350. }
  351.  
  352. function setEnabled(control, enabled)
  353. {
  354.   if (!control) return;
  355.   if (enabled)
  356.     control.removeAttribute("disabled");
  357.   else
  358.     control.setAttribute("disabled", true);
  359. }
  360.  
  361. // this is a workaround for bug #51546
  362. // the on click handler is getting called twice
  363. var bug51546CurrentPage = null;
  364. var bug51546CurrentServerId = null;
  365.  
  366. //
  367. // called when someone clicks on an account
  368. // figure out context by what they clicked on
  369. //
  370. function onAccountClick(tree) {
  371.   //dump("onAccountClick()\n");
  372.  
  373.   var result = getServerIdAndPageIdFromTree(tree);
  374.  
  375.   //dump("sputter:"+bug51546CurrentPage+","+bug51546CurrentServerId+":"+result.pageId+","+result.serverId+"\n");
  376.   if ((bug51546CurrentPage == result.pageId) && (bug51546CurrentServerId == result.serverId)) {
  377.     //dump("workaround for #51546\n");
  378.     return;
  379.   }
  380.   
  381.   bug51546CurrentPage = result.pageId;
  382.   bug51546CurrentServerId = result.serverId;
  383.   
  384.   if (result) {
  385.       showPage(result.serverId, result.pageId);
  386.       updateButtons(tree,result.serverId);
  387.   }
  388. }
  389.  
  390. // show the page for the given server:
  391. // - save the old values
  392. // - start loading the new page
  393. function showPage(serverId, pageId) {
  394.  
  395.   if (pageId == currentPageId &&
  396.       serverId == currentServerId)
  397.     return;
  398.  
  399.  
  400.   // save the previous page
  401.   savePage(currentServerId);
  402.   
  403.   // loading a complete different page
  404.   if (pageId != currentPageId) {
  405.     
  406.     // prevent overwriting with bad stuff
  407.     currentServerId = currentPageId = null;
  408.     
  409.     pendingServerId=serverId;
  410.     pendingPageId=pageId;
  411.     loadPage(pageId);
  412.   }
  413.   
  414.   // same page, different server
  415.   else if (serverId != currentServerId) {
  416.     restorePage(pageId, serverId);
  417.   }
  418.   
  419. }
  420.  
  421. // page has loaded
  422. function onPanelLoaded(pageId) {
  423.   if (pageId != pendingPageId) {
  424.     
  425.     // if we're reloading the current page, we'll assume the
  426.     // page has asked itself to be completely reloaded from
  427.     // the prefs. to do this, clear out the the old entry in
  428.     // the account data, and then restore theh page
  429.     if (pageId == currentPageId) {
  430.       clearAccountData(currentServerId, currentPageId);
  431.       restorePage(currentPageId, currentServerId);
  432.     }
  433.   } else {
  434.  
  435.     restorePage(pendingPageId, pendingServerId);
  436.   }
  437.  
  438.   // probably unnecessary, but useful for debugging
  439.   pendingServerId = null;
  440.   pendingPageId = null;
  441. }
  442.  
  443.  
  444. function loadPage(pageId)
  445. {
  446.   document.getElementById("contentFrame").setAttribute("src","chrome://messenger/content/" + pageId);
  447. }
  448.  
  449. //
  450. // save the values of the widgets to the given server
  451. //
  452. function savePage(serverId) {
  453.   
  454.   if (!serverId) return;
  455.  
  456.   // tell the page that it's about to save
  457.   if (top.frames["contentFrame"].onSave)
  458.       top.frames["contentFrame"].onSave();
  459.   
  460.   var accountValues = getValueArrayFor(serverId);
  461.   var pageElements = getPageFormElements();
  462.  
  463.   if (pageElements == null) return;
  464.  
  465.   // store the value in the account
  466.   for (var i=0; i<pageElements.length; i++) {
  467.       if (pageElements[i].id) {
  468.         var vals = pageElements[i].id.split(".");
  469.         var type = vals[0];
  470.         var slot = vals[1];
  471.  
  472.         setAccountValue(accountValues,
  473.                         type, slot,
  474.                         getFormElementValue(pageElements[i]));
  475.       }
  476.   }
  477.  
  478. }
  479.  
  480. function setAccountValue(accountValues, type, slot, value) {
  481.   if (!accountValues[type])
  482.     accountValues[type] = new Array;
  483.  
  484.   //dump("Form->Array: accountValues[" + type + "][" + slot + "] = " + value + "\n");
  485.   
  486.   accountValues[type][slot] = value;
  487. }
  488.  
  489. function getAccountValue(account, accountValues, type, slot) {
  490.   if (!accountValues[type])
  491.     accountValues[type] = new Array;
  492.  
  493.   // fill in the slot from the account if necessary
  494.   if (accountValues[type][slot]== undefined) {
  495.     // dump("Array->Form: lazily reading in the " + slot + " from the " + type + "\n");
  496.     var server;
  497.     if (account)
  498.       server= account.incomingServer;
  499.     var source = null;
  500.     try {
  501.     if (type == "identity")
  502.       source = account.defaultIdentity;
  503.  
  504.     else if (type == "server")
  505.       source = account.incomingServer;
  506.  
  507.     else if (type == "pop3")
  508.       source = server.QueryInterface(Components.interfaces.nsIPop3IncomingServer);
  509.     
  510.     else if (type == "imap")
  511.       source = server.QueryInterface(Components.interfaces.nsIImapIncomingServer);
  512.     
  513.     else if (type == "none")
  514.       source = server.QueryInterface(Components.interfaces.nsINoIncomingServer); 
  515.  
  516.     else if (type == "nntp")
  517.       source = server.QueryInterface(Components.interfaces.nsINntpIncomingServer);
  518.  
  519.     else if (type == "smtp")
  520.         source = smtpService.defaultServer;
  521.     
  522.     } catch (ex) {
  523.     }
  524.     
  525.     if (source) {
  526.       accountValues[type][slot] = source[slot];
  527.     }
  528.   }
  529.   var value = accountValues[type][slot];
  530.   //dump("Array->Form: accountValues[" + type + "][" + slot + "] = " + value + "\n");
  531.   return value;
  532. }
  533. //
  534. // restore the values of the widgets from the given server
  535. //
  536. function restorePage(pageId, serverId) {
  537.   if (!serverId) return;
  538.  
  539.   var accountValues = getValueArrayFor(serverId);
  540.   var pageElements = getPageFormElements();
  541.  
  542.   if (pageElements == null) return;
  543.  
  544.   var account = getAccountFromServerId(serverId);
  545.  
  546.   if (top.frames["contentFrame"].onPreInit)
  547.     top.frames["contentFrame"].onPreInit(account, accountValues);
  548.   
  549.   // restore the value from the account
  550.   for (var i=0; i<pageElements.length; i++) {
  551.       if (pageElements[i].id) {
  552.         var vals = pageElements[i].id.split(".");
  553.         var type = vals[0];
  554.         var slot = vals[1];
  555.  
  556.         var value = getAccountValue(account, accountValues, type, slot);
  557.         setFormElementValue(pageElements[i], value);
  558.       }
  559.   }
  560.  
  561.   // tell the page that new values have been loaded
  562.   if (top.frames["contentFrame"].onInit)
  563.       top.frames["contentFrame"].onInit();
  564.  
  565.   // everything has succeeded, vervied by setting currentPageId
  566.   currentPageId = pageId;
  567.   currentServerId = serverId;
  568.  
  569. }
  570.  
  571. //
  572. // gets the value of a widget
  573. //
  574. function getFormElementValue(formElement) {
  575.  try {
  576.   var type = formElement.localName;
  577.   if (type=="checkbox") {
  578.     if (formElement.getAttribute("reversed"))
  579.       return !formElement.checked;
  580.     else
  581.       return formElement.checked;
  582.   }
  583.  
  584.   else if (type == "radiogroup" || type=="menulist") {
  585.     return formElement.selectedItem.data;
  586.   }
  587.   
  588.   else if (type == "textfield" &&
  589.            formElement.getAttribute("datatype") == "nsIFileSpec") {
  590.     if (formElement.value) {
  591.       var filespec = Components.classes["@mozilla.org/filespec;1"].createInstance(Components.interfaces.nsIFileSpec);
  592.       var filePicker = Components.classes["@mozilla.org/filepicker;1"].createInstance();
  593.       if (filePicker != null) {
  594.         filePicker = filePicker.QueryInterface( Components.interfaces.nsIFilePicker);
  595.         if (filePicker != null) {
  596.           var outvalue = {};
  597.           filePicker.converttofscharset(formElement.value, outvalue);
  598.           filespec.nativePath = outvalue.value;
  599.         }
  600.       }
  601.       if (filePicker == null)
  602.         filespec.nativePath = formElement.value;
  603.       return filespec;
  604.     } else {
  605.       return null;
  606.     }
  607.   }
  608.  
  609.   else if (type == "text") {
  610.     var val = formElement.getAttribute("value");
  611.     if (val) return val;
  612.     else return null;
  613.   }
  614.   
  615.   else {
  616.     return formElement.value;
  617.   }
  618.  }
  619.  catch (ex) {
  620.   dump("getFormElementValue failed, ex="+ex+"\n");
  621.   return null;
  622.  }
  623. }
  624.  
  625. //
  626. // sets the value of a widget
  627. //
  628. function setFormElementValue(formElement, value) {
  629.   
  630.   //formElement.value = formElement.defaultValue;
  631.   //  formElement.checked = formElement.defaultChecked;
  632.   var type = formElement.localName;
  633.   if (type == "checkbox") {
  634.     if (value == undefined) {
  635.       if (formElement.defaultChecked)
  636.         formElement.checked = formElement.defaultChecked;
  637.       else
  638.         formElement.checked = false;
  639.     } else {
  640.       if (formElement.getAttribute("reversed"))
  641.         formElement.checked = !value;
  642.       else
  643.         formElement.checked = value;
  644.     }     
  645.   }
  646.  
  647.   else if (type == "radiogroup" || type =="menulist") {
  648.     
  649.     var selectedItem;
  650.     if (value == undefined) {
  651.       if (type == "radiogroup")
  652.         selectedItem = formElement.firstChild;
  653.       else
  654.         selectedItem = formElement.firstChild.firstChild;
  655.     }
  656.     else
  657.       selectedItem = formElement.getElementsByAttribute("data", value)[0];
  658.     
  659.     formElement.selectedItem = selectedItem;
  660.   }
  661.   // handle nsIFileSpec
  662.   else if (type == "textfield" &&
  663.            formElement.getAttribute("datatype") == "nsIFileSpec") {
  664.     if (value) {
  665.       var filespec = value.QueryInterface(Components.interfaces.nsIFileSpec);
  666.       var filePicker = Components.classes["@mozilla.org/filepicker;1"].createInstance();
  667.       if (filePicker != null) {
  668.         filePicker = filePicker.QueryInterface( Components.interfaces.nsIFilePicker);
  669.         if (filePicker != null) {
  670.           var outvalue = {};
  671.           filePicker.convertfromfscharset(filespec.nativePath, outvalue);
  672.           formElement.value = outvalue.value;
  673.         }
  674.       }
  675.       if (filePicker == null) {
  676.         try {
  677.           formElement.value = filespec.nativePath;
  678.         } catch (ex) {
  679.           dump("Still need to fix uninitialized filespec problem!\n");
  680.         }
  681.       }
  682.     } else {
  683.       if (formElement.defaultValue)
  684.         formElement.value = formElement.defaultValue;
  685.     }
  686.   }
  687.  
  688.   else if (type == "text") {
  689.     if (value == null || value == undefined)
  690.       formElement.removeAttribute("value");
  691.     else
  692.       formElement.setAttribute("value",value);
  693.   }
  694.   
  695.   // let the form figure out what to do with it
  696.   else {
  697.     if (value == undefined) {
  698.       if (formElement.defaultValue)
  699.         formElement.value = formElement.defaultValue;
  700.     }
  701.     else
  702.       formElement.value = value;
  703.   }
  704. }
  705.  
  706. //
  707. // conversion routines - get data associated
  708. // with a given pageId, serverId, etc
  709. //
  710.  
  711. //
  712. // get the account associated with this serverId
  713. //
  714. function getAccountFromServerId(serverId) {
  715.   // get the account by dipping into RDF and then into the acount manager
  716.   var serverResource = RDF.GetResource(serverId);
  717.   try {
  718.     var serverFolder =
  719.       serverResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  720.     var incomingServer = serverFolder.server;
  721.     var account = accountManager.FindAccountForServer(incomingServer);
  722.     return account;
  723.   } catch (ex) {
  724.     return null;
  725.   }
  726. }
  727.  
  728. //
  729. // get the array of form elements for the given page
  730. //
  731. function getPageFormElements() {
  732.  try {
  733.     var pageElements =
  734.       top.frames["contentFrame"].document.getElementsByAttribute("wsm_persist", "true");
  735.     return pageElements;
  736.  }
  737.  catch (ex) {
  738.     dump("getPageFormElements() failed: " + ex + "\n");
  739.  }
  740.  return null;
  741. }
  742.  
  743. //
  744. // get the value array for the given serverId
  745. //
  746. function getValueArrayFor(serverId) {
  747.   if (serverId == undefined) serverId="global";
  748.   
  749.   if (accountArray[serverId] == null) {
  750.     accountArray[serverId] = new Array;
  751.   }
  752.   
  753.   return accountArray[serverId];
  754. }
  755.  
  756. function clearAccountData(serverId, pageId)
  757. {
  758.   accountArray[serverId] = null;
  759. }
  760.  
  761. function getServerIdAndPageIdFromTree(tree)
  762. {
  763.   var serverId = null;
  764.  
  765.   if (tree.selectedItems.length < 1) return null;
  766.   var node = tree.selectedItems[0];
  767.  
  768.   // get the page to load
  769.   // (stored in the PageTag attribute of this node)
  770.   var pageId = node.getAttribute('PageTag');
  771.  
  772.   // get the server's Id
  773.   // (stored in the Id attribute of the server node)
  774.   var servernode = node.parentNode.parentNode;
  775.  
  776.   // for toplevel treeitems, we just use the current treeitem
  777.   //  dump("servernode is " + servernode + "\n");
  778.   if (servernode.localName != "treeitem") {
  779.     servernode = node;
  780.   }
  781.   serverId = servernode.getAttribute('id');  
  782.  
  783.   return {"serverId": serverId, "pageId": pageId }
  784. }
  785.