mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-11 02:10:17 +01:00
529 lines
12 KiB
JavaScript
529 lines
12 KiB
JavaScript
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
*
|
|
* ***** 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 mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Netscape Communications Corporation.
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Robert Ginda, rginda@netscape.com, original author
|
|
*
|
|
* 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 ***** */
|
|
|
|
/*
|
|
* This file is (at the time of this writing) an exact copy of the chatzilla
|
|
* utility functions. It should actually be globally accessible (not just
|
|
* part of chatzilla.) This hasn't happened yet, so it's copied here to
|
|
* avoid a dependancy on chatzilla
|
|
*/
|
|
|
|
var dumpln;
|
|
if (typeof document == "undefined") /* in xpcshell */
|
|
dumpln = print;
|
|
else
|
|
if (typeof dump == "function")
|
|
dumpln = function (str) {dump (str + "\n");}
|
|
else if (jsenv.HAS_RHINO)
|
|
dumpln = function (str) {var out = java.lang.System.out;
|
|
out.println(str); out.flush(); }
|
|
else
|
|
dumpln = function () {} /* no suitable function */
|
|
|
|
var dd;
|
|
if (DEBUG)
|
|
dd = dumpln;
|
|
else
|
|
dd = function (){};
|
|
|
|
var jsenv = new Object();
|
|
jsenv.HAS_SECURITYMANAGER = ((typeof netscape == "object") &&
|
|
(typeof netscape.security == "object"));
|
|
jsenv.HAS_XPCOM = ((typeof Components == "function") &&
|
|
(typeof Components.classes == "function"));
|
|
jsenv.HAS_JAVA = (typeof java == "object");
|
|
jsenv.HAS_RHINO = (typeof defineClass == "function");
|
|
jsenv.HAS_DOCUMENT = (typeof document == "object");
|
|
|
|
function dumpObject (o, pfx, sep)
|
|
{
|
|
var p;
|
|
var s = "";
|
|
|
|
sep = (typeof sep == "undefined") ? " = " : sep;
|
|
pfx = (typeof pfx == "undefined") ? "" : pfx;
|
|
|
|
for (p in o)
|
|
{
|
|
if (typeof (o[p]) != "function")
|
|
s += pfx + p + sep + o[p] + "\n";
|
|
else
|
|
s += pfx + p + sep + "function\n";
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
/* Dumps an object in tree format, recurse specifiec the the number of objects
|
|
* to recurse, compress is a boolean that can uncompress (true) the output
|
|
* format, and level is the number of levels to intitialy indent (only useful
|
|
* internally.) A sample dumpObjectTree (o, 1) is shown below.
|
|
*
|
|
* + parent (object)
|
|
* + users (object)
|
|
* | + jsbot (object)
|
|
* | + mrjs (object)
|
|
* | + nakkezzzz (object)
|
|
* | *
|
|
* + bans (object)
|
|
* | *
|
|
* + topic (string) 'ircclient.js:59: nothing is not defined'
|
|
* + getUsersLength (function) 9 lines
|
|
* *
|
|
*/
|
|
function dumpObjectTree (o, recurse, compress, level)
|
|
{
|
|
var s = "";
|
|
var pfx = "";
|
|
|
|
if (typeof recurse == "undefined")
|
|
recurse = 0;
|
|
if (typeof level == "undefined")
|
|
level = 0;
|
|
if (typeof compress == "undefined")
|
|
compress = true;
|
|
|
|
for (var i = 0; i < level; i++)
|
|
pfx += (compress) ? "| " : "| ";
|
|
|
|
var tee = (compress) ? "+ " : "+- ";
|
|
|
|
for (i in o)
|
|
{
|
|
|
|
var t = typeof o[i];
|
|
switch (t)
|
|
{
|
|
case "function":
|
|
var sfunc = o[i].toString().split("\n");
|
|
if (sfunc[2] == " [native code]")
|
|
sfunc = "[native code]";
|
|
else
|
|
sfunc = sfunc.length + " lines";
|
|
s += pfx + tee + i + " (function) " + sfunc + "\n";
|
|
break;
|
|
|
|
case "object":
|
|
s += pfx + tee + i + " (object)\n";
|
|
if (!compress)
|
|
s += pfx + "|\n";
|
|
if ((i != "parent") && (recurse))
|
|
s += dumpObjectTree (o[i], recurse - 1,
|
|
compress, level + 1);
|
|
break;
|
|
|
|
case "string":
|
|
if (o[i].length > 200)
|
|
s += pfx + tee + i + " (" + t + ") " +
|
|
o[i].length + " chars\n";
|
|
else
|
|
s += pfx + tee + i + " (" + t + ") '" + o[i] + "'\n";
|
|
break;
|
|
|
|
default:
|
|
s += pfx + tee + i + " (" + t + ") " + o[i] + "\n";
|
|
|
|
}
|
|
|
|
if (!compress)
|
|
s += pfx + "|\n";
|
|
|
|
}
|
|
|
|
s += pfx + "*\n";
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
/*
|
|
* Clones an existing object (Only the enumerable properties
|
|
* of course.) use as a function..
|
|
* var c = Clone (obj);
|
|
* or a constructor...
|
|
* var c = new Clone (obj);
|
|
*/
|
|
function Clone (obj)
|
|
{
|
|
robj = new Object();
|
|
|
|
for (var p in obj)
|
|
robj[p] = obj[p];
|
|
|
|
return robj;
|
|
|
|
}
|
|
|
|
/*
|
|
* matches a real object against one or more pattern objects.
|
|
* if you pass an array of pattern objects, |negate| controls wether to check
|
|
* if the object matches ANY of the patterns, or NONE of the patterns.
|
|
*/
|
|
function matchObject (o, pattern, negate)
|
|
{
|
|
negate = Boolean(negate);
|
|
|
|
function _match (o, pattern)
|
|
{
|
|
if (pattern instanceof Function)
|
|
return pattern(o);
|
|
|
|
for (p in pattern)
|
|
{
|
|
var val;
|
|
/* nice to have, but slow as molases, allows you to match
|
|
* properties of objects with obj$prop: "foo" syntax */
|
|
/*
|
|
if (p[0] == "$")
|
|
val = eval ("o." +
|
|
p.substr(1,p.length).replace (/\$/g, "."));
|
|
else
|
|
*/
|
|
val = o[p];
|
|
|
|
if (pattern[p] instanceof Function)
|
|
{
|
|
if (!pattern[p](val))
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
var ary = (new String(val)).match(pattern[p]);
|
|
if (ary == null)
|
|
return false;
|
|
else
|
|
o.matchresult = ary;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (!(pattern instanceof Array))
|
|
return Boolean (negate ^ _match(o, pattern));
|
|
|
|
for (var i in pattern)
|
|
if (_match (o, pattern[i]))
|
|
return !negate;
|
|
|
|
return negate;
|
|
|
|
}
|
|
|
|
function matchEntry (partialName, list)
|
|
{
|
|
|
|
if ((typeof partialName == "undefined") ||
|
|
(String(partialName) == ""))
|
|
return list;
|
|
|
|
var ary = new Array();
|
|
|
|
for (var i in list)
|
|
{
|
|
if (list[i].indexOf(partialName) == 0)
|
|
ary.push (list[i]);
|
|
}
|
|
|
|
return ary;
|
|
|
|
}
|
|
|
|
function getCommonPfx (list)
|
|
{
|
|
var pfx = list[0];
|
|
var l = list.length;
|
|
|
|
for (var i = 1; i < l; i++)
|
|
{
|
|
for (var c = 0; c < pfx.length; c++)
|
|
if (pfx[c] != list[i][c])
|
|
pfx = pfx.substr (0, c);
|
|
}
|
|
|
|
return pfx;
|
|
|
|
}
|
|
|
|
function renameProperty (obj, oldname, newname)
|
|
{
|
|
|
|
if (oldname == newname)
|
|
return;
|
|
|
|
obj[newname] = obj[oldname];
|
|
delete obj[oldname];
|
|
|
|
}
|
|
|
|
function newObject(contractID, iface)
|
|
{
|
|
if (!jsenv.HAS_XPCOM)
|
|
return null;
|
|
|
|
var obj = Components.classes[contractID].createInstance();
|
|
var rv;
|
|
|
|
switch (typeof iface)
|
|
{
|
|
case "string":
|
|
rv = obj.QueryInterface(Components.interfaces[iface]);
|
|
break;
|
|
|
|
case "object":
|
|
rv = obj.QueryInterface[iface];
|
|
break;
|
|
|
|
default:
|
|
rv = null;
|
|
break;
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
function getPriv (priv)
|
|
{
|
|
if (!jsenv.HAS_SECURITYMANAGER)
|
|
return true;
|
|
|
|
var rv = true;
|
|
|
|
try
|
|
{
|
|
netscape.security.PrivilegeManager.enablePrivilege(priv);
|
|
}
|
|
catch (e)
|
|
{
|
|
dd ("getPriv: unable to get privlege '" + priv + "': " + e);
|
|
rv = false;
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
function keys (o)
|
|
{
|
|
var rv = new Array();
|
|
|
|
for (var p in o)
|
|
rv.push(p);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
function stringTrim (s)
|
|
{
|
|
if (!s)
|
|
return "";
|
|
s = s.replace (/^\s+/, "");
|
|
return s.replace (/\s+$/, "");
|
|
|
|
}
|
|
|
|
|
|
function arrayInsertAt (ary, i, o)
|
|
{
|
|
|
|
ary.splice (i, 0, o);
|
|
|
|
/* doh, forgot about that 'splice' thing
|
|
if (ary.length < i)
|
|
{
|
|
this[i] = o;
|
|
return;
|
|
}
|
|
|
|
for (var j = ary.length; j > i; j--)
|
|
ary[j] = ary[j - 1];
|
|
|
|
ary[i] = o;
|
|
*/
|
|
}
|
|
|
|
function arrayRemoveAt (ary, i)
|
|
{
|
|
|
|
ary.splice (i, 1);
|
|
|
|
/* doh, forgot about that 'splice' thing
|
|
if (ary.length < i)
|
|
return false;
|
|
|
|
for (var j = i; j < ary.length; j++)
|
|
ary[j] = ary[j + 1];
|
|
|
|
ary.length--;
|
|
*/
|
|
|
|
}
|
|
|
|
/* length should be an even number >= 6 */
|
|
function abbreviateWord (str, length)
|
|
{
|
|
if (str.length <= length || length < 6)
|
|
return str;
|
|
|
|
var left = str.substr (0, (length / 2) - 1);
|
|
var right = str.substr (str.length - (length / 2) + 1);
|
|
|
|
return left + "..." + right;
|
|
}
|
|
|
|
function getRandomElement (ary)
|
|
{
|
|
var i = parseInt (Math.random() * ary.length)
|
|
if (i == ary.length) i = 0;
|
|
|
|
return ary[i];
|
|
|
|
}
|
|
|
|
function roundTo (num, prec)
|
|
{
|
|
|
|
return parseInt (( Math.round(num) * Math.pow (10, prec))) /
|
|
Math.pow (10, prec);
|
|
|
|
}
|
|
|
|
function randomRange (min, max)
|
|
{
|
|
|
|
if (typeof min == "undefined")
|
|
min = 0;
|
|
|
|
if (typeof max == "undefined")
|
|
max = 1;
|
|
|
|
var rv = (parseInt(Math.round((Math.random() * (max - min)) + min )));
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
function getStackTrace ()
|
|
{
|
|
|
|
if (!jsenv.HAS_XPCOM)
|
|
return "No stack trace available.";
|
|
|
|
var frame = Components.stack.caller;
|
|
var str = "<top>";
|
|
|
|
while (frame)
|
|
{
|
|
var name = frame.functionName ? frame.functionName : "[anonymous]";
|
|
str += "\n" + name + "@" + frame.lineNumber;
|
|
frame = frame.caller;
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
function getInterfaces (cls)
|
|
{
|
|
if (!jsenv.HAS_XPCOM)
|
|
return null;
|
|
|
|
var rv = new Object();
|
|
var e;
|
|
|
|
for (var i in Components.interfaces)
|
|
{
|
|
try
|
|
{
|
|
var ifc = Components.interfaces[i];
|
|
cls.QueryInterface(ifc);
|
|
rv[i] = ifc;
|
|
}
|
|
catch (e)
|
|
{
|
|
/* nada */
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
/**
|
|
* Calls a named function for each element in an array, sending
|
|
* the same parameter each call.
|
|
*
|
|
* @param ary an array of objects
|
|
* @param func_name string name of function to call.
|
|
* @param data data object to pass to each object.
|
|
*/
|
|
function mapObjFunc(ary, func_name, data)
|
|
{
|
|
/*
|
|
* WARNING: Caller assumes resonsibility to verify ary
|
|
* and func_name
|
|
*/
|
|
|
|
for (var i in ary)
|
|
ary[i][func_name](data);
|
|
}
|
|
|
|
/**
|
|
* Passes each element of an array to a given function object.
|
|
*
|
|
* @param func a function object.
|
|
* @param ary an array of values.
|
|
*/
|
|
function map(func, ary) {
|
|
|
|
/*
|
|
* WARNING: Caller assumnes responsibility to verify
|
|
* func and ary.
|
|
*/
|
|
|
|
for (var i in ary)
|
|
func(ary[i]);
|
|
|
|
}
|
|
|