home *** CD-ROM | disk | FTP | other *** search
/ ftp.swcp.com / ftp.swcp.com.zip / ftp.swcp.com / mac / mozilla-macos9-1.3.1.sea.bin / Mozilla1.3.1 / Chrome / comm.jar / content / editor / publishprefs.js < prev    next >
Text File  |  2003-06-08  |  27KB  |  952 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Netscape Public License
  6.  * Version 1.1 (the "License"); you may not use this file except in
  7.  * compliance with the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/NPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  17.  * The Initial Developer of the Original Code is 
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 2001
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *  cmanske@netscape.com
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the NPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the NPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39.  
  40. /****************** Get publishing data methods *******************/
  41.  
  42. // Build an array of all publish site data obtained from prefs
  43. function GetPublishSiteData()
  44. {
  45.   var publishBranch = GetPublishPrefsBranch();
  46.   if (!publishBranch)
  47.     return null;
  48.  
  49.   // Array of site names - sorted, but don't put default name first
  50.   var siteNameList = GetSiteNameList(true, false);
  51.   if (!siteNameList)
  52.     return null;
  53.  
  54.   // Array of all site data
  55.   var siteArray = [];
  56.  
  57.   // We  rewrite siteName prefs to eliminate names if data is bad
  58.   //  and to be sure order is the same as sorted name list
  59.   try {
  60.     publishBranch.deleteBranch("site_name.");
  61.   } catch (e) {}
  62.  
  63.   // Get publish data using siteName as the key
  64.   var index = 0;
  65.   for (var i = 0; i < siteNameList.length; i++)
  66.   {
  67.     // Associated data uses site name as key
  68.     var publishData = GetPublishData_internal(publishBranch, siteNameList[i]);
  69.     if (publishData)
  70.     {
  71.       siteArray[index] = publishData;
  72.       SetPublishStringPref(publishBranch, "site_name."+index, siteNameList[i]);
  73.       index++;
  74.     }
  75.     else
  76.     {
  77.       try {
  78.         // Remove bad site prefs now
  79.         publishBranch.deleteBranch("site_data." + siteNameList[i] + ".");
  80.       } catch (e) {}
  81.     }
  82.   }
  83.  
  84.   SavePrefFile();
  85.  
  86.   if (index == 0) // No Valid pref records found!
  87.     return null;
  88.  
  89.  
  90.   return siteArray;
  91. }
  92.  
  93. function GetDefaultPublishSiteName()
  94. {
  95.   var publishBranch = GetPublishPrefsBranch();
  96.   var name = "";  
  97.   if (publishBranch)
  98.     name = GetPublishStringPref(publishBranch, "default_site");
  99.  
  100.   return name;
  101. }
  102.  
  103. // Return object with all info needed to publish
  104. //   from database of sites previously published to.
  105. function CreatePublishDataFromUrl(docUrl)
  106. {
  107.   if (!docUrl || IsUrlAboutBlank(docUrl) || GetScheme(docUrl) == "file")
  108.     return null;
  109.  
  110.   var pubSiteData = GetPublishSiteData();
  111.   if (pubSiteData)
  112.   {
  113.     var dirObj = {};
  114.     var index = FindSiteIndexAndDocDir(pubSiteData, docUrl, dirObj);
  115.     var publishData;
  116.     if (index != -1)
  117.     {
  118.       publishData = pubSiteData[index];
  119.       publishData.docDir = FormatDirForPublishing(dirObj.value)
  120.  
  121.       //XXX Problem: OtherDir: How do we decide when to use the dir in 
  122.       //    publishSiteData (default DocDir) or docDir from current filepath?
  123.       publishData.otherDir = FormatDirForPublishing(pubSiteData[index].otherDir);
  124.  
  125.       publishData.filename = GetFilename(docUrl);
  126.       publishData.notInSiteData = false;
  127.       return publishData;
  128.     }
  129.   }
  130.  
  131.   // Document wasn't found in publish site database
  132.   // Create data just from URL
  133.  
  134.   // Extract username and password from docUrl
  135.   var userObj = {};
  136.   var passObj = {};
  137.   var pubUrl = StripUsernamePassword(docUrl, userObj, passObj);
  138.  
  139.   // Strip off filename
  140.   var lastSlash = pubUrl.lastIndexOf("\/");
  141.   //XXX Look for "?", "=", and "&" ?
  142.   pubUrl = pubUrl.slice(0, lastSlash+1);
  143.  
  144.   var siteName = CreateSiteNameFromUrl(pubUrl, pubSiteData);
  145.  
  146.   publishData = { 
  147.     siteName : siteName,
  148.     previousSiteName : siteName,
  149.     filename : GetFilename(docUrl),
  150.     username : userObj.value,
  151.     password : passObj.value,
  152.     savePassword : false,
  153.     publishUrl : pubUrl,
  154.     browseUrl  : pubUrl,
  155.     docDir     : "",
  156.     otherDir   : "",
  157.     publishOtherFiles : true,
  158.     dirList    : [""],
  159.     saveDirs   : false,
  160.     notInSiteData : true
  161.   }
  162.  
  163.   return publishData;
  164. }
  165.  
  166. function CreateSiteNameFromUrl(url, publishSiteData)
  167. {
  168.   var host = GetHost(url);
  169.   var schemePostfix = " (" + GetScheme(url) + ")";
  170.   var siteName = host + schemePostfix;
  171.  
  172.   if (publishSiteData)
  173.   {
  174.     // Look for duplicates. Append "-1"  etc until unique name found
  175.     var i = 1;
  176.     var exists = false;
  177.     do {
  178.       exists = PublishSiteNameExists(siteName, publishSiteData, -1)  
  179.       if (exists)
  180.         siteName = host + "-" + i + schemePostfix;
  181.       i++;
  182.     }
  183.     while (exists);
  184.   }
  185.   return siteName;
  186. }
  187.  
  188. // Similar to above, but in param is a site profile name
  189. // Note that this is more efficient than getting from a URL,
  190. //   since we don't have to get all the sitedata but can key off of sitename.
  191. // Caller must supply the current docUrl or just a filename
  192. // If doc URL is supplied, we find the publish subdirectory if publishUrl is part of docUrl
  193. function GetPublishDataFromSiteName(siteName, docUrlOrFilename)
  194. {
  195.   var publishBranch = GetPublishPrefsBranch();
  196.   if (!publishBranch)
  197.     return null;
  198.  
  199.   var siteNameList = GetSiteNameList(false, false);
  200.   if (!siteNameList)
  201.     return null;
  202.   for (var i = 0; i < siteNameList.length; i++)
  203.   {
  204.     if (siteNameList[i] == siteName)
  205.     {
  206.       var publishData = GetPublishData_internal(publishBranch, siteName);
  207.       if (GetScheme(docUrlOrFilename))
  208.         FillInMatchingPublishData(publishData, docUrlOrFilename);
  209.       else
  210.         publishData.filename = docUrlOrFilename;
  211.  
  212.       return publishData;
  213.     }
  214.   }
  215.   return null;
  216. }
  217.  
  218. function GetDefaultPublishData()
  219. {
  220.   var publishBranch = GetPublishPrefsBranch();
  221.   if (!publishBranch)
  222.     return null;
  223.  
  224.   var siteName = GetPublishStringPref(publishBranch, "default_site");
  225.   if (!siteName)
  226.     return null;
  227.  
  228.   return GetPublishData_internal(publishBranch, siteName);
  229. }
  230.  
  231. function GetPublishData_internal(publishBranch, siteName)
  232. {
  233.   if (!publishBranch || !siteName)
  234.     return null;
  235.  
  236.   var prefPrefix = "site_data." + siteName + ".";
  237.  
  238.   // We must have a publish url, else we ignore this site
  239.   // (siteData and siteNames for sites with incomplete data 
  240.   //  will get deleted by SavePublishSiteDataToPrefs)
  241.   var publishUrl = GetPublishStringPref(publishBranch, prefPrefix+"url");
  242.   if (!publishUrl)
  243.     return null;
  244.  
  245.   var savePassword = false;
  246.   var publishOtherFiles = true;
  247.   try {
  248.     savePassword = publishBranch.getBoolPref(prefPrefix+"save_password");
  249.     publishOtherFiles = publishBranch.getBoolPref(prefPrefix+"publish_other_files");
  250.   } catch (e) {}
  251.  
  252.   var publishData = { 
  253.     siteName : siteName,
  254.     previousSiteName : siteName,
  255.     filename : "",
  256.     username : GetPublishStringPref(publishBranch, prefPrefix+"username"),
  257.     savePassword : savePassword,
  258.     publishUrl : publishUrl,
  259.     browseUrl  : GetPublishStringPref(publishBranch, prefPrefix+"browse_url"),
  260.     docDir     : FormatDirForPublishing(GetPublishStringPref(publishBranch, prefPrefix+"doc_dir")),
  261.     otherDir   : FormatDirForPublishing(GetPublishStringPref(publishBranch, prefPrefix+"other_dir")),
  262.     publishOtherFiles : publishOtherFiles,
  263.     saveDirs : false
  264.   }
  265.  
  266.   // Get password from PasswordManager
  267.   publishData.password = GetSavedPassword(publishData);
  268.  
  269.   // If password was found, user must have checked "Save password"
  270.   //    checkbox in prompt outside of publishing, so override the pref we stored
  271.   if (publishData.password)
  272.   {
  273.     if (!savePassword)
  274.     {
  275.       try {
  276.         publishPrefsBranch.setBoolPref(prefPrefix+"save_password", true);
  277.       } catch (e) {}
  278.     }
  279.     publishData.savePassword = true;
  280.   }
  281.  
  282.   // Build history list of directories 
  283.   // Always supply the root dir 
  284.   publishData.dirList = [""];
  285.  
  286.   // Get the rest from prefs
  287.   var dirCount = {value:0};
  288.   var dirPrefs;
  289.   try {
  290.     dirPrefs = publishBranch.getChildList(prefPrefix+"dir.", dirCount);
  291.   } catch (e) {}
  292.  
  293.   if (dirPrefs && dirCount.value > 0)
  294.   {
  295.     if (dirCount.value > 1)
  296.       dirPrefs.sort();
  297.  
  298.     for (var j = 0; j < dirCount.value; j++)
  299.     {
  300.       var dirName = GetPublishStringPref(publishBranch, dirPrefs[j]);
  301.       if (dirName)
  302.         publishData.dirList[j+1] = dirName;
  303.     }
  304.   }
  305.  
  306.   return publishData;
  307. }
  308.  
  309. /****************** Save publishing data methods *********************/
  310.  
  311. // Save the siteArray containing all current publish site data
  312. function SavePublishSiteDataToPrefs(siteArray, defaultName)
  313. {
  314.   var publishBranch = GetPublishPrefsBranch();
  315.   if (!publishBranch)
  316.     return false;
  317.  
  318.   try {
  319.     if (siteArray)
  320.     {
  321.       var defaultFound = false;
  322.  
  323.       // Clear existing names and data -- rebuild all site prefs
  324.       publishBranch.deleteBranch("site_name.");
  325.       publishBranch.deleteBranch("site_data.");
  326.  
  327.       for (var i = 0; i < siteArray.length; i++)
  328.       {
  329.         SavePublishData_Internal(publishBranch, siteArray[i], i);
  330.         if (!defaultFound)
  331.           defaultFound = defaultName == siteArray[i].siteName;
  332.       }
  333.       // Assure that we have a default name
  334.       if (siteArray.length && !defaultFound)
  335.         defaultName = siteArray[0].siteName;
  336.     }
  337.  
  338.     // Save default site name
  339.     SetPublishStringPref(publishBranch, "default_site", defaultName);
  340.   
  341.     // Force saving to file so next page edited finds these values
  342.     SavePrefFile();
  343.   }
  344.   catch (ex) { return false; }
  345.  
  346.   return true;
  347. }
  348.  
  349. // Update prefs if publish site already exists
  350. //  or add prefs for a new site
  351. function SavePublishDataToPrefs(publishData)
  352. {
  353.   if (!publishData || !publishData.publishUrl)
  354.     return false;
  355.  
  356.   var publishBranch = GetPublishPrefsBranch();
  357.   if (!publishBranch)
  358.     return false;
  359.  
  360.   // Create name from URL if no site name is provided
  361.   if (!publishData.siteName)
  362.     publishData.siteName = CreateSiteNameFromUrl(publishData.publishUrl, publishData);
  363.  
  364.   var siteCount = {value:0};
  365.   var siteNamePrefs;
  366.   try {
  367.     siteNamePrefs = publishBranch.getChildList("site_name.", siteCount);
  368.   } catch (e) {}
  369.  
  370.   if (!siteNamePrefs || siteCount.value == 0)
  371.   {
  372.     // We currently have no site prefs, so create them
  373.     var siteData = [publishData];
  374.     return SavePublishSiteDataToPrefs(siteData, publishData.siteName);
  375.   }
  376.  
  377.   // Use "previous" name if available in case it was changed
  378.   var previousSiteName =  ("previousSiteName" in publishData && publishData.previousSiteName) ? 
  379.                             publishData.previousSiteName : publishData.siteName;
  380.  
  381.   // Find site number of existing site or fall through at next available one
  382.   // (Number is arbitrary; needed to construct unique "site_name.x" pref string)
  383.   for (var i = 0; i < siteCount.value; i++)
  384.   {
  385.     var siteName = GetPublishStringPref(publishBranch, "site_name."+i);
  386.  
  387.     if (siteName == previousSiteName)
  388.     {
  389.       // Delete prefs for an existing site
  390.       try {
  391.         publishBranch.deleteBranch("site_data." + siteName + ".");
  392.       } catch (e) {}
  393.       break;
  394.     }
  395.   }
  396.  
  397.   // We've taken care of finding old duplicate, so be sure 'previous name' is current
  398.   publishData.previousSiteName = publishData.siteName;
  399.  
  400.   var ret = SavePublishData_Internal(publishBranch, publishData, i);
  401.   if (ret)
  402.   {
  403.     // Check if siteName was the default and we need to update that
  404.     var defaultSiteName = GetPublishStringPref(publishBranch, "default_site");
  405.     if (previousSiteName == defaultSiteName 
  406.         && publishData.siteName != defaultSiteName)
  407.       SetPublishStringPref(publishBranch, "default_site", publishData.siteName);
  408.  
  409.     SavePrefFile();
  410.  
  411.     // Clear signal to save these data
  412.     if ("notInSiteData" in publishData && publishData.notInSiteData)
  413.       publishData.notInSiteData = false;
  414.   }
  415.   return ret;
  416. }
  417.  
  418. // Save data at a particular site number
  419. function SavePublishData_Internal(publishPrefsBranch, publishData, siteIndex)
  420. {
  421.   if (!publishPrefsBranch || !publishData)
  422.     return false;
  423.  
  424.   SetPublishStringPref(publishPrefsBranch, "site_name."+siteIndex, publishData.siteName);
  425.  
  426.   FixupUsernamePasswordInPublishData(publishData);
  427.  
  428.   var prefPrefix = "site_data." + publishData.siteName + "."
  429.  
  430.   SetPublishStringPref(publishPrefsBranch, prefPrefix+"url", publishData.publishUrl);
  431.   SetPublishStringPref(publishPrefsBranch, prefPrefix+"browse_url", publishData.browseUrl);
  432.   SetPublishStringPref(publishPrefsBranch, prefPrefix+"username", publishData.username);
  433.   
  434.   try {
  435.     publishPrefsBranch.setBoolPref(prefPrefix+"save_password", publishData.savePassword);
  436.     publishPrefsBranch.setBoolPref(prefPrefix+"publish_other_files", publishData.publishOtherFiles);
  437.   } catch (e) {}
  438.  
  439.   // Save password using PasswordManager 
  440.   // (If publishData.savePassword = false, this clears existing password)
  441.   SavePassword(publishData);
  442.  
  443.   SetPublishStringPref(publishPrefsBranch, prefPrefix+"doc_dir", 
  444.                        FormatDirForPublishing(publishData.docDir));
  445.  
  446.   if (publishData.publishOtherFiles && publishData.otherDir)
  447.     SetPublishStringPref(publishPrefsBranch, prefPrefix+"other_dir",
  448.                          FormatDirForPublishing(publishData.otherDir));
  449.  
  450.   if ("saveDirs" in publishData && publishData.saveDirs)
  451.   {
  452.     if (publishData.docDir)
  453.       AppendNewDirToList(publishData, publishData.docDir);
  454.  
  455.     if (publishData.publishOtherFiles && publishData.otherDir 
  456.         && publishData.otherDir != publishData.docDir)
  457.       AppendNewDirToList(publishData, publishData.otherDir);
  458.   }
  459.  
  460.   // Save array of subdirectories with site
  461.   if (publishData.dirList.length)
  462.   {
  463.     publishData.dirList.sort();
  464.     var dirIndex = 0;
  465.     for (var j = 0; j < publishData.dirList.length; j++)
  466.     {
  467.       var dir = publishData.dirList[j];
  468.  
  469.       // Don't store the root dir
  470.       if (dir && dir != "/")
  471.       {
  472.         SetPublishStringPref(publishPrefsBranch, prefPrefix + "dir." + dirIndex, dir);
  473.         dirIndex++;
  474.       }
  475.     }
  476.   }
  477.  
  478.   return true;
  479. }
  480.  
  481. function AppendNewDirToList(publishData, newDir)
  482. {
  483.   newDir = FormatDirForPublishing(newDir);
  484.   if (!publishData || !newDir)
  485.     return;
  486.  
  487.   if (!publishData.dirList)
  488.   {
  489.     publishData.dirList = [newDir];
  490.     return;
  491.   }
  492.  
  493.   // Check if already in the list
  494.   for (var i = 0; i < publishData.dirList.length; i++)
  495.   {
  496.     // Don't add if already in the list
  497.     if (newDir == publishData.dirList[i])
  498.       return;
  499.   }
  500.   // Add to end of list
  501.   publishData.dirList[publishData.dirList.length] = newDir;
  502. }
  503.  
  504. function RemovePublishSubdirectoryFromPrefs(publishData, removeDir)
  505. {
  506.   removeDir = FormatDirForPublishing(removeDir);
  507.   if (!publishData || !publishData.siteName || !removeDir)
  508.     return false;
  509.  
  510.   var publishBranch = GetPublishPrefsBranch();
  511.   if (!publishBranch)
  512.     return false;
  513.  
  514.   var prefPrefix = "site_data." + publishData.siteName + ".";
  515.  
  516.   // Remove dir from the default dir prefs
  517.   if (publishData.docDir == removeDir)
  518.   {
  519.     publishData.docDir = "";
  520.     SetPublishStringPref(publishBranch, prefPrefix+"doc_dir", "");
  521.   }
  522.  
  523.   if (publishData.otherDir == removeDir)
  524.   {
  525.     publishData.otherDir = "";
  526.     SetPublishStringPref(publishBranch, prefPrefix+"other_dir", "");
  527.   }
  528.  
  529.   prefPrefix += "dir.";
  530.  
  531.   // Delete entire subdir list
  532.   try {
  533.     publishBranch.deleteBranch(prefPrefix);
  534.   } catch (e) {}
  535.  
  536.   // Rebuild prefs, skipping over site to remove
  537.   if (publishData.dirList.length)
  538.   {
  539.     var dirIndex = 0;
  540.     var docDirInList = false;
  541.     var otherDirInList = false;
  542.     for (var i = 0; i < publishData.dirList.length; i++)
  543.     {
  544.       var dir = publishData.dirList[i];
  545.       if (dir == removeDir)
  546.       {
  547.         // Remove item from the dirList array
  548.         publishData.dirList.splice(i, 1);
  549.         --i;
  550.       }
  551.       else if (dir && dir != "/") // skip empty or root dir
  552.       {
  553.         // Save to prefs
  554.         SetPublishStringPref(publishBranch, prefPrefix + dirIndex, dir);
  555.         dirIndex++;
  556.       }
  557.     }
  558.   }
  559.   SavePrefFile();
  560.   return true;
  561. }
  562.  
  563. function SetDefaultSiteName(name)
  564. {
  565.   if (name)
  566.   {
  567.     var publishBranch = GetPublishPrefsBranch();
  568.     if (publishBranch)
  569.       SetPublishStringPref(publishBranch, "default_site", name);
  570.  
  571.     SavePrefFile();
  572.   }
  573. }
  574.  
  575. function SavePrefFile()
  576. {
  577.   try {
  578.     if (gPrefsService)
  579.       gPrefsService.savePrefFile(null);
  580.   }
  581.   catch (e) {}
  582. }
  583.  
  584. /***************** Helper / utility methods ********************/
  585.  
  586. function GetPublishPrefsBranch()
  587. {
  588.   var prefsService = GetPrefsService();
  589.   if (!prefsService)
  590.     return null;
  591.  
  592.   return prefsService.getBranch("editor.publish.");
  593. }
  594.  
  595. function GetSiteNameList(doSort, defaultFirst)
  596. {
  597.   var publishBranch = GetPublishPrefsBranch();
  598.   if (!publishBranch)
  599.     return null;
  600.  
  601.   var siteCountObj = {value:0};
  602.   var siteNamePrefs;
  603.   try {
  604.     siteNamePrefs = publishBranch.getChildList("site_name.", siteCountObj);
  605.   } catch (e) {}
  606.  
  607.   if (!siteNamePrefs || siteCountObj.value == 0)
  608.     return null;
  609.  
  610.   // Array of site names
  611.   var siteNameList = [];
  612.   var index = 0;
  613.   var defaultName = "";
  614.   if (defaultFirst)
  615.   {
  616.     defaultName = GetPublishStringPref(publishBranch, "default_site");
  617.     // This always sorts to top -- replace with real string below
  618.     siteNameList[0] = "";
  619.     index++;
  620.   }
  621.  
  622.   for (var i = 0; i < siteCountObj.value; i++)
  623.   {
  624.     var siteName = GetPublishStringPref(publishBranch, siteNamePrefs[i]);
  625.     // Skip if siteName pref is empty or is default name
  626.     if (siteName && siteName != defaultName)
  627.     {
  628.       siteNameList[index] = siteName;
  629.       index++;
  630.     }
  631.   }
  632.  
  633.   if (siteNameList.length && doSort)
  634.     siteNameList.sort();
  635.  
  636.   if (defaultName)
  637.   {
  638.     siteNameList[0] = defaultName;
  639.     index++;
  640.   }
  641.  
  642.   return siteNameList.length? siteNameList : null;
  643. }
  644.  
  645. function PublishSiteNameExists(name, publishSiteData, skipSiteIndex)
  646. {
  647.   if (!name)
  648.     return false;
  649.  
  650.   if (!publishSiteData)
  651.   {
  652.     publishSiteData = GetPublishSiteData();
  653.     skipSiteIndex = -1;
  654.   }
  655.  
  656.   if (!publishSiteData)
  657.     return false;
  658.  
  659.   // Array of site names - sorted, but don't put default name first
  660.   for (var i = 0; i < publishSiteData.length; i++)
  661.   {
  662.     if (i != skipSiteIndex && name == publishSiteData[i].siteName)
  663.       return true;
  664.   }
  665.   return false;
  666. }
  667.  
  668. // Find index of a site record in supplied publish site database
  669. // docUrl: Document URL with or without filename
  670. //         (Must end in "/" if no filename)
  671. // dirObj.value =  the directory of the document URL 
  672. //      relative to the base publishing URL, using "" if none
  673. //
  674. // XXX: Currently finds the site with the longest-matching url;
  675. //      should we look for the shortest instead? Or match just the host portion?
  676. function FindSiteIndexAndDocDir(publishSiteData, docUrl, dirObj)
  677. {
  678.   if (dirObj)
  679.     dirObj.value = "";
  680.  
  681.   if (!publishSiteData || !docUrl || GetScheme(docUrl) == "file")
  682.     return -1;
  683.  
  684.   var siteIndex = -1;
  685.   var siteUrlLen = 0;
  686.   
  687.   for (var i = 0; i < publishSiteData.length; i++)
  688.   {
  689.     // Site publish or browse url needs to be contained in document URL,
  690.     //  but that may also have a directory after the site base URL
  691.     //  So we must examine all records to find the site URL that best
  692.     //    matches the document URL: the longest-matching substring (XXX is this right?)
  693.     var lenObj = {value:0};
  694.     var tempData = Clone(publishSiteData[i]);
  695.  
  696.     // Check if this site matches docUrl (returns length of match if found)
  697.     var len = FillInMatchingPublishData(tempData, docUrl);
  698.  
  699.     if (len > siteUrlLen)
  700.     {
  701.       siteIndex = i;
  702.       siteUrlLen = len;
  703.       if (dirObj)
  704.         dirObj.value = tempData.docDir;
  705.  
  706.       // Continue to find the site with longest-matching publishUrl
  707.     }
  708.   }
  709.   return siteIndex;
  710. }
  711.  
  712. // Look for a matching publish url within the document url
  713. // (We need to look at both "publishUrl" and "browseUrl" in case we are editing
  714. //  an http: document but using ftp: to publish.)
  715. // If match is found:
  716. //    Fill in the filename and subirectory based on the docUrl and 
  717. //    return the length of the docUrl with username+password stripped out
  718. function FillInMatchingPublishData(publishData, docUrl)
  719. {
  720.   if (!publishData || !docUrl)
  721.     return 0;
  722.  
  723.   // Separate docUrl into the base url and filename
  724.   var lastSlash = docUrl.lastIndexOf("\/");
  725.   var baseUrl = docUrl.slice(0, lastSlash+1);
  726.   var filename = docUrl.slice(lastSlash+1);
  727.     
  728.   // Strip username+password from docUrl because these
  729.   //  are stored separately in publishData, never embedded in the publishUrl
  730.   // If both docUrl and publishData contain usernames,
  731.   //   we must match that as well as the url
  732.   var username = {value:""};
  733.   baseUrl = StripUsernamePassword(baseUrl, username); 
  734.   username = username.value;
  735.  
  736.   var matchedLength = 0;
  737.   var pubUrlFound = publishData.publishUrl ?
  738.                       baseUrl.indexOf(publishData.publishUrl) == 0 : false;
  739.   var browseUrlFound = publishData.browseUrl ?
  740.                           baseUrl.indexOf(publishData.browseUrl) == 0 : false;
  741.  
  742.   if ((pubUrlFound || browseUrlFound) 
  743.       && (!username || !publishData.username || username == publishData.username))
  744.   {
  745.     // We found a match
  746.     matchedLength = pubUrlFound ? publishData.publishUrl.length 
  747.                             : publishData.browseUrl.length;
  748.  
  749.     if (matchedLength > 0)
  750.     {
  751.       publishData.filename = filename;
  752.  
  753.       // Subdirectory within the site is what's left in baseUrl after the matched portion
  754.       publishData.docDir = FormatDirForPublishing(baseUrl.slice(matchedLength));
  755.     }
  756.   }
  757.   return matchedLength;
  758. }
  759.  
  760. // Prefs that don't exist will through an exception,
  761. //  so just return an empty string
  762. function GetPublishStringPref(prefBranch, name)
  763. {
  764.   if (prefBranch && name)
  765.   {
  766.     try {
  767.       return prefBranch.getComplexValue(name, Components.interfaces.nsISupportsString).data;
  768.     } catch (e) {}
  769.   }
  770.   return "";
  771. }
  772.  
  773. function SetPublishStringPref(prefBranch, name, value)
  774. {
  775.   if (prefBranch && name)
  776.   {
  777.     try {
  778.         var str = Components.classes["@mozilla.org/supports-string;1"]
  779.                             .createInstance(Components.interfaces.nsISupportsString);
  780.         str.data = value;
  781.         prefBranch.setComplexValue(name, Components.interfaces.nsISupportsString, str);
  782.     } catch (e) {}
  783.   }
  784. }
  785.  
  786. // Assure that a publishing URL ends in "/", "=", "&" or "?"
  787. // Username and password should always be extracted as separate fields
  788. //  and are not allowed to remain embeded in publishing URL
  789. function FormatUrlForPublishing(url)
  790. {
  791.   url = TrimString(StripUsernamePassword(url));
  792.   if (url)
  793.   {
  794.     var lastChar = url.charAt(url.length-1);
  795.     if (lastChar != "/" && lastChar != "=" && lastChar != "&" && lastChar  != "?")
  796.       return (url + "/");
  797.   }
  798.   return url;
  799. }
  800.  
  801. // Username and password present in publish url are
  802. //  extracted into the separate "username" and "password" fields 
  803. //  of the publishData object
  804. // Returns true if we did change the publishData
  805. function FixupUsernamePasswordInPublishData(publishData)
  806. {
  807.   var ret = false;
  808.   if (publishData && publishData.publishUrl)
  809.   {
  810.     var userObj = {value:""};
  811.     var passObj = {value:""};
  812.     publishData.publishUrl = FormatUrlForPublishing(StripUsernamePassword(publishData.publishUrl, userObj, passObj));
  813.     if (userObj.value)
  814.     {
  815.       publishData.username = userObj.value;
  816.       ret = true;
  817.     }
  818.     if (passObj.value)
  819.     {
  820.       publishData.password = passObj.value;
  821.       ret = true;
  822.     }
  823.     // While we're at it, be sure browse URL is proper format
  824.     publishData.browseUrl = FormatUrlForPublishing(publishData.browseUrl);
  825.   }
  826.   return ret;
  827. }
  828.  
  829. // Assure that a publishing directory ends with "/" and does not begin with "/"
  830. // Input dir is assumed to be a subdirectory string, not a full URL or pathname
  831. function FormatDirForPublishing(dir)
  832. {
  833.   dir = TrimString(dir);
  834.  
  835.   // The "//" case is an expected "typo" filter
  836.   //  that simplifies code below!
  837.   if (!dir || dir == "/" || dir == "//")
  838.     return "";
  839.  
  840.   // Remove leading "/"
  841.   if (dir.charAt(0) == "/")
  842.     dir = dir.slice(1);
  843.  
  844.   // Append "/" at the end if necessary
  845.   var dirLen = dir.length;
  846.   var lastChar = dir.charAt(dirLen-1);
  847.   if (dirLen > 1 && lastChar != "/" && lastChar != "=" && lastChar != "&" && lastChar  != "?")
  848.     return (dir + "/");
  849.  
  850.   return dir;
  851. }
  852.  
  853.  
  854. var gPasswordManager;
  855. function GetPasswordManager()
  856. {
  857.   if (!gPasswordManager)
  858.   {
  859.     var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"].createInstance();
  860.     if (passwordManager)
  861.       gPasswordManager = passwordManager.QueryInterface(Components.interfaces.nsIPasswordManager);
  862.   }
  863.   return gPasswordManager;
  864. }
  865.  
  866. var gPasswordManagerInternal;
  867. function GetPasswordManagerInternal()
  868. {
  869.   if (!gPasswordManagerInternal)
  870.   {
  871.     try {
  872.       gPasswordManagerInternal =
  873.         Components.classes["@mozilla.org/passwordmanager;1"].createInstance(
  874.           Components.interfaces.nsIPasswordManagerInternal);
  875.     } catch (e) {
  876.     }
  877.   }
  878.   return gPasswordManagerInternal;
  879. }
  880.  
  881. function GetSavedPassword(publishData)
  882. {
  883.   if (!publishData)
  884.     return "";
  885.   var passwordManagerInternal = GetPasswordManagerInternal();
  886.   if (!passwordManagerInternal)
  887.     return "";
  888.  
  889.   var host = {value:""};
  890.   var user =  {value:""};
  891.   var password = {value:""}; 
  892.   var url = GetUrlForPasswordManager(publishData);
  893.   
  894.   try {
  895.     passwordManagerInternal.findPasswordEntry
  896.       (url, publishData.username, "", host, user, password);
  897.     return password.value;
  898.   } catch (e) {}
  899.  
  900.   return "";
  901. }
  902.  
  903. function SavePassword(publishData)
  904. {
  905.   if (!publishData || !publishData.publishUrl || !publishData.username)
  906.     return false;
  907.  
  908.   var passwordManager = GetPasswordManager();
  909.   if (passwordManager)
  910.   {
  911.     var url = GetUrlForPasswordManager(publishData);
  912.  
  913.     // Remove existing entry
  914.     // (Note: there is no method to update a password for an existing entry)
  915.     try {
  916.       passwordManager.removeUser(url, publishData.username);
  917.     } catch (e) {}
  918.  
  919.     // If SavePassword is true, add new password
  920.     if (publishData.savePassword)
  921.     {
  922.       try {
  923.         passwordManager.addUser(url, publishData.username, publishData.password);
  924.       } catch (e) {}
  925.     }
  926.     return true;
  927.   }
  928.   return false;
  929. }
  930.  
  931. function GetUrlForPasswordManager(publishData)
  932. {
  933.   if (!publishData || !publishData.publishUrl)
  934.     return false;
  935.  
  936.   var url;
  937.  
  938.   // For FTP, we must embed the username into the url for a site address
  939.   // XXX Maybe we should we do this for HTTP as well???
  940.   if (publishData.username && GetScheme(publishData.publishUrl) == "ftp")
  941.     url = InsertUsernameIntoUrl(publishData.publishUrl, publishData.username);
  942.   else
  943.     url = publishData.publishUrl;
  944.  
  945.   // Strip off terminal "/"
  946.   var len = url.length;
  947.   if (len && url.charAt(len-1) == "\/")
  948.     url = url.slice(0, len-1);
  949.   
  950.   return url;
  951. }
  952.