2001-11-15 18:28:24 +03:00
|
|
|
/*
|
|
|
|
* The contents of this file are subject to the Netscape Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/NPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code is Mozilla Communicator client code, released
|
|
|
|
* March 31, 1998.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
* Pete Collins
|
|
|
|
* Brian King
|
2002-01-09 16:51:37 +03:00
|
|
|
* Daniel Glazman <glazman@netscape.com>
|
2001-11-15 18:28:24 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**** NAMESPACES ****/
|
|
|
|
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
|
|
|
|
|
|
// Each editor window must include this file
|
|
|
|
// Variables shared by all dialogs:
|
|
|
|
var editorShell;
|
|
|
|
|
|
|
|
// Object to attach commonly-used widgets (all dialogs should use this)
|
|
|
|
var gDialog = {};
|
|
|
|
|
|
|
|
// Bummer! Can't get at enums from nsIDocumentEncoder.h
|
2002-02-15 09:07:40 +03:00
|
|
|
// http://lxr.mozilla.org/seamonkey/source/content/base/public/nsIDocumentEncoder.h#111
|
2001-11-15 18:28:24 +03:00
|
|
|
var gStringBundle;
|
|
|
|
var gIOService;
|
|
|
|
var gPrefsService;
|
2002-01-26 03:55:27 +03:00
|
|
|
var gPrefsBranch;
|
2002-01-05 23:25:53 +03:00
|
|
|
var gFilePickerDirectory;
|
2001-11-15 18:28:24 +03:00
|
|
|
|
|
|
|
var gOS = "";
|
|
|
|
const gWin = "Win";
|
|
|
|
const gUNIX = "UNIX";
|
|
|
|
const gMac = "Mac";
|
|
|
|
|
|
|
|
/************* Message dialogs ***************/
|
|
|
|
|
|
|
|
function AlertWithTitle(title, message)
|
|
|
|
{
|
|
|
|
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
|
|
|
|
promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
|
|
|
|
|
|
|
|
if (promptService)
|
|
|
|
{
|
|
|
|
if (!title)
|
|
|
|
title = GetString("Alert");
|
|
|
|
|
|
|
|
// "window" is the calling dialog window
|
|
|
|
promptService.alert(window, title, message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Optional: Caller may supply text to substitue for "Ok" and/or "Cancel"
|
|
|
|
function ConfirmWithTitle(title, message, okButtonText, cancelButtonText)
|
|
|
|
{
|
|
|
|
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
|
|
|
|
promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
|
|
|
|
|
|
|
|
if (promptService)
|
|
|
|
{
|
|
|
|
var result = {value:0};
|
|
|
|
var okFlag = okButtonText ? promptService.BUTTON_TITLE_IS_STRING : promptService.BUTTON_TITLE_OK;
|
|
|
|
var cancelFlag = cancelButtonText ? promptService.BUTTON_TITLE_IS_STRING : promptService.BUTTON_TITLE_CANCEL;
|
|
|
|
|
|
|
|
promptService.confirmEx(window, title, message,
|
|
|
|
(okFlag * promptService.BUTTON_POS_0) +
|
|
|
|
(cancelFlag * promptService.BUTTON_POS_1),
|
|
|
|
okButtonText, cancelButtonText, null, null, {value:0}, result);
|
|
|
|
return (result.value == 0);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************* String Utilities ***************/
|
|
|
|
|
|
|
|
function GetString(name)
|
|
|
|
{
|
2002-03-27 00:19:28 +03:00
|
|
|
if (!gStringBundle)
|
2001-11-15 18:28:24 +03:00
|
|
|
{
|
2002-01-05 23:25:53 +03:00
|
|
|
try {
|
2002-03-27 00:19:28 +03:00
|
|
|
var strBundleService =
|
|
|
|
Components.classes["@mozilla.org/intl/stringbundle;1"].getService();
|
|
|
|
strBundleService =
|
|
|
|
strBundleService.QueryInterface(Components.interfaces.nsIStringBundleService);
|
|
|
|
|
|
|
|
gStringBundle = strBundleService.createBundle("chrome://editor/locale/editor.properties");
|
|
|
|
|
|
|
|
} catch (ex) {}
|
2001-11-15 18:28:24 +03:00
|
|
|
}
|
2002-03-27 00:19:28 +03:00
|
|
|
if (gStringBundle)
|
2001-11-15 18:28:24 +03:00
|
|
|
{
|
2002-01-05 23:25:53 +03:00
|
|
|
try {
|
|
|
|
return gStringBundle.GetStringFromName(name);
|
|
|
|
} catch (e) {}
|
2001-11-15 18:28:24 +03:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
function TrimStringLeft(string)
|
|
|
|
{
|
|
|
|
if(!string) return "";
|
|
|
|
return string.replace(/^\s+/, "");
|
|
|
|
}
|
|
|
|
|
|
|
|
function TrimStringRight(string)
|
|
|
|
{
|
|
|
|
if (!string) return "";
|
|
|
|
return string.replace(/\s+$/, '');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove whitespace from both ends of a string
|
|
|
|
function TrimString(string)
|
|
|
|
{
|
|
|
|
if (!string) return "";
|
|
|
|
return string.replace(/(^\s+)|(\s+$)/g, '')
|
|
|
|
}
|
|
|
|
|
|
|
|
function IsWhitespace(string)
|
|
|
|
{
|
|
|
|
return /^\s/.test(string);
|
|
|
|
}
|
|
|
|
|
|
|
|
function TruncateStringAtWordEnd(string, maxLength, addEllipses)
|
|
|
|
{
|
|
|
|
// Return empty if string is null, undefined, or the empty string
|
|
|
|
if (!string)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
// We assume they probably don't want whitespace at the beginning
|
|
|
|
string = string.replace(/^\s+/, '');
|
|
|
|
if (string.length <= maxLength)
|
|
|
|
return string;
|
|
|
|
|
|
|
|
// We need to truncate the string to maxLength or fewer chars
|
|
|
|
if (addEllipses)
|
|
|
|
maxLength -= 3;
|
|
|
|
string = string.replace(RegExp("(.{0," + maxLength + "})\\s.*"), "$1")
|
|
|
|
|
|
|
|
if (string.length > maxLength)
|
|
|
|
string = string.slice(0, maxLength);
|
|
|
|
|
|
|
|
if (addEllipses)
|
|
|
|
string += "...";
|
|
|
|
return string;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Replace all whitespace characters with supplied character
|
|
|
|
// E.g.: Use charReplace = " ", to "unwrap" the string by removing line-end chars
|
|
|
|
// Use charReplace = "_" when you don't want spaces (like in a URL)
|
|
|
|
function ReplaceWhitespace(string, charReplace)
|
|
|
|
{
|
|
|
|
return string.replace(/(^\s+)|(\s+$)/g,'').replace(/\s+/g,charReplace)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Replace whitespace with "_" and allow only HTML CDATA
|
|
|
|
// characters: "a"-"z","A"-"Z","0"-"9", "_", ":", "-", ".",
|
|
|
|
// and characters above ASCII 127
|
|
|
|
function ConvertToCDATAString(string)
|
|
|
|
{
|
|
|
|
return string.replace(/\s+/g,"_").replace(/[^a-zA-Z0-9_\.\-\:\u0080-\uFFFF]+/g,'');
|
|
|
|
}
|
|
|
|
|
|
|
|
function GetSelectionAsText()
|
|
|
|
{
|
2002-02-15 09:07:40 +03:00
|
|
|
return editorShell.GetContentsAs("text/plain", 1); // OutputSelectionOnly
|
2001-11-15 18:28:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************* Element enbabling/disabling ***************/
|
|
|
|
|
|
|
|
// this function takes an elementID and a flag
|
|
|
|
// if the element can be found by ID, then it is either enabled (by removing "disabled" attr)
|
|
|
|
// or disabled (setAttribute) as specified in the "doEnable" parameter
|
|
|
|
function SetElementEnabledById(elementID, doEnable)
|
|
|
|
{
|
|
|
|
SetElementEnabled(document.getElementById(elementID), doEnable);
|
|
|
|
}
|
|
|
|
|
|
|
|
function SetElementEnabled(element, doEnable)
|
|
|
|
{
|
|
|
|
if ( element )
|
|
|
|
{
|
|
|
|
if ( doEnable )
|
2001-12-12 06:57:32 +03:00
|
|
|
element.removeAttribute("disabled");
|
2001-11-15 18:28:24 +03:00
|
|
|
else
|
2001-12-12 06:57:32 +03:00
|
|
|
element.setAttribute("disabled", "true");
|
2001-11-15 18:28:24 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dump("Element not found in SetElementEnabled\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-20 05:17:46 +03:00
|
|
|
function SetElementHidden(element, hide)
|
|
|
|
{
|
|
|
|
if (element)
|
|
|
|
{
|
|
|
|
if (hide)
|
2002-03-08 03:37:47 +03:00
|
|
|
element.setAttribute("hidden", "true");
|
2002-02-20 05:17:46 +03:00
|
|
|
else
|
|
|
|
element.removeAttribute("hidden");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
function DisableItem(id, disable)
|
|
|
|
{
|
|
|
|
var item = document.getElementById(id);
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
if (disable != (item.getAttribute("disabled") == "true"))
|
|
|
|
item.setAttribute("disabled", disable ? "true" : "");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************* Services / Prefs ***************/
|
|
|
|
|
|
|
|
function GetIOService()
|
|
|
|
{
|
|
|
|
if (gIOService)
|
|
|
|
return gIOService;
|
|
|
|
|
2001-12-12 06:57:32 +03:00
|
|
|
gIOService = Components.classes["@mozilla.org/network/io-service;1"]
|
|
|
|
.getService(Components.interfaces.nsIIOService);
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
return gIOService;
|
|
|
|
}
|
|
|
|
|
|
|
|
function GetPrefsService()
|
|
|
|
{
|
|
|
|
if (gPrefsService)
|
|
|
|
return gPrefsService;
|
|
|
|
|
|
|
|
try {
|
|
|
|
gPrefsService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
|
|
|
|
}
|
2002-02-06 17:48:03 +03:00
|
|
|
catch(ex) {
|
2001-11-15 18:28:24 +03:00
|
|
|
dump("failed to get prefs service!\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return gPrefsService;
|
|
|
|
}
|
|
|
|
|
|
|
|
function GetPrefs()
|
|
|
|
{
|
2002-01-26 03:55:27 +03:00
|
|
|
if (gPrefsBranch)
|
|
|
|
return gPrefsBranch;
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
try {
|
|
|
|
var prefService = GetPrefsService();
|
2002-01-26 03:55:27 +03:00
|
|
|
if (prefService)
|
|
|
|
gPrefsBranch = prefService.getBranch(null);
|
|
|
|
|
|
|
|
if (gPrefsBranch)
|
|
|
|
return gPrefsBranch;
|
2001-11-15 18:28:24 +03:00
|
|
|
else
|
|
|
|
dump("failed to get root prefs!\n");
|
|
|
|
}
|
2002-02-06 17:48:03 +03:00
|
|
|
catch(ex) {
|
2001-11-15 18:28:24 +03:00
|
|
|
dump("failed to get root prefs!\n");
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2002-01-05 23:25:53 +03:00
|
|
|
function SetUnicharPref(aPrefName, aPrefValue)
|
|
|
|
{
|
|
|
|
var prefs = GetPrefs();
|
|
|
|
if (prefs)
|
|
|
|
{
|
2002-02-06 17:48:03 +03:00
|
|
|
try {
|
2002-01-05 23:25:53 +03:00
|
|
|
var str = Components.classes["@mozilla.org/supports-wstring;1"]
|
|
|
|
.createInstance(Components.interfaces.nsISupportsWString);
|
|
|
|
str.data = aPrefValue;
|
|
|
|
prefs.setComplexValue(aPrefName, Components.interfaces.nsISupportsWString, str);
|
|
|
|
}
|
|
|
|
catch(e) {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-06 17:48:03 +03:00
|
|
|
function GetUnicharPref(aPrefName, aDefVal)
|
2002-01-05 23:25:53 +03:00
|
|
|
{
|
|
|
|
var prefs = GetPrefs();
|
|
|
|
if (prefs)
|
|
|
|
{
|
2002-02-06 17:48:03 +03:00
|
|
|
try {
|
2002-01-05 23:25:53 +03:00
|
|
|
return prefs.getComplexValue(aPrefName, Components.interfaces.nsISupportsWString).data;
|
|
|
|
}
|
|
|
|
catch(e) {}
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set initial directory for a filepicker from URLs saved in prefs
|
|
|
|
function SetFilePickerDirectory(filePicker, fileType)
|
|
|
|
{
|
|
|
|
if (filePicker)
|
|
|
|
{
|
2002-01-26 03:55:27 +03:00
|
|
|
try {
|
|
|
|
var prefBranch = GetPrefs();
|
|
|
|
if (prefBranch)
|
|
|
|
{
|
2002-01-05 23:25:53 +03:00
|
|
|
// Save current directory so we can reset it in SaveFilePickerDirectory
|
|
|
|
gFilePickerDirectory = filePicker.displayDirectory;
|
|
|
|
|
2002-01-26 03:55:27 +03:00
|
|
|
var location = prefBranch.getComplexValue("editor.lastFileLocation."+fileType, Components.interfaces.nsILocalFile);
|
|
|
|
if (location)
|
|
|
|
filePicker.displayDirectory = location;
|
2002-01-05 23:25:53 +03:00
|
|
|
}
|
|
|
|
}
|
2002-01-26 03:55:27 +03:00
|
|
|
catch(e) {}
|
2002-01-05 23:25:53 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save the directory of the selected file to prefs
|
|
|
|
function SaveFilePickerDirectory(filePicker, fileType)
|
|
|
|
{
|
2002-01-26 03:55:27 +03:00
|
|
|
if (filePicker && filePicker.file)
|
2002-01-05 23:25:53 +03:00
|
|
|
{
|
2002-01-26 03:55:27 +03:00
|
|
|
try {
|
|
|
|
var prefBranch = GetPrefs();
|
|
|
|
|
|
|
|
var fileDir;
|
|
|
|
if (filePicker.file.parent)
|
|
|
|
fileDir = filePicker.file.parent.QueryInterface(Components.interfaces.nsILocalFile);
|
|
|
|
|
|
|
|
if (prefBranch)
|
|
|
|
prefBranch.setComplexValue("editor.lastFileLocation."+fileType, Components.interfaces.nsILocalFile, fileDir);
|
|
|
|
|
|
|
|
var prefsService = GetPrefsService();
|
|
|
|
prefsService.savePrefFile(null);
|
|
|
|
} catch (e) {}
|
2002-01-05 23:25:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// Restore the directory used before SetFilePickerDirectory was called;
|
|
|
|
// This reduces interference with Browser and other module directory defaults
|
|
|
|
if (gFilePickerDirectory)
|
|
|
|
filePicker.displayDirectory = gFilePickerDirectory;
|
|
|
|
|
2002-01-26 03:55:27 +03:00
|
|
|
gFilePickerDirectory = null;
|
2002-01-05 23:25:53 +03:00
|
|
|
}
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
function GetDefaultBrowserColors()
|
|
|
|
{
|
|
|
|
var prefs = GetPrefs();
|
|
|
|
var colors = new Object();
|
|
|
|
var useSysColors = false;
|
|
|
|
colors.TextColor = 0;
|
|
|
|
colors.BackgroundColor = 0;
|
|
|
|
try { useSysColors = prefs.getBoolPref("browser.display.use_system_colors"); } catch (e) {}
|
|
|
|
|
|
|
|
if (!useSysColors)
|
|
|
|
{
|
|
|
|
try { colors.TextColor = prefs.getCharPref("browser.display.foreground_color"); } catch (e) {}
|
|
|
|
|
|
|
|
try { colors.BackgroundColor = prefs.getCharPref("browser.display.background_color"); } catch (e) {}
|
|
|
|
}
|
|
|
|
// Use OS colors for text and background if explicitly asked or pref is not set
|
|
|
|
if (!colors.TextColor)
|
|
|
|
colors.TextColor = "windowtext";
|
|
|
|
|
|
|
|
if (!colors.BackgroundColor)
|
|
|
|
colors.BackgroundColor = "window";
|
|
|
|
|
|
|
|
colors.LinkColor = prefs.getCharPref("browser.anchor_color");
|
|
|
|
colors.VisitedLinkColor = prefs.getCharPref("browser.visited_color");
|
|
|
|
|
|
|
|
return colors;
|
|
|
|
}
|
|
|
|
|
|
|
|
/************* URL handling ***************/
|
|
|
|
|
|
|
|
function TextIsURI(selectedText)
|
|
|
|
{
|
|
|
|
if (selectedText)
|
|
|
|
{
|
|
|
|
var text = selectedText.toLowerCase();
|
|
|
|
return text.match(/^http:\/\/|^https:\/\/|^file:\/\/|^ftp:\/\/|\
|
|
|
|
^about:|^mailto:|^news:|^snews:|^telnet:|\
|
|
|
|
^ldap:|^ldaps:|^gopher:|^finger:|^javascript:/);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function IsUrlAboutBlank(urlString)
|
|
|
|
{
|
|
|
|
return (urlString == "about:blank");
|
|
|
|
}
|
|
|
|
|
|
|
|
function MakeRelativeUrl(url)
|
|
|
|
{
|
|
|
|
var inputUrl = TrimString(url);
|
|
|
|
if (!inputUrl)
|
|
|
|
return inputUrl;
|
|
|
|
|
|
|
|
// Get the filespec relative to current document's location
|
|
|
|
// NOTE: Can't do this if file isn't saved yet!
|
|
|
|
var docUrl = GetDocumentBaseUrl();
|
|
|
|
var docScheme = GetScheme(docUrl);
|
|
|
|
|
|
|
|
// Can't relativize if no doc scheme (page hasn't been saved)
|
|
|
|
if (!docScheme)
|
|
|
|
return inputUrl;
|
|
|
|
|
|
|
|
var urlScheme = GetScheme(inputUrl);
|
|
|
|
|
|
|
|
// Do nothing if not the same scheme or url is already relativized
|
|
|
|
if (docScheme != urlScheme)
|
|
|
|
return inputUrl;
|
|
|
|
|
|
|
|
var IOService = GetIOService();
|
|
|
|
if (!IOService)
|
|
|
|
return inputUrl;
|
|
|
|
|
|
|
|
// Host must be the same
|
|
|
|
var docHost = GetHost(docUrl);
|
|
|
|
var urlHost = GetHost(inputUrl);
|
|
|
|
if (docHost != urlHost)
|
|
|
|
return inputUrl;
|
|
|
|
|
2001-12-12 06:57:32 +03:00
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
// Get just the file path part of the urls
|
|
|
|
var docPath = IOService.extractUrlPart(docUrl, IOService.url_Path, {start:0}, {end:0});
|
|
|
|
var urlPath = IOService.extractUrlPart(inputUrl, IOService.url_Path, {start:0}, {end:0});
|
|
|
|
|
|
|
|
// We only return "urlPath", so we can convert
|
|
|
|
// the entire docPath for case-insensitive comparisons
|
|
|
|
var os = GetOS();
|
2002-02-15 09:07:40 +03:00
|
|
|
var doCaseInsensitive = (docScheme == "file" && os == gWin);
|
2001-11-15 18:28:24 +03:00
|
|
|
if (doCaseInsensitive)
|
|
|
|
docPath = docPath.toLowerCase();
|
|
|
|
|
|
|
|
// Get document filename before we start chopping up the docPath
|
|
|
|
var docFilename = GetFilename(docPath);
|
|
|
|
|
|
|
|
// Both url and doc paths now begin with "/"
|
|
|
|
// Look for shared dirs starting after that
|
|
|
|
urlPath = urlPath.slice(1);
|
|
|
|
docPath = docPath.slice(1);
|
|
|
|
|
|
|
|
var firstDirTest = true;
|
|
|
|
var nextDocSlash = 0;
|
|
|
|
var done = false;
|
|
|
|
|
|
|
|
// Remove all matching subdirs common to both doc and input urls
|
|
|
|
do {
|
|
|
|
nextDocSlash = docPath.indexOf("\/");
|
|
|
|
var nextUrlSlash = urlPath.indexOf("\/");
|
|
|
|
|
|
|
|
if (nextUrlSlash == -1)
|
|
|
|
{
|
|
|
|
// We're done matching and all dirs in url
|
|
|
|
// what's left is the filename
|
|
|
|
done = true;
|
|
|
|
|
|
|
|
// Remove filename for named anchors in the same file
|
|
|
|
if (nextDocSlash == -1 && docFilename)
|
|
|
|
{
|
|
|
|
var anchorIndex = urlPath.indexOf("#");
|
|
|
|
if (anchorIndex > 0)
|
|
|
|
{
|
|
|
|
var urlFilename = doCaseInsensitive ? urlPath.toLowerCase() : urlPath;
|
|
|
|
|
|
|
|
if (urlFilename.indexOf(docFilename) == 0)
|
|
|
|
urlPath = urlPath.slice(anchorIndex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (nextDocSlash >= 0)
|
|
|
|
{
|
|
|
|
// Test for matching subdir
|
|
|
|
var docDir = docPath.slice(0, nextDocSlash);
|
|
|
|
var urlDir = urlPath.slice(0, nextUrlSlash);
|
|
|
|
if (doCaseInsensitive)
|
|
|
|
urlDir = urlDir.toLowerCase();
|
|
|
|
|
|
|
|
if (urlDir == docDir)
|
|
|
|
{
|
|
|
|
|
|
|
|
// Remove matching dir+"/" from each path
|
|
|
|
// and continue to next dir
|
|
|
|
docPath = docPath.slice(nextDocSlash+1);
|
|
|
|
urlPath = urlPath.slice(nextUrlSlash+1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// No match, we're done
|
|
|
|
done = true;
|
|
|
|
|
|
|
|
// Be sure we are on the same local drive or volume
|
|
|
|
// (the first "dir" in the path) because we can't
|
|
|
|
// relativize to different drives/volumes.
|
|
|
|
// UNIX doesn't have volumes, so we must not do this else
|
|
|
|
// the first directory will be misinterpreted as a volume name
|
|
|
|
if (firstDirTest && docScheme == "file" && os != gUNIX)
|
|
|
|
return inputUrl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // No more doc dirs left, we're done
|
|
|
|
done = true;
|
|
|
|
|
|
|
|
firstDirTest = false;
|
|
|
|
}
|
|
|
|
while (!done);
|
|
|
|
|
|
|
|
// Add "../" for each dir left in docPath
|
|
|
|
while (nextDocSlash > 0)
|
|
|
|
{
|
|
|
|
urlPath = "../" + urlPath;
|
|
|
|
nextDocSlash = docPath.indexOf("\/", nextDocSlash+1);
|
|
|
|
}
|
|
|
|
return urlPath;
|
|
|
|
}
|
|
|
|
|
|
|
|
function MakeAbsoluteUrl(url)
|
|
|
|
{
|
|
|
|
var resultUrl = TrimString(url);
|
|
|
|
if (!resultUrl)
|
|
|
|
return resultUrl;
|
|
|
|
|
|
|
|
// Check if URL is already absolute, i.e., it has a scheme
|
|
|
|
var urlScheme = GetScheme(resultUrl);
|
|
|
|
|
|
|
|
if (urlScheme)
|
|
|
|
return resultUrl;
|
|
|
|
|
|
|
|
var docUrl = GetDocumentBaseUrl();
|
|
|
|
var docScheme = GetScheme(docUrl);
|
|
|
|
|
|
|
|
// Can't relativize if no doc scheme (page hasn't been saved)
|
|
|
|
if (!docScheme)
|
|
|
|
return resultUrl;
|
|
|
|
|
|
|
|
var IOService = GetIOService();
|
|
|
|
if (!IOService)
|
|
|
|
return resultUrl;
|
|
|
|
|
|
|
|
// Make a URI object to use its "resolve" method
|
|
|
|
var absoluteUrl = resultUrl;
|
2002-03-06 10:48:55 +03:00
|
|
|
var docUri = IOService.newURI(docUrl, null, null);
|
2001-11-15 18:28:24 +03:00
|
|
|
|
|
|
|
try {
|
|
|
|
absoluteUrl = docUri.resolve(resultUrl);
|
|
|
|
// This is deprecated and buggy!
|
|
|
|
// If used, we must make it a path for the parent directory (remove filename)
|
|
|
|
//absoluteUrl = IOService.resolveRelativePath(resultUrl, docUrl);
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
return absoluteUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the HREF of the page's <base> tag or the document location
|
|
|
|
// returns empty string if no base href and document hasn't been saved yet
|
|
|
|
function GetDocumentBaseUrl()
|
|
|
|
{
|
|
|
|
if (window.editorShell)
|
|
|
|
{
|
|
|
|
var docUrl;
|
|
|
|
|
|
|
|
// if document supplies a <base> tag, use that URL instead
|
|
|
|
var baseList = editorShell.editorDocument.getElementsByTagName("base");
|
|
|
|
if (baseList)
|
|
|
|
{
|
|
|
|
var base = baseList.item(0);
|
|
|
|
if (base)
|
|
|
|
docUrl = base.getAttribute("href");
|
|
|
|
}
|
|
|
|
if (!docUrl)
|
2002-02-15 09:07:40 +03:00
|
|
|
docUrl = GetDocumentUrl();
|
2001-11-15 18:28:24 +03:00
|
|
|
|
|
|
|
if (!IsUrlAboutBlank(docUrl))
|
|
|
|
return docUrl;
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2002-02-15 09:07:40 +03:00
|
|
|
function GetDocumentUrl()
|
|
|
|
{
|
|
|
|
if (editorShell && editorShell.editorDocument)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
var aDOMHTMLDoc = editorShell.editorDocument.QueryInterface(Components.interfaces.nsIDOMHTMLDocument);
|
|
|
|
return aDOMHTMLDoc.URL;
|
|
|
|
}
|
|
|
|
catch (e) {}
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
// Extract the scheme (e.g., 'file', 'http') from a URL string
|
|
|
|
function GetScheme(url)
|
|
|
|
{
|
|
|
|
var resultUrl = TrimString(url);
|
|
|
|
// Unsaved document URL has no acceptable scheme yet
|
|
|
|
if (!resultUrl || IsUrlAboutBlank(resultUrl))
|
|
|
|
return "";
|
|
|
|
|
2002-02-08 18:32:25 +03:00
|
|
|
if (/^internal-gopher-/.test(resultUrl))
|
|
|
|
return "internal-gopher-";
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
var IOService = GetIOService();
|
|
|
|
if (!IOService)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
var scheme = "";
|
|
|
|
try {
|
|
|
|
// This fails if there's no scheme
|
|
|
|
scheme = IOService.extractScheme(resultUrl, {schemeStartPos:0}, {schemeEndPos:0});
|
2002-02-15 09:07:40 +03:00
|
|
|
} catch (e) {}
|
2001-11-15 18:28:24 +03:00
|
|
|
|
2002-02-15 09:07:40 +03:00
|
|
|
return scheme ? scheme.toLowerCase() : "";
|
2001-11-15 18:28:24 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function GetHost(url)
|
|
|
|
{
|
2002-02-20 05:17:46 +03:00
|
|
|
if (!url)
|
|
|
|
return "";
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
var IOService = GetIOService();
|
|
|
|
if (!IOService)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
var host = "";
|
2002-02-20 05:17:46 +03:00
|
|
|
try {
|
|
|
|
host = IOService.extractUrlPart(url, IOService.url_Host, {start:0}, {end:0});
|
|
|
|
} catch (e) {}
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
return host;
|
|
|
|
}
|
|
|
|
|
2002-02-20 05:17:46 +03:00
|
|
|
function GetUsername(url)
|
|
|
|
{
|
|
|
|
if (!url)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
var IOService = GetIOService();
|
|
|
|
if (!IOService)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
var username = "";
|
|
|
|
try {
|
|
|
|
username = IOService.extractUrlPart(url, IOService.url_Username, {start:0}, {end:0});
|
|
|
|
} catch (e) {}
|
|
|
|
|
|
|
|
return username;
|
|
|
|
}
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
function GetFilename(url)
|
|
|
|
{
|
2002-02-20 05:17:46 +03:00
|
|
|
if (!url || IsUrlAboutBlank(url))
|
|
|
|
return "";
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
var IOService = GetIOService();
|
|
|
|
if (!IOService)
|
|
|
|
return "";
|
|
|
|
|
|
|
|
var filename;
|
|
|
|
|
2002-02-20 05:17:46 +03:00
|
|
|
try {
|
|
|
|
filename = IOService.extractUrlPart(url, IOService.url_FileBaseName, {start:0}, {end:0});
|
|
|
|
if (filename)
|
|
|
|
{
|
|
|
|
var ext = IOService.extractUrlPart(url, IOService.url_FileExtension, {start:0}, {end:0});
|
|
|
|
if (ext)
|
|
|
|
filename += "."+ext;
|
|
|
|
}
|
|
|
|
} catch (e) {}
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
return filename ? filename : "";
|
|
|
|
}
|
|
|
|
|
2002-03-08 03:37:47 +03:00
|
|
|
// Return the url without username and password
|
|
|
|
// Optional output objects return extracted username and password strings
|
|
|
|
// This uses just string routines via nsIIOServices
|
|
|
|
function StripUsernamePassword(url, usernameObj, passwordObj)
|
2002-02-15 09:07:40 +03:00
|
|
|
{
|
2002-03-08 03:37:47 +03:00
|
|
|
url = TrimString(url);
|
|
|
|
if (!url || IsUrlAboutBlank(url))
|
|
|
|
return url;
|
|
|
|
|
|
|
|
var IOService = GetIOService();
|
|
|
|
if (!IOService)
|
|
|
|
return url;
|
|
|
|
|
|
|
|
if (usernameObj)
|
|
|
|
usernameObj.value = "";
|
|
|
|
if (passwordObj)
|
|
|
|
passwordObj.value = "";
|
|
|
|
|
|
|
|
// "@" must exist else we will never detect username or password
|
|
|
|
var atIndex = url.indexOf("@");
|
|
|
|
if (atIndex > 0)
|
2002-02-15 09:07:40 +03:00
|
|
|
{
|
|
|
|
try {
|
2002-03-08 03:37:47 +03:00
|
|
|
var startU = {value :0};
|
|
|
|
var username = IOService.extractUrlPart(url, IOService.url_Username, startU, {end:0});
|
|
|
|
var password = IOService.extractUrlPart(url, IOService.url_Password, {start:0}, {end:0});
|
|
|
|
|
|
|
|
if (usernameObj && username)
|
|
|
|
usernameObj.value = username;
|
|
|
|
if (passwordObj && password)
|
|
|
|
passwordObj.value = password;
|
|
|
|
|
|
|
|
if (username)
|
|
|
|
return url.slice(0, startU.value) + url.slice(atIndex+1);
|
|
|
|
|
|
|
|
} catch (e) {}
|
2002-02-15 09:07:40 +03:00
|
|
|
}
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2002-03-08 03:37:47 +03:00
|
|
|
// Version to use when you have an nsIURI object
|
2002-02-15 09:07:40 +03:00
|
|
|
function StripUsernamePasswordFromURI(uri)
|
|
|
|
{
|
|
|
|
var url = "";
|
|
|
|
if (uri)
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
url = uri.spec;
|
2002-03-06 10:48:55 +03:00
|
|
|
var userPass = uri.userPass;
|
|
|
|
if (userPass)
|
2002-02-15 09:07:40 +03:00
|
|
|
{
|
2002-03-06 10:48:55 +03:00
|
|
|
start = url.indexOf(userPass);
|
|
|
|
url = url.slice(0, start) + url.slice(start+userPass.length+1);
|
2002-02-15 09:07:40 +03:00
|
|
|
}
|
|
|
|
} catch (e) {}
|
|
|
|
}
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2001-11-15 18:28:24 +03:00
|
|
|
function GetOS()
|
|
|
|
{
|
|
|
|
if (gOS)
|
|
|
|
return gOS;
|
|
|
|
|
|
|
|
var platform = navigator.platform.toLowerCase();
|
|
|
|
|
|
|
|
if (platform.indexOf("win") != -1)
|
|
|
|
gOS = gWin;
|
|
|
|
else if (platform.indexOf("mac") != -1)
|
|
|
|
gOS = gMac;
|
|
|
|
else if (platform.indexOf("unix") != -1 || platform.indexOf("linux") != -1 || platform.indexOf("sun") != -1)
|
|
|
|
gOS = gUNIX;
|
|
|
|
else
|
|
|
|
gOS = "";
|
|
|
|
// Add other tests?
|
|
|
|
|
|
|
|
return gOS;
|
|
|
|
}
|
2002-01-05 23:25:53 +03:00
|
|
|
|
2002-01-09 16:51:37 +03:00
|
|
|
function ConvertRGBColorIntoHEXColor(color)
|
|
|
|
{
|
|
|
|
if (color.search( /rgb.*/ ) != -1)
|
|
|
|
{
|
2002-02-06 17:48:03 +03:00
|
|
|
var res = color.match( /rgb\((\d*),(\d*),(\d*)\)/ );
|
|
|
|
var r = Number(RegExp.$1).toString(16);
|
2002-01-09 16:51:37 +03:00
|
|
|
if (r.length == 1) r = "0"+r;
|
2002-02-06 17:48:03 +03:00
|
|
|
var g = Number(RegExp.$2).toString(16);
|
2002-02-12 18:52:40 +03:00
|
|
|
if (g.length == 1) g = "0"+g;
|
2002-02-06 17:48:03 +03:00
|
|
|
var b = Number(RegExp.$3).toString(16);
|
2002-01-09 16:51:37 +03:00
|
|
|
if (b.length == 1) b = "0"+b;
|
2002-02-06 17:48:03 +03:00
|
|
|
return "#"+r+g+b;
|
2002-01-09 16:51:37 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-02-15 09:07:40 +03:00
|
|
|
/************* CSS ***************/
|
|
|
|
|
2002-01-09 16:51:37 +03:00
|
|
|
function GetHTMLOrCSSStyleValue(element, attrName, cssPropertyName)
|
|
|
|
{
|
|
|
|
var prefs = GetPrefs();
|
|
|
|
var IsCSSPrefChecked = prefs.getBoolPref("editor.use_css");
|
|
|
|
var value;
|
|
|
|
if (IsCSSPrefChecked && editorShell.editorType == "html")
|
|
|
|
value = element.style.getPropertyValue(cssPropertyName);
|
2002-03-27 00:19:28 +03:00
|
|
|
|
|
|
|
if (!value)
|
2002-01-09 16:51:37 +03:00
|
|
|
value = element.getAttribute(attrName);
|
2002-03-27 00:19:28 +03:00
|
|
|
|
|
|
|
if (!value)
|
|
|
|
return "";
|
|
|
|
|
2002-01-09 16:51:37 +03:00
|
|
|
return value;
|
|
|
|
}
|