mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-15 04:00:12 +01:00
669 lines
21 KiB
JavaScript
669 lines
21 KiB
JavaScript
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla 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/MPL/
|
|
*
|
|
* 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 the Platform for Privacy Preferences.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Netscape Communications Corporation.
|
|
* Portions created by the Initial Developer are Copyright (C) 2002
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s): Harish Dhurvasula <harishd@netscape.com>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
const nsIPolicyReference = Components.interfaces.nsIPolicyReference;
|
|
const nsIPolicyTarget = Components.interfaces.nsIPolicyTarget;
|
|
const nsIIOService = Components.interfaces.nsIIOService;
|
|
const nsIPromptService = Components.interfaces.nsIPromptService;
|
|
const nsIURL = Components.interfaces.nsIURL;
|
|
const nsIStringBundleService = Components.interfaces.nsIStringBundleService;
|
|
const nsIHttpChannel = Components.interfaces.nsIHttpChannel;
|
|
|
|
const STYLESHEET_URL_200201 = "chrome://communicator/content/p3p/p3p200201.xsl";
|
|
const STYLESHEET_URL_200109 = "chrome://communicator/content/p3p/p3p200109.xsl";
|
|
const STYLESHEET_URL_200012 = "chrome://communicator/content/p3p/p3p200012.xsl";
|
|
const STYLESHEET_URL_200010 = "chrome://communicator/content/p3p/p3p200010.xsl";
|
|
const STYLESHEET_URL_200005 = "chrome://communicator/content/p3p/p3p200005.xsl";
|
|
|
|
const FAILURE = 0;
|
|
const SUCCESS = 1;
|
|
|
|
const LOAD_POLICY = 2;
|
|
const LOAD_SUMMARY = 3;
|
|
const LOAD_OPTIONS = 4;
|
|
|
|
const POLICY_ERROR = 5;
|
|
const SUMMARY_ERROR = 6;
|
|
const OPTIONS_ERROR = 7;
|
|
|
|
const DO_TRANSFORM = 8;
|
|
|
|
var gIOService = null;
|
|
var gPromptService = null;
|
|
var gStrBundleService = null;
|
|
var gStrBundle = null;
|
|
var gBrandName = null;
|
|
|
|
/* class nsPolicyViewer
|
|
*
|
|
* Used for viewing site's privacy policy, policy summary ( generated ),
|
|
* and opt-ins/opt-outs
|
|
* @param - aMainURI -> The URI of the loaded document.
|
|
*
|
|
*/
|
|
function nsPolicyViewer(aDoc)
|
|
{
|
|
if (!gIOService) {
|
|
gIOService =
|
|
Components.classes["@mozilla.org/network/io-service;1"].getService(nsIIOService);
|
|
}
|
|
|
|
try {
|
|
this.mMainURI = gIOService.newURI(aDoc.location.href, null, null);
|
|
}
|
|
catch(ex) {
|
|
this.mSelectedURI = aDoc.location.href;
|
|
this.reportError(LOAD_POLICY);
|
|
}
|
|
|
|
}
|
|
|
|
nsPolicyViewer.prototype =
|
|
{
|
|
mAction : null,
|
|
mPolicyLocation : null,
|
|
mPolicyReference : null,
|
|
mPolicyTarget : null,
|
|
mXMLHttpRequest : null,
|
|
mXSLTProcessor : null,
|
|
mDocument : null,
|
|
mPolicyURL : null,
|
|
mMainURI : null,
|
|
mSelectedURI : null,
|
|
mLinkedURI : null,
|
|
mStyle : null,
|
|
mFragment : null,
|
|
mFlag : 0,
|
|
|
|
/*
|
|
* Initiate privacy policy loading for a URI selected
|
|
* in the Page-Info-Privacy tab window.
|
|
* @param - aSelectedURI -> Absolute URI that requests a privacy policy
|
|
* @param - aAction -> HUMAN READABLE | GENERATE SUMMARY | OPT-IN/OPT-OUT
|
|
*/
|
|
load : function (aSelectedURI, aAction)
|
|
{
|
|
// Since P3P operates by definition on HTTP(S) URLs only,
|
|
// bail out here if the URL is not HTTP(S).
|
|
if (aSelectedURI.match(/^\s*https?:/i)) {
|
|
if (this.init(aSelectedURI, aAction) == SUCCESS) {
|
|
this.handleURI(this.mSelectedURI, this.mFlag);
|
|
}
|
|
} else {
|
|
// XXX Error message should reflect that this operation
|
|
// is not supported for this protocol (which is not HTTP(S)).
|
|
this.mSelectedURI = aSelectedURI;
|
|
this.reportError(aAction);
|
|
}
|
|
},
|
|
|
|
/*
|
|
* Initialize nsPolicyViewer
|
|
* @param - aSelectedURI -> URI that requests a privacy policy
|
|
* @param - aAction -> HUMAN READABLE | MACHINE READABLE | OPT-IN/OPT-OUT
|
|
*/
|
|
init : function(aSelectedURI, aAction)
|
|
{
|
|
try {
|
|
if (!this.mPolicyReference) {
|
|
this.mPolicyReference =
|
|
Components.classes["@mozilla.org/p3p/policyreference;1"].createInstance(nsIPolicyReference);
|
|
|
|
this.mPolicyTarget = this.mPolicyReference.QueryInterface(nsIPolicyTarget);
|
|
this.mPolicyTarget.setupPolicyListener(this);
|
|
this.mPolicyReference.initialize(this.mMainURI);
|
|
}
|
|
|
|
this.mAction = aAction;
|
|
|
|
// aSelectedURI is already absolute spec
|
|
if (!this.mSelectedURI) {
|
|
this.mSelectedURI = gIOService.newURI(aSelectedURI, null, null);
|
|
}
|
|
else {
|
|
this.mSelectedURI.spec = aSelectedURI;
|
|
}
|
|
|
|
// Ex. http://foo.com:80/ == http://foo.com/
|
|
if (isEquivalent(this.mMainURI, this.mSelectedURI)) {
|
|
this.mFlag = nsIPolicyReference.IS_MAIN_URI;
|
|
}
|
|
else {
|
|
this.mFlag = nsIPolicyReference.IS_EMBEDDED_URI;
|
|
}
|
|
|
|
return SUCCESS;
|
|
}
|
|
catch (ex) {
|
|
this.reportError(aAction);
|
|
return FAILURE;
|
|
}
|
|
},
|
|
|
|
/*
|
|
* This is a callback method. This method gets called
|
|
* when a full privacy policy is loaded or when a style
|
|
* sheet is loaded to begin transformation.
|
|
*/
|
|
handleEvent : function(aEvent) {
|
|
switch (this.mAction) {
|
|
case LOAD_POLICY :
|
|
this.viewHumanReadablePolicy(); break;
|
|
case LOAD_SUMMARY :
|
|
this.viewMachineReadablePolicy(); break;
|
|
case LOAD_OPTIONS :
|
|
this.viewOptInOptOutPolicy(); break;
|
|
case DO_TRANSFORM :
|
|
this.transform(); break;
|
|
default:
|
|
reportError(POLICY_ERROR); break;
|
|
}
|
|
},
|
|
|
|
/*
|
|
* Initiate policy reference file ( PRF ) loading. A policy reference file
|
|
* is used for locating the full p3p policy location.
|
|
* @param - aURI -> URI that requests a privacy policy
|
|
* @param - aFlag -> IS_MAIN_URI - The loaded document's URI
|
|
* IS_EMBEDDED_URI - URI, embedded in the current document, with a different host.
|
|
* IS_LINKED_URI - URI referenced via HTML/XHTML LINK tag.
|
|
*/
|
|
handleURI : function (aURI, aFlag)
|
|
{
|
|
try {
|
|
this.mPolicyReference.loadPolicyReferenceFileFor(aURI, aFlag);
|
|
}
|
|
catch(ex) {
|
|
this.reportError(this.mAction);
|
|
}
|
|
},
|
|
|
|
/*
|
|
* This is a callback method.
|
|
* @param - aLocation -> A full p3p policy location
|
|
* @param - aError -> POLICY_LOAD_SUCCESS | POLICY_LOAD_FAILURE
|
|
*/
|
|
notifyPolicyLocation : function (aLocation, aError)
|
|
{
|
|
if (aError == nsIPolicyReference.POLICY_LOAD_SUCCESS) {
|
|
if (!this.mPolicyURL) {
|
|
this.mPolicyURL = gIOService.newURI(aLocation, null, null).QueryInterface(nsIURL);
|
|
}
|
|
else {
|
|
this.mPolicyURL.spec = aLocation;
|
|
}
|
|
|
|
// We have located the full p3p policy location from
|
|
// the policy reference file. Now let's try to load full p3p
|
|
// policy document.
|
|
if (!this.mXMLHttpRequest) {
|
|
this.mXMLHttpRequest = new XMLHttpRequest();
|
|
}
|
|
|
|
// If a fragment identifier is specified then we have to locate
|
|
// the POLICY with a name specified by the fragment.
|
|
// Ex. <POLICY name="one"> .... </POLICY> <POLICY name="two"> ...</POLICY>
|
|
// if the fragment identifier is "#two" then we should find the POLICY named "two"
|
|
this.mFragment = this.mPolicyURL.ref;
|
|
|
|
// If we've already loaded a full p3p policy then the policy
|
|
// document should be available ( note: Only for the same host's URIs ).
|
|
if (this.mFlag & nsIPolicyReference.IS_MAIN_URI) {
|
|
if (this.mDocument) {
|
|
if (this.mPolicyLocation.match(aLocation)) {
|
|
this.handleEvent(null);
|
|
return;
|
|
}
|
|
this.mFlag &= ~nsIPolicyReference.IS_MAIN_URI;
|
|
}
|
|
else {
|
|
if (this.mMainURI.spec.match(this.mSelectedURI.spec)) {
|
|
this.mPolicyLocation = aLocation;
|
|
}
|
|
else {
|
|
this.mFlag &= ~nsIPolicyReference.IS_MAIN_URI;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.mXMLHttpRequest.onload = this;
|
|
// Override the mime type because without it XMLHttpRequest hangs
|
|
// on certain sites that serve HTML instead ofXML.
|
|
this.mXMLHttpRequest.overrideMimeType("application/xml");
|
|
this.mXMLHttpRequest.open("GET", aLocation);
|
|
this.mXMLHttpRequest.send(null);
|
|
}
|
|
else if (this.mFlag & nsIPolicyReference.IS_MAIN_URI) {
|
|
// Weren't able to locate the full p3p policy via PRF?
|
|
// Let's see if the policy location is referenced via the
|
|
// current document's link tag.
|
|
var links = gTopDoc.getElementsByTagName("LINK");
|
|
var length = links.length;
|
|
for (index = 0; index < length; index++) {
|
|
var node = links[index];
|
|
if (node.getAttribute("rel") == "P3Pv1") {
|
|
try {
|
|
if (!this.mLinkedURI) {
|
|
this.mLinkedURI = gIOService.newURI(node.href, null, null);
|
|
}
|
|
else {
|
|
this.mLinkedURI.spec = node.href;
|
|
}
|
|
// Yay!, we have found the policy location no need to search the other link tags.
|
|
this.handleURI(this.mLinkedURI, this.mFlag = nsIPolicyReference.IS_LINKED_URI);
|
|
return;
|
|
}
|
|
catch (ex) {
|
|
// fall through to report error.
|
|
}
|
|
}
|
|
}
|
|
this.reportError(this.mAction);
|
|
}
|
|
else {
|
|
this.reportError(this.mAction);
|
|
}
|
|
},
|
|
|
|
/*
|
|
* Called on a policy load error.
|
|
* @param - aError -> POLICY_LOAD_SUCCESS | POLICY_LOAD_FAILURE
|
|
*/
|
|
notifyPolicyError : function (aError)
|
|
{
|
|
this.reportError(this.mAction);
|
|
},
|
|
|
|
/*
|
|
* Signal policy reference ( native code ) that we're done
|
|
* with the policy viewer and therefore all the objects can
|
|
* be released
|
|
*/
|
|
finalize: function ()
|
|
{
|
|
if (this.mPolicyReference) {
|
|
this.mPolicyReference.finalize();
|
|
}
|
|
},
|
|
|
|
/*
|
|
* This is required to make the wrapper code happy
|
|
*/
|
|
QueryInterface: function (iid)
|
|
{
|
|
if (iid.equals(Components.interfaces.nsISupports) ||
|
|
iid.equals(Components.interfaces.nsISupportsWeakReference) ||
|
|
iid.equals(Components.interfaces.nsIDOMEventListener))
|
|
return this;
|
|
|
|
Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
|
|
return null;
|
|
},
|
|
|
|
/*
|
|
* The purpose of this method is to display a human readable
|
|
* version of the site's policy. That is, we load, on a new window,
|
|
* the value of the "discuri" attribute of the POLICY node.
|
|
*/
|
|
viewHumanReadablePolicy : function ()
|
|
{
|
|
var document = this.getDocument();
|
|
if (document) {
|
|
// Note: P3P policies can be associated with at least five
|
|
// different namespaces. For performance reasons intentionally
|
|
// accessing element by name without namespace.
|
|
var nodelist = document.getElementsByTagName("POLICY");
|
|
var length = nodelist.length;
|
|
if (length > 0) {
|
|
for (index = 0; index < length; index++) {
|
|
var node = nodelist[index];
|
|
var name = node.getAttribute("name");
|
|
|
|
// If a fragment identifier is specified then we have to locate
|
|
// the POLICY with a name specified by that fragment.
|
|
if (!this.mFragment || this.mFragment == name) {
|
|
var discuri = node.getAttribute("discuri");
|
|
if (discuri) {
|
|
discuri = this.mPolicyURL.resolve(discuri);
|
|
if (discuri.match(/^\s*https?:/i)) {
|
|
window.open(discuri);
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
this.reportError(POLICY_ERROR);
|
|
}
|
|
else {
|
|
this.reportError(POLICY_ERROR);
|
|
}
|
|
}
|
|
},
|
|
|
|
/*
|
|
* The purpose of this method is to generate a summary ( using XSLT )
|
|
* based on the machine readable format ( XML ) of the full p3p policy.
|
|
*/
|
|
viewMachineReadablePolicy : function ()
|
|
{
|
|
var document = this.getDocument();
|
|
if (document) {
|
|
// Note: P3P policies can be associated with at least five
|
|
// different namespaces. For performance reasons intentionally
|
|
// accessing element by name without namespace.
|
|
var nodelist = document.getElementsByTagName("POLICY");
|
|
var length = nodelist.length;
|
|
if (length > 1) {
|
|
var index = 0;
|
|
while (index < length) {
|
|
var node = nodelist[index];
|
|
var name = node.getAttribute("name");
|
|
|
|
// If a fragment identifier is specified then target
|
|
// the POLICY with that fragment name. To achieve that
|
|
// remove all other POLICY nodes that don't match the name.
|
|
// By doing this the XSLT code doesn't have to know what
|
|
// part of the full policy needs to be transformed.
|
|
if (this.mFragment && this.mFragment != name) {
|
|
node.parentNode.removeChild(node);
|
|
// When a node gets removed it will be reflected on the nodelist.
|
|
// That is, the nodelist length will decrease. To stay within
|
|
// bounds of the nodelist array do not increment index.
|
|
--length;
|
|
}
|
|
else {
|
|
++index;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.preTransform();
|
|
}
|
|
},
|
|
|
|
/*
|
|
* The purpose of this method is to display a human readable
|
|
* version of the site's opt-in / opt-out policy. That is, we
|
|
* load, on a new window, the value of the "opturi" attribute
|
|
* of the POLICY node.
|
|
*/
|
|
viewOptInOptOutPolicy : function ()
|
|
{
|
|
var document = this.getDocument();
|
|
|
|
if (document) {
|
|
// Note: P3P policies can be associated with at least five
|
|
// different namespaces. For performance reasons intentionally
|
|
// accessing element by name without namespace.
|
|
var nodelist = document.getElementsByTagName("POLICY");
|
|
var length = nodelist.length;
|
|
if (length > 0) {
|
|
for (index = 0; index < length; index++) {
|
|
var node = nodelist[index];
|
|
var name = node.getAttribute("name");
|
|
|
|
// If a fragment identifier is specified then we have to locate
|
|
// the POLICY with a name specified by that fragment.
|
|
if (!this.mFragment || this.mFragment == name) {
|
|
var opturi = node.getAttribute("opturi");
|
|
if (opturi) {
|
|
opturi = this.mPolicyURL.resolve(opturi);
|
|
if (opturi.match(/^\s*https?:/i)) {
|
|
window.open(opturi);
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
this.reportError(OPTIONS_ERROR);
|
|
}
|
|
else {
|
|
this.reportError(OPTIONS_ERROR);
|
|
}
|
|
}
|
|
},
|
|
|
|
/*
|
|
* The purpose of this method is to retrieve a full p3p
|
|
* policy document.
|
|
* @return document or null.
|
|
*/
|
|
getDocument : function ()
|
|
{
|
|
var document = null;
|
|
var channel = null;
|
|
if (this.mFlag & nsIPolicyReference.IS_MAIN_URI) {
|
|
if (!this.mDocument) {
|
|
channel = this.mXMLHttpRequest.channel.QueryInterface(nsIHttpChannel);
|
|
if (channel.requestSucceeded) {
|
|
this.mDocument = this.mXMLHttpRequest.responseXML;
|
|
}
|
|
else {
|
|
this.reportError(this.mAction);
|
|
return null;
|
|
}
|
|
}
|
|
document = this.mDocument;
|
|
}
|
|
else {
|
|
channel = this.mXMLHttpRequest.channel.QueryInterface(nsIHttpChannel);
|
|
if (channel.requestSucceeded) {
|
|
document = this.mXMLHttpRequest.responseXML;
|
|
}
|
|
else {
|
|
this.reportError(aAction);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
return document;
|
|
},
|
|
|
|
/*
|
|
* The purpose of this method is to select a style sheet ( XSL )
|
|
* based on the document's namespace and then initiate transformation
|
|
* of the machine readable privacy policy into a human readable summary.
|
|
*/
|
|
preTransform : function ()
|
|
{
|
|
try {
|
|
this.mStyle = document.implementation.createDocument("", "", null);
|
|
this.mAction = DO_TRANSFORM;
|
|
this.mStyle.addEventListener("load", this, false);
|
|
|
|
var sheet = null;
|
|
var ns = this.getDocument().documentElement.namespaceURI;
|
|
|
|
if (ns == "http://www.w3.org/2002/01/P3Pv1") {
|
|
sheet = STYLESHEET_URL_200201;
|
|
} else if (ns == "http://www.w3.org/2001/09/P3Pv1") {
|
|
sheet = STYLESHEET_URL_200109;
|
|
} else if (ns == "http://www.w3.org/2000/12/P3Pv1") {
|
|
sheet = STYLESHEET_URL_200012;
|
|
} else if (ns == "http://www.w3.org/2000/10/18/P3Pv1") {
|
|
sheet = STYLESHEET_URL_200010;
|
|
} else if (ns == "http://www.w3.org/2000/P3Pv1") {
|
|
sheet = STYLESHEET_URL_200005;
|
|
} else {
|
|
this.reportError(SUMMARY_ERROR);
|
|
}
|
|
|
|
if (sheet) {
|
|
this.mStyle.load(sheet);
|
|
}
|
|
}
|
|
catch(ex) {
|
|
this.reportError(LOAD_SUMMARY);
|
|
}
|
|
},
|
|
|
|
/*
|
|
* This is a callback method. This method assumes that
|
|
* a style sheet is available, for the document in question,
|
|
* and therefore the document ( XML ) is ready for the
|
|
* transformation.
|
|
*/
|
|
transform : function ()
|
|
{
|
|
this.mStyle.removeEventListener("load", this, false);
|
|
|
|
if (!this.mXSLTProcessor) {
|
|
this.mXSLTProcessor = new XSLTProcessor();
|
|
}
|
|
|
|
// An onload event ( triggered when a result window is opened )
|
|
// would start the transformation.
|
|
var resultWin = window.openDialog("chrome://p3p/content/p3pSummary.xul", "_blank",
|
|
"chrome,all,dialog=no", this.mXSLTProcessor,
|
|
this.getDocument(), this.mStyle, this.mPolicyURL);
|
|
},
|
|
|
|
/*
|
|
* The purpose of this method is to display localized errors to the user
|
|
*/
|
|
reportError : function (aAction)
|
|
{
|
|
var name = null;
|
|
switch (aAction) {
|
|
case LOAD_POLICY :
|
|
name = "PolicyLoadFailed"; break;
|
|
case LOAD_SUMMARY :
|
|
name = "SummaryLoadFailed"; break;
|
|
case LOAD_OPTIONS :
|
|
name = "OptionLoadFailed"; break;
|
|
case POLICY_ERROR :
|
|
name = "PolicyError"; break;
|
|
case SUMMARY_ERROR :
|
|
name = "SummaryError"; break;
|
|
case OPTIONS_ERROR :
|
|
name = "OptionsError"; break;
|
|
case DO_TRANSFORM:
|
|
name = "SummaryError"; break;
|
|
default:
|
|
name = "PolicyLoadFailed"; break;
|
|
}
|
|
|
|
var spec = this.mSelectedURI.spec;
|
|
if (!spec) {
|
|
spec = this.mSelectedURI;
|
|
this.mSelectedURI = null;
|
|
}
|
|
|
|
var errorMessage = getBundle().formatStringFromName(name, [spec], 1);
|
|
alertMessage(errorMessage);
|
|
}
|
|
};
|
|
|
|
/*
|
|
* @return string bundle service.
|
|
*/
|
|
function getStrBundleService ()
|
|
{
|
|
if (!gStrBundleService) {
|
|
gStrBundleService =
|
|
Components.classes["@mozilla.org/intl/stringbundle;1"].getService(nsIStringBundleService);
|
|
}
|
|
return gStrBundleService;
|
|
}
|
|
|
|
/*
|
|
* This method is required for localized messages.
|
|
* @return string bundle.
|
|
*/
|
|
function getBundle ()
|
|
{
|
|
if (!gStrBundle) {
|
|
gStrBundle = getStrBundleService().createBundle("chrome://p3p/locale/P3P.properties");
|
|
}
|
|
return gStrBundle;
|
|
}
|
|
|
|
/*
|
|
* @return brand name.
|
|
*/
|
|
function getBrandName ()
|
|
{
|
|
if (!gBrandName) {
|
|
var brandBundle = getStrBundleService().createBundle("chrome://branding/locale/brand.properties");
|
|
gBrandName = brandBundle.GetStringFromName("brandShortName")
|
|
}
|
|
return gBrandName;
|
|
}
|
|
|
|
/*
|
|
* This functions compares two URLs for equality
|
|
* That is, if the scheme, host, and port match then
|
|
* the URLs are considered to be equal.
|
|
* Ex. http://www.example.com/ == http://www.example.com/doc
|
|
* http://www.example.com:80/ == http://www.example.com
|
|
*/
|
|
function isEquivalent (aLHS, aRHS)
|
|
{
|
|
var scheme1 = aLHS.scheme;
|
|
var scheme2 = aRHS.scheme;
|
|
if (scheme1.match(scheme2) && aLHS.host.match(aRHS.host)) {
|
|
var port1 = aLHS.port;
|
|
var port2 = aRHS.port;
|
|
// A port value of -1 corresponds to the protocol's default port.
|
|
// 80 -> http, 443 -> https
|
|
if (scheme1.match("http")) {
|
|
port1 = (port1 == 80) ? -1 : port1;
|
|
port2 = (port2 == 80) ? -1 : port2;
|
|
}
|
|
else if (scheme1.match("https")) {
|
|
port1 = (port1 == 443) ? -1 : port1;
|
|
port2 = (port2 == 443) ? -1 : port2;
|
|
}
|
|
|
|
if (port1 == port2) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function alertMessage(aMessage)
|
|
{
|
|
if (!gPromptService) {
|
|
gPromptService =
|
|
Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(nsIPromptService);
|
|
}
|
|
gPromptService.alert(window, getBrandName(), aMessage);
|
|
}
|