summaryrefslogtreecommitdiffstats
path: root/comm/suite/editor/base/content/publishprefs.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/suite/editor/base/content/publishprefs.js')
-rw-r--r--comm/suite/editor/base/content/publishprefs.js867
1 files changed, 867 insertions, 0 deletions
diff --git a/comm/suite/editor/base/content/publishprefs.js b/comm/suite/editor/base/content/publishprefs.js
new file mode 100644
index 0000000000..4de3b4f282
--- /dev/null
+++ b/comm/suite/editor/base/content/publishprefs.js
@@ -0,0 +1,867 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/****************** Get publishing data methods *******************/
+
+// Build an array of all publish site data obtained from prefs
+function GetPublishSiteData()
+{
+ var publishBranch = GetPublishPrefsBranch();
+ if (!publishBranch)
+ return null;
+
+ // Array of site names - sorted, but don't put default name first
+ var siteNameList = GetSiteNameList(true, false);
+ if (!siteNameList)
+ return null;
+
+ // Array of all site data
+ var siteArray = [];
+
+ // We rewrite siteName prefs to eliminate names if data is bad
+ // and to be sure order is the same as sorted name list
+ try {
+ publishBranch.deleteBranch("site_name.");
+ } catch (e) {}
+
+ // Get publish data using siteName as the key
+ var index = 0;
+ for (var i = 0; i < siteNameList.length; i++)
+ {
+ // Associated data uses site name as key
+ var publishData = GetPublishData_internal(publishBranch, siteNameList[i]);
+ if (publishData)
+ {
+ siteArray[index] = publishData;
+ SetPublishStringPref(publishBranch, "site_name."+index, siteNameList[i]);
+ index++;
+ }
+ else
+ {
+ try {
+ // Remove bad site prefs now
+ publishBranch.deleteBranch("site_data." + siteNameList[i] + ".");
+ } catch (e) {}
+ }
+ }
+
+ SavePrefFile();
+
+ if (index == 0) // No Valid pref records found!
+ return null;
+
+
+ return siteArray;
+}
+
+function GetDefaultPublishSiteName()
+{
+ var publishBranch = GetPublishPrefsBranch();
+ var name = "";
+ if (publishBranch)
+ name = GetPublishStringPref(publishBranch, "default_site");
+
+ return name;
+}
+
+// Return object with all info needed to publish
+// from database of sites previously published to.
+function CreatePublishDataFromUrl(docUrl)
+{
+ if (!docUrl || IsUrlAboutBlank(docUrl) || GetScheme(docUrl) == "file")
+ return null;
+
+ var pubSiteData = GetPublishSiteData();
+ if (pubSiteData)
+ {
+ var dirObj = {};
+ var index = FindSiteIndexAndDocDir(pubSiteData, docUrl, dirObj);
+ var publishData;
+ if (index != -1)
+ {
+ publishData = pubSiteData[index];
+ publishData.docDir = FormatDirForPublishing(dirObj.value)
+
+ //XXX Problem: OtherDir: How do we decide when to use the dir in
+ // publishSiteData (default DocDir) or docDir from current filepath?
+ publishData.otherDir = FormatDirForPublishing(pubSiteData[index].otherDir);
+
+ publishData.filename = GetFilename(docUrl);
+ publishData.notInSiteData = false;
+ return publishData;
+ }
+ }
+
+ // Document wasn't found in publish site database
+ // Create data just from URL
+
+ // Extract username and password from docUrl
+ var userObj = {};
+ var passObj = {};
+ var pubUrl = StripUsernamePassword(docUrl, userObj, passObj);
+
+ // Strip off filename
+ var lastSlash = pubUrl.lastIndexOf("\/");
+ //XXX Look for "?", "=", and "&" ?
+ pubUrl = pubUrl.slice(0, lastSlash+1);
+
+ var siteName = CreateSiteNameFromUrl(pubUrl, pubSiteData);
+
+ publishData = {
+ siteName : siteName,
+ previousSiteName : siteName,
+ filename : GetFilename(docUrl),
+ username : userObj.value,
+ password : passObj.value,
+ savePassword : false,
+ publishUrl : pubUrl,
+ browseUrl : pubUrl,
+ docDir : "",
+ otherDir : "",
+ publishOtherFiles : true,
+ dirList : [""],
+ saveDirs : false,
+ notInSiteData : true
+ }
+
+ return publishData;
+}
+
+function CreateSiteNameFromUrl(url, publishSiteData)
+{
+ var host = GetHost(url);
+ var schemePostfix = " (" + GetScheme(url) + ")";
+ var siteName = host + schemePostfix;
+
+ if (publishSiteData)
+ {
+ // Look for duplicates. Append "-1" etc until unique name found
+ var i = 1;
+ var exists = false;
+ do {
+ exists = PublishSiteNameExists(siteName, publishSiteData, -1)
+ if (exists)
+ siteName = host + "-" + i + schemePostfix;
+ i++;
+ }
+ while (exists);
+ }
+ return siteName;
+}
+
+// Similar to above, but in param is a site profile name
+// Note that this is more efficient than getting from a URL,
+// since we don't have to get all the sitedata but can key off of sitename.
+// Caller must supply the current docUrl or just a filename
+// If doc URL is supplied, we find the publish subdirectory if publishUrl is part of docUrl
+function GetPublishDataFromSiteName(siteName, docUrlOrFilename)
+{
+ var publishBranch = GetPublishPrefsBranch();
+ if (!publishBranch)
+ return null;
+
+ var siteNameList = GetSiteNameList(false, false);
+ if (!siteNameList)
+ return null;
+ for (var i = 0; i < siteNameList.length; i++)
+ {
+ if (siteNameList[i] == siteName)
+ {
+ var publishData = GetPublishData_internal(publishBranch, siteName);
+ if (GetScheme(docUrlOrFilename))
+ FillInMatchingPublishData(publishData, docUrlOrFilename);
+ else
+ publishData.filename = docUrlOrFilename;
+
+ return publishData;
+ }
+ }
+ return null;
+}
+
+function GetDefaultPublishData()
+{
+ var publishBranch = GetPublishPrefsBranch();
+ if (!publishBranch)
+ return null;
+
+ var siteName = GetPublishStringPref(publishBranch, "default_site");
+ if (!siteName)
+ return null;
+
+ return GetPublishData_internal(publishBranch, siteName);
+}
+
+function GetPublishData_internal(publishBranch, siteName)
+{
+ if (!publishBranch || !siteName)
+ return null;
+
+ var prefPrefix = "site_data." + siteName + ".";
+
+ // We must have a publish url, else we ignore this site
+ // (siteData and siteNames for sites with incomplete data
+ // will get deleted by SavePublishSiteDataToPrefs)
+ var publishUrl = GetPublishStringPref(publishBranch, prefPrefix+"url");
+ if (!publishUrl)
+ return null;
+
+ var savePassword = false;
+ var publishOtherFiles = true;
+ try {
+ savePassword = publishBranch.getBoolPref(prefPrefix+"save_password");
+ publishOtherFiles = publishBranch.getBoolPref(prefPrefix+"publish_other_files");
+ } catch (e) {}
+
+ var publishData = {
+ siteName : siteName,
+ previousSiteName : siteName,
+ filename : "",
+ username : GetPublishStringPref(publishBranch, prefPrefix+"username"),
+ savePassword : savePassword,
+ publishUrl : publishUrl,
+ browseUrl : GetPublishStringPref(publishBranch, prefPrefix+"browse_url"),
+ docDir : FormatDirForPublishing(GetPublishStringPref(publishBranch, prefPrefix+"doc_dir")),
+ otherDir : FormatDirForPublishing(GetPublishStringPref(publishBranch, prefPrefix+"other_dir")),
+ publishOtherFiles : publishOtherFiles,
+ saveDirs : false
+ }
+
+ // Get password from PasswordManager
+ publishData.password = GetSavedPassword(publishData);
+
+ // If password was found, user must have checked "Save password"
+ // checkbox in prompt outside of publishing, so override the pref we stored
+ if (publishData.password)
+ {
+ if (!savePassword)
+ {
+ try {
+ publishPrefsBranch.setBoolPref(prefPrefix+"save_password", true);
+ } catch (e) {}
+ }
+ publishData.savePassword = true;
+ }
+
+ // Build history list of directories
+ // Always supply the root dir
+ publishData.dirList = [""];
+
+ // Get the rest from prefs
+ var dirPrefs;
+ try {
+ dirPrefs = publishBranch.getChildList(prefPrefix+"dir.");
+ } catch (e) {}
+
+ if (dirPrefs && dirPrefs.length > 0)
+ {
+ if (dirPrefs.length > 1)
+ dirPrefs.sort();
+
+ for (var j = 0; j < dirPrefs.length; j++)
+ {
+ var dirName = GetPublishStringPref(publishBranch, dirPrefs[j]);
+ if (dirName)
+ publishData.dirList[j+1] = dirName;
+ }
+ }
+
+ return publishData;
+}
+
+/****************** Save publishing data methods *********************/
+
+// Save the siteArray containing all current publish site data
+function SavePublishSiteDataToPrefs(siteArray, defaultName)
+{
+ var publishBranch = GetPublishPrefsBranch();
+ if (!publishBranch)
+ return false;
+
+ try {
+ if (siteArray)
+ {
+ var defaultFound = false;
+
+ // Clear existing names and data -- rebuild all site prefs
+ publishBranch.deleteBranch("site_name.");
+ publishBranch.deleteBranch("site_data.");
+
+ for (var i = 0; i < siteArray.length; i++)
+ {
+ SavePublishData_Internal(publishBranch, siteArray[i], i);
+ if (!defaultFound)
+ defaultFound = defaultName == siteArray[i].siteName;
+ }
+ // Assure that we have a default name
+ if (siteArray.length && !defaultFound)
+ defaultName = siteArray[0].siteName;
+ }
+
+ // Save default site name
+ SetPublishStringPref(publishBranch, "default_site", defaultName);
+
+ // Force saving to file so next page edited finds these values
+ SavePrefFile();
+ }
+ catch (ex) { return false; }
+
+ return true;
+}
+
+// Update prefs if publish site already exists
+// or add prefs for a new site
+function SavePublishDataToPrefs(publishData)
+{
+ if (!publishData || !publishData.publishUrl)
+ return false;
+
+ var publishBranch = GetPublishPrefsBranch();
+ if (!publishBranch)
+ return false;
+
+ // Create name from URL if no site name is provided
+ if (!publishData.siteName)
+ publishData.siteName = CreateSiteNameFromUrl(publishData.publishUrl, publishData);
+
+ var siteNamePrefs;
+ try {
+ siteNamePrefs = publishBranch.getChildList("site_name.");
+ } catch (e) {}
+
+ if (!siteNamePrefs || siteNamePrefs.length == 0)
+ {
+ // We currently have no site prefs, so create them
+ var siteData = [publishData];
+ return SavePublishSiteDataToPrefs(siteData, publishData.siteName);
+ }
+
+ // Use "previous" name if available in case it was changed
+ var previousSiteName = ("previousSiteName" in publishData && publishData.previousSiteName) ?
+ publishData.previousSiteName : publishData.siteName;
+
+ // Find site number of existing site or fall through at next available one
+ // (Number is arbitrary; needed to construct unique "site_name.x" pref string)
+ for (var i = 0; i < siteNamePrefs.length; i++)
+ {
+ var siteName = GetPublishStringPref(publishBranch, "site_name."+i);
+
+ if (siteName == previousSiteName)
+ {
+ // Delete prefs for an existing site
+ try {
+ publishBranch.deleteBranch("site_data." + siteName + ".");
+ } catch (e) {}
+ break;
+ }
+ }
+
+ // We've taken care of finding old duplicate, so be sure 'previous name' is current
+ publishData.previousSiteName = publishData.siteName;
+
+ var ret = SavePublishData_Internal(publishBranch, publishData, i);
+ if (ret)
+ {
+ // Check if siteName was the default and we need to update that
+ var defaultSiteName = GetPublishStringPref(publishBranch, "default_site");
+ if (previousSiteName == defaultSiteName
+ && publishData.siteName != defaultSiteName)
+ SetPublishStringPref(publishBranch, "default_site", publishData.siteName);
+
+ SavePrefFile();
+
+ // Clear signal to save these data
+ if ("notInSiteData" in publishData && publishData.notInSiteData)
+ publishData.notInSiteData = false;
+ }
+ return ret;
+}
+
+// Save data at a particular site number
+function SavePublishData_Internal(publishPrefsBranch, publishData, siteIndex)
+{
+ if (!publishPrefsBranch || !publishData)
+ return false;
+
+ SetPublishStringPref(publishPrefsBranch, "site_name."+siteIndex, publishData.siteName);
+
+ FixupUsernamePasswordInPublishData(publishData);
+
+ var prefPrefix = "site_data." + publishData.siteName + "."
+
+ SetPublishStringPref(publishPrefsBranch, prefPrefix+"url", publishData.publishUrl);
+ SetPublishStringPref(publishPrefsBranch, prefPrefix+"browse_url", publishData.browseUrl);
+ SetPublishStringPref(publishPrefsBranch, prefPrefix+"username", publishData.username);
+
+ try {
+ publishPrefsBranch.setBoolPref(prefPrefix+"save_password", publishData.savePassword);
+ publishPrefsBranch.setBoolPref(prefPrefix+"publish_other_files", publishData.publishOtherFiles);
+ } catch (e) {}
+
+ // Save password using PasswordManager
+ // (If publishData.savePassword = false, this clears existing password)
+ SavePassword(publishData);
+
+ SetPublishStringPref(publishPrefsBranch, prefPrefix+"doc_dir",
+ FormatDirForPublishing(publishData.docDir));
+
+ if (publishData.publishOtherFiles && publishData.otherDir)
+ SetPublishStringPref(publishPrefsBranch, prefPrefix+"other_dir",
+ FormatDirForPublishing(publishData.otherDir));
+
+ if ("saveDirs" in publishData && publishData.saveDirs)
+ {
+ if (publishData.docDir)
+ AppendNewDirToList(publishData, publishData.docDir);
+
+ if (publishData.publishOtherFiles && publishData.otherDir
+ && publishData.otherDir != publishData.docDir)
+ AppendNewDirToList(publishData, publishData.otherDir);
+ }
+
+ // Save array of subdirectories with site
+ if (publishData.dirList.length)
+ {
+ publishData.dirList.sort();
+ var dirIndex = 0;
+ for (var j = 0; j < publishData.dirList.length; j++)
+ {
+ var dir = publishData.dirList[j];
+
+ // Don't store the root dir
+ if (dir && dir != "/")
+ {
+ SetPublishStringPref(publishPrefsBranch, prefPrefix + "dir." + dirIndex, dir);
+ dirIndex++;
+ }
+ }
+ }
+
+ return true;
+}
+
+function AppendNewDirToList(publishData, newDir)
+{
+ newDir = FormatDirForPublishing(newDir);
+ if (!publishData || !newDir)
+ return;
+
+ if (!publishData.dirList)
+ {
+ publishData.dirList = [newDir];
+ return;
+ }
+
+ // Check if already in the list
+ for (var i = 0; i < publishData.dirList.length; i++)
+ {
+ // Don't add if already in the list
+ if (newDir == publishData.dirList[i])
+ return;
+ }
+ // Add to end of list
+ publishData.dirList[publishData.dirList.length] = newDir;
+}
+
+function RemovePublishSubdirectoryFromPrefs(publishData, removeDir)
+{
+ removeDir = FormatDirForPublishing(removeDir);
+ if (!publishData || !publishData.siteName || !removeDir)
+ return false;
+
+ var publishBranch = GetPublishPrefsBranch();
+ if (!publishBranch)
+ return false;
+
+ var prefPrefix = "site_data." + publishData.siteName + ".";
+
+ // Remove dir from the default dir prefs
+ if (publishData.docDir == removeDir)
+ {
+ publishData.docDir = "";
+ SetPublishStringPref(publishBranch, prefPrefix+"doc_dir", "");
+ }
+
+ if (publishData.otherDir == removeDir)
+ {
+ publishData.otherDir = "";
+ SetPublishStringPref(publishBranch, prefPrefix+"other_dir", "");
+ }
+
+ prefPrefix += "dir.";
+
+ // Delete entire subdir list
+ try {
+ publishBranch.deleteBranch(prefPrefix);
+ } catch (e) {}
+
+ // Rebuild prefs, skipping over site to remove
+ if (publishData.dirList.length)
+ {
+ var dirIndex = 0;
+ var docDirInList = false;
+ var otherDirInList = false;
+ for (var i = 0; i < publishData.dirList.length; i++)
+ {
+ var dir = publishData.dirList[i];
+ if (dir == removeDir)
+ {
+ // Remove item from the dirList array
+ publishData.dirList.splice(i, 1);
+ --i;
+ }
+ else if (dir && dir != "/") // skip empty or root dir
+ {
+ // Save to prefs
+ SetPublishStringPref(publishBranch, prefPrefix + dirIndex, dir);
+ dirIndex++;
+ }
+ }
+ }
+ SavePrefFile();
+ return true;
+}
+
+function SetDefaultSiteName(name)
+{
+ if (name)
+ {
+ var publishBranch = GetPublishPrefsBranch();
+ if (publishBranch)
+ SetPublishStringPref(publishBranch, "default_site", name);
+
+ SavePrefFile();
+ }
+}
+
+function SavePrefFile()
+{
+ try {
+ Services.prefs.savePrefFile(null);
+ }
+ catch (e) {}
+}
+
+/***************** Helper / utility methods ********************/
+
+function GetPublishPrefsBranch()
+{
+ return Services.prefs.getBranch("editor.publish.");
+}
+
+function GetSiteNameList(doSort, defaultFirst)
+{
+ var publishBranch = GetPublishPrefsBranch();
+ if (!publishBranch)
+ return null;
+
+ var siteNamePrefs;
+ try {
+ siteNamePrefs = publishBranch.getChildList("site_name.");
+ } catch (e) {}
+
+ if (!siteNamePrefs || siteNamePrefs.length == 0)
+ return null;
+
+ // Array of site names
+ var siteNameList = [];
+ var index = 0;
+ var defaultName = "";
+ if (defaultFirst)
+ {
+ defaultName = GetPublishStringPref(publishBranch, "default_site");
+ // This always sorts to top -- replace with real string below
+ siteNameList[0] = "";
+ index++;
+ }
+
+ for (var i = 0; i < siteNamePrefs.length; i++)
+ {
+ var siteName = GetPublishStringPref(publishBranch, siteNamePrefs[i]);
+ // Skip if siteName pref is empty or is default name
+ if (siteName && siteName != defaultName)
+ {
+ siteNameList[index] = siteName;
+ index++;
+ }
+ }
+
+ if (siteNameList.length && doSort)
+ siteNameList.sort();
+
+ if (defaultName)
+ {
+ siteNameList[0] = defaultName;
+ index++;
+ }
+
+ return siteNameList.length? siteNameList : null;
+}
+
+function PublishSiteNameExists(name, publishSiteData, skipSiteIndex)
+{
+ if (!name)
+ return false;
+
+ if (!publishSiteData)
+ {
+ publishSiteData = GetPublishSiteData();
+ skipSiteIndex = -1;
+ }
+
+ if (!publishSiteData)
+ return false;
+
+ // Array of site names - sorted, but don't put default name first
+ for (var i = 0; i < publishSiteData.length; i++)
+ {
+ if (i != skipSiteIndex && name == publishSiteData[i].siteName)
+ return true;
+ }
+ return false;
+}
+
+// Find index of a site record in supplied publish site database
+// docUrl: Document URL with or without filename
+// (Must end in "/" if no filename)
+// dirObj.value = the directory of the document URL
+// relative to the base publishing URL, using "" if none
+//
+// XXX: Currently finds the site with the longest-matching url;
+// should we look for the shortest instead? Or match just the host portion?
+function FindSiteIndexAndDocDir(publishSiteData, docUrl, dirObj)
+{
+ if (dirObj)
+ dirObj.value = "";
+
+ if (!publishSiteData || !docUrl || GetScheme(docUrl) == "file")
+ return -1;
+
+ var siteIndex = -1;
+ var siteUrlLen = 0;
+
+ for (var i = 0; i < publishSiteData.length; i++)
+ {
+ // Site publish or browse url needs to be contained in document URL,
+ // but that may also have a directory after the site base URL
+ // So we must examine all records to find the site URL that best
+ // matches the document URL: the longest-matching substring (XXX is this right?)
+ var lenObj = {value:0};
+ var tempData = Clone(publishSiteData[i]);
+
+ // Check if this site matches docUrl (returns length of match if found)
+ var len = FillInMatchingPublishData(tempData, docUrl);
+
+ if (len > siteUrlLen)
+ {
+ siteIndex = i;
+ siteUrlLen = len;
+ if (dirObj)
+ dirObj.value = tempData.docDir;
+
+ // Continue to find the site with longest-matching publishUrl
+ }
+ }
+ return siteIndex;
+}
+
+// Look for a matching publish url within the document url
+// (We need to look at both "publishUrl" and "browseUrl" in case we are editing
+// an http: document but using ftp: to publish.)
+// If match is found:
+// Fill in the filename and subdirectory based on the docUrl and
+// return the length of the docUrl with username+password stripped out
+function FillInMatchingPublishData(publishData, docUrl)
+{
+ if (!publishData || !docUrl)
+ return 0;
+
+ // Separate docUrl into the base url and filename
+ var lastSlash = docUrl.lastIndexOf("\/");
+ var baseUrl = docUrl.slice(0, lastSlash+1);
+ var filename = docUrl.slice(lastSlash+1);
+
+ // Strip username+password from docUrl because these
+ // are stored separately in publishData, never embedded in the publishUrl
+ // If both docUrl and publishData contain usernames,
+ // we must match that as well as the url
+ var username = {value:""};
+ baseUrl = StripUsernamePassword(baseUrl, username);
+ username = username.value;
+
+ var matchedLength = 0;
+ let pubUrlFound = publishData.publishUrl && baseUrl.startsWith(publishData.publishUrl);
+ let browseUrlFound = publishData.browseUrl && baseUrl.startsWith(publishData.browseUrl);
+
+ if ((pubUrlFound || browseUrlFound)
+ && (!username || !publishData.username || username == publishData.username))
+ {
+ // We found a match
+ matchedLength = pubUrlFound ? publishData.publishUrl.length
+ : publishData.browseUrl.length;
+
+ if (matchedLength > 0)
+ {
+ publishData.filename = filename;
+
+ // Subdirectory within the site is what's left in baseUrl after the matched portion
+ publishData.docDir = FormatDirForPublishing(baseUrl.slice(matchedLength));
+ }
+ }
+ return matchedLength;
+}
+
+// Prefs that don't exist will through an exception,
+// so just return an empty string
+function GetPublishStringPref(prefBranch, name)
+{
+ if (prefBranch && name)
+ {
+ try {
+ return prefBranch.getStringPref(name);
+ } catch (e) {}
+ }
+ return "";
+}
+
+function SetPublishStringPref(prefBranch, name, value)
+{
+ if (prefBranch && name)
+ {
+ try {
+ prefBranch.setStringPref(name, value);
+ } catch (e) {}
+ }
+}
+
+// Assure that a publishing URL ends in "/", "=", "&" or "?"
+// Username and password should always be extracted as separate fields
+// and are not allowed to remain embedded in publishing URL
+function FormatUrlForPublishing(url)
+{
+ url = TrimString(StripUsernamePassword(url));
+ if (url)
+ {
+ var lastChar = url.charAt(url.length-1);
+ if (lastChar != "/" && lastChar != "=" && lastChar != "&" && lastChar != "?")
+ return (url + "/");
+ }
+ return url;
+}
+
+// Username and password present in publish url are
+// extracted into the separate "username" and "password" fields
+// of the publishData object
+// Returns true if we did change the publishData
+function FixupUsernamePasswordInPublishData(publishData)
+{
+ var ret = false;
+ if (publishData && publishData.publishUrl)
+ {
+ var userObj = {value:""};
+ var passObj = {value:""};
+ publishData.publishUrl = FormatUrlForPublishing(StripUsernamePassword(publishData.publishUrl, userObj, passObj));
+ if (userObj.value)
+ {
+ publishData.username = userObj.value;
+ ret = true;
+ }
+ if (passObj.value)
+ {
+ publishData.password = passObj.value;
+ ret = true;
+ }
+ // While we're at it, be sure browse URL is proper format
+ publishData.browseUrl = FormatUrlForPublishing(publishData.browseUrl);
+ }
+ return ret;
+}
+
+// Assure that a publishing directory ends with "/" and does not begin with "/"
+// Input dir is assumed to be a subdirectory string, not a full URL or pathname
+function FormatDirForPublishing(dir)
+{
+ dir = TrimString(dir);
+
+ // The "//" case is an expected "typo" filter
+ // that simplifies code below!
+ if (!dir || dir == "/" || dir == "//")
+ return "";
+
+ // Remove leading "/"
+ if (dir.startsWith("/"))
+ dir = dir.slice(1);
+
+ // Append "/" at the end if necessary
+ var dirLen = dir.length;
+ var lastChar = dir.charAt(dirLen-1);
+ if (dirLen > 1 && ["/", "=", "&", "?"].indexOf(lastChar) == -1)
+ dir += "/";
+
+ return dir;
+}
+
+function GetSavedPassword(publishData)
+{
+ if (!publishData || !publishData.publishUrl)
+ return "";
+
+ let url = GetUrlForPasswordManager(publishData);
+ let logins = Services.logins.findLogins(url, null, url);
+
+ for (let i = 0; i < logins.length; i++) {
+ if (logins[i].username == publishData.username)
+ return logins[i].password;
+ }
+
+ return "";
+}
+
+function SavePassword(publishData)
+{
+ if (!publishData || !publishData.publishUrl || !publishData.username)
+ return false;
+
+ let url = GetUrlForPasswordManager(publishData);
+
+ // Remove existing entry by finding all logins that match.
+ let logins = Services.logins.findLogins(url, null, url);
+
+ for (let i = 0; i < logins.length; i++) {
+ if (logins[i].username == publishData.username) {
+ Services.logins.removeLogin(logins[i]);
+ break;
+ }
+ }
+
+ // If SavePassword is true, add new password.
+ if (publishData.savePassword)
+ {
+ let authInfo = Cc["@mozilla.org/login-manager/loginInfo;1"]
+ .createInstance(Ci.nsILoginInfo);
+ authInfo.init(url, null, url, publishData.username, publishData.password,
+ "", "");
+ Services.logins.addLogin(authInfo);
+ }
+
+ return true;
+}
+
+function GetUrlForPasswordManager(publishData)
+{
+ if (!publishData || !publishData.publishUrl)
+ return false;
+
+ let url = Services.io.newURI(publishData.publishUrl);
+
+ if (url.scheme == "ftp" && publishData.username)
+ // Include username in the URL so we can handle multiple users per server
+ // in the password manager
+ url = url.scheme + "://" + publishData.username + "@" + url.hostPort;
+ else
+ url = url.scheme + "://" + url.hostPort;
+
+ return url;
+}