1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3
* The contents of this file are subject to the Mozilla Public
4
* License Version 1.1 (the "License"); you may not use this file
5
* except in compliance with the License. You may obtain a copy of
6
* the License at http://www.mozilla.org/MPL/
8
* Software distributed under the License is distributed on an "AS
9
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10
* implied. See the License for the specific language governing
11
* rights and limitations under the License.
13
* The Original Code is mozilla.org code
15
* The Initial Developer of the Original Code is New Dimensions Consulting,
16
* Inc. Portions created by New Dimensions Consulting, Inc. are
17
* Copyright (C) 1999 New Dimensions Consulting, Inc. All Rights Reserved.
20
* Robert Ginda, rginda@ndcico.com, original author
23
* JavaScript utility functions.
29
const nsIBaseWindow = Components.interfaces.nsIBaseWindow;
30
const nsIXULWindow = Components.interfaces.nsIXULWindow;
31
const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor;
32
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
33
const nsIDocShellTreeItem = Components.interfaces.nsIDocShellTreeItem;
35
var utils = new Object();
37
if (typeof document == "undefined") /* in xpcshell */
43
if (typeof dump == "function")
44
dumpln = function (str) {dump (str + "\n");}
45
else if (jsenv.HAS_RHINO)
47
dumpln = function (str) {
48
var out = java.lang.System.out;
49
out.println(str); out.flush();
53
dumpln = function () {} /* no suitable function */
58
var _dd_singleIndent = " ";
59
var _dd_indentLength = _dd_singleIndent.length;
60
var _dd_currentIndent = "";
61
var _dd_lastDumpWasOpen = false;
62
var _dd_timeStack = new Array();
63
var _dd_disableDepth = Number.MAX_VALUE;
64
var _dd_currentDepth = 0;
65
dd = function _dd (str) {
66
if (typeof str != "string") {
68
} else if (str[str.length - 1] == "{") {
70
if (_dd_currentDepth >= _dd_disableDepth)
72
if (str.indexOf("OFF") == 0)
73
_dd_disableDepth = _dd_currentDepth;
74
_dd_timeStack.push (new Date());
75
if (_dd_lastDumpWasOpen)
77
dump (_dd_pfx + _dd_currentIndent + str);
78
_dd_currentIndent += _dd_singleIndent;
79
_dd_lastDumpWasOpen = true;
80
} else if (str[0] == "}") {
81
if (--_dd_currentDepth >= _dd_disableDepth)
83
_dd_disableDepth = Number.MAX_VALUE;
84
var sufx = (new Date() - _dd_timeStack.pop()) / 1000 + " sec";
86
_dd_currentIndent.substr (0, _dd_currentIndent.length -
88
if (_dd_lastDumpWasOpen)
89
dumpln (str + " " + sufx);
91
dumpln (_dd_pfx + _dd_currentIndent + str + " " + sufx);
92
_dd_lastDumpWasOpen = false;
94
if (_dd_currentDepth >= _dd_disableDepth)
96
if (_dd_lastDumpWasOpen)
98
dumpln (_dd_pfx + _dd_currentIndent + str);
99
_dd_lastDumpWasOpen = false;
106
var jsenv = new Object();
107
jsenv.HAS_SECURITYMANAGER = ((typeof netscape == "object") &&
108
(typeof netscape.security == "object"));
109
jsenv.HAS_XPCOM = ((typeof Components == "object") &&
110
(typeof Components.classes == "object"));
111
jsenv.HAS_JAVA = (typeof java == "object");
112
jsenv.HAS_RHINO = (typeof defineClass == "function");
113
jsenv.HAS_DOCUMENT = (typeof document == "object");
115
/* Dumps an object in tree format, recurse specifiec the the number of objects
116
* to recurse, compress is a boolean that can uncompress (true) the output
117
* format, and level is the number of levels to intitialy indent (only useful
118
* internally.) A sample dumpObjectTree (o, 1) is shown below.
124
* | + nakkezzzz (object)
128
* + topic (string) 'ircclient.js:59: nothing is not defined'
129
* + getUsersLength (function) 9 lines
132
function dumpObjectTree (o, recurse, compress, level)
137
if (typeof recurse == "undefined")
139
if (typeof level == "undefined")
141
if (typeof compress == "undefined")
144
for (var i = 0; i < level; i++)
145
pfx += (compress) ? "| " : "| ";
147
var tee = (compress) ? "+ " : "+- ";
159
var sfunc = String(o[i]).split("\n");
160
if (sfunc[2] == " [native code]")
161
sfunc = "[native code]";
163
sfunc = sfunc.length + " lines";
164
s += pfx + tee + i + " (function) " + sfunc + "\n";
168
s += pfx + tee + i + " (object) " + o[i] + "\n";
171
if ((i != "parent") && (recurse))
172
s += dumpObjectTree (o[i], recurse - 1,
173
compress, level + 1);
177
if (o[i].length > 200)
178
s += pfx + tee + i + " (" + t + ") " +
179
o[i].length + " chars\n";
181
s += pfx + tee + i + " (" + t + ") '" + o[i] + "'\n";
185
s += pfx + tee + i + " (" + t + ") " + o[i] + "\n";
190
s += pfx + tee + i + " (exception) " + ex + "\n";
204
function safeHTML(str)
206
function replaceChars(ch)
223
return String(str).replace(/[<>&]/g, replaceChars);
226
function alert(msg, parent, title)
228
var PROMPT_CTRID = "@mozilla.org/embedcomp/prompt-service;1";
229
var nsIPromptService = Components.interfaces.nsIPromptService;
230
var ps = Components.classes[PROMPT_CTRID].createInstance(nsIPromptService);
235
ps.alert (parent, title, msg);
238
function confirm(msg, parent, title)
240
var PROMPT_CTRID = "@mozilla.org/embedcomp/prompt-service;1";
241
var nsIPromptService = Components.interfaces.nsIPromptService;
242
var ps = Components.classes[PROMPT_CTRID].createInstance(nsIPromptService);
247
return ps.confirm (parent, title, msg);
250
function prompt(msg, initial, parent, title)
252
var PROMPT_CTRID = "@mozilla.org/embedcomp/prompt-service;1";
253
var nsIPromptService = Components.interfaces.nsIPromptService;
254
var ps = Components.classes[PROMPT_CTRID].createInstance(nsIPromptService);
259
rv = { value: initial };
261
if (!ps.prompt (parent, title, msg, rv, null, {value: null}))
267
function getChildById (element, id)
269
var nl = element.getElementsByAttribute("id", id);
273
function openTopWin (url)
275
var window = getWindowByType ("navigator:browser");
278
var base = getBaseWindowFromWindow (window);
282
window._content.location.href = url;
287
return openDialog (getBrowserURL(), "_blank", "chrome,all,dialog=no", url);
290
function getWindowByType (windowType)
292
const MEDIATOR_CONTRACTID =
293
"@mozilla.org/appshell/window-mediator;1";
294
const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
297
Components.classes[MEDIATOR_CONTRACTID].getService(nsIWindowMediator);
299
return windowManager.getMostRecentWindow(windowType);
302
function htmlVA (attribs, href, contents)
305
attribs = {"class": "venkman-link", target: "_content"};
306
else if (attribs["class"])
307
attribs["class"] += " venkman-link";
309
attribs["class"] = "venkman-link";
311
if (typeof contents == "undefined")
313
contents = htmlSpan();
314
insertHyphenatedWord (href, contents);
317
return htmlA (attribs, href, contents);
320
function insertHyphenatedWord (longWord, containerTag)
322
var wordParts = splitLongWord (longWord, MAX_WORD_LEN);
323
containerTag.appendChild (htmlWBR());
324
for (var i = 0; i < wordParts.length; ++i)
326
containerTag.appendChild (document.createTextNode (wordParts[i]));
327
if (i != wordParts.length)
328
containerTag.appendChild (htmlWBR());
332
function insertLink (matchText, containerTag)
338
ary = matchText.match(/([.,]+)$/);
341
linkText = RegExp.leftContext;
346
linkText = matchText;
349
var ary = linkText.match (/^(\w[\w-]+):/);
352
if (!("schemes" in utils))
354
var pfx = "@mozilla.org/network/protocol;1?name=";
357
utils.schemes = new Object();
358
for (var c in Components.classes)
360
if (c.indexOf(pfx) == 0)
361
utils.schemes[c.substr(len)] = true;
365
if (!(ary[1] in utils.schemes))
367
insertHyphenatedWord(matchText, containerTag);
375
href = "http://" + linkText;
378
var anchor = htmlVA (null, href, "");
379
insertHyphenatedWord (linkText, anchor);
380
containerTag.appendChild (anchor);
382
insertHyphenatedWord (trailing, containerTag);
386
function insertQuote (matchText, containerTag, msgtype)
388
if (msgtype[0] == "#")
390
containerTag.appendChild(document.createTextNode(matchText));
394
if (matchText == "``")
395
containerTag.appendChild(document.createTextNode("\u201c"));
397
containerTag.appendChild(document.createTextNode("\u201d"));
400
/* length should be an even number >= 6 */
401
function abbreviateWord (str, length)
403
if (str.length <= length || length < 6)
406
var left = str.substr (0, (length / 2) - 1);
407
var right = str.substr (str.length - (length / 2) + 1);
409
return left + "..." + right;
412
function toBool (val)
427
return (val.search(/true|on|yes|1/i) != -1);
433
/* some of the drag and drop code has an annoying appetite for exceptions. any
434
* exception raised during a dnd operation causes the operation to fail silently.
435
* passing the function through one of these adapters lets you use "return
436
* false on planned failure" symantics, and dumps any exceptions caught
438
function Prophylactic (parentObj, fun)
447
rv = fun.apply (parentObj, arguments);
451
dd ("Prophylactic caught an exception:\n" +
464
function argumentsAsArray (args, start)
466
if (typeof start == "undefined")
469
if (start >= args.length)
472
var rv = new Array();
474
for (var i = start; i < args.length; ++i)
480
function splitLongWord (str, pos)
482
if (str.length <= pos)
485
var ary = new Array();
488
while (right.length > pos)
490
/* search for a nice place to break the word, fuzzfactor of +/-5,
491
* centered around |pos| */
493
right.substring(pos - 5, pos + 5).search(/[^A-Za-z0-9]/);
495
splitPos = (splitPos != -1) ? pos - 4 + splitPos : pos;
496
ary.push(right.substr (0, splitPos));
497
right = right.substr (splitPos);
505
function wrapText (str, width)
508
while (str.length > width)
510
rv += str.substr(0, width) + "\n";
511
str = str.substr(width);
516
function wordCap (str)
521
return str[0].toUpperCase() + str.substr(1);
525
* Clones an existing object (Only the enumerable properties
526
* of course.) use as a function..
527
* var c = Clone (obj);
528
* or a constructor...
529
* var c = new Clone (obj);
533
var robj = new Object();
542
function getXULWindowFromWindow (win)
545
//dd ("getXULWindowFromWindow: before: getInterface is " + win.getInterface);
548
var requestor = win.QueryInterface(nsIInterfaceRequestor);
549
var nav = requestor.getInterface(nsIWebNavigation);
550
var dsti = nav.QueryInterface(nsIDocShellTreeItem);
551
var owner = dsti.treeOwner;
552
requestor = owner.QueryInterface(nsIInterfaceRequestor);
553
rv = requestor.getInterface(nsIXULWindow);
558
//dd ("not a nsIXULWindow: " + formatException(ex));
559
/* ignore no-interface exception */
562
//dd ("getXULWindowFromWindow: after: getInterface is " + win.getInterface);
566
function getBaseWindowFromWindow (win)
569
//dd ("getBaseWindowFromWindow: before: getInterface is " + win.getInterface);
572
var requestor = win.QueryInterface(nsIInterfaceRequestor);
573
var nav = requestor.getInterface(nsIWebNavigation);
574
var dsti = nav.QueryInterface(nsIDocShellTreeItem);
575
var owner = dsti.treeOwner;
576
requestor = owner.QueryInterface(nsIInterfaceRequestor);
577
rv = requestor.getInterface(nsIBaseWindow);
582
//dd ("not a nsIXULWindow: " + formatException(ex));
583
/* ignore no-interface exception */
586
//dd ("getBaseWindowFromWindow: after: getInterface is " + win.getInterface);
590
function getSpecialDirectory(name)
592
if (!("directoryService" in utils))
594
const DS_CTR = "@mozilla.org/file/directory_service;1";
595
const nsIProperties = Components.interfaces.nsIProperties;
597
utils.directoryService =
598
Components.classes[DS_CTR].getService(nsIProperties);
601
return utils.directoryService.get(name, Components.interfaces.nsIFile);
604
function getPathFromURL (url)
606
var ary = url.match(/^(.*\/)([^\/?#]+)(\?|#|$)/);
613
function getFileFromPath (path)
615
var ary = path.match(/\/([^\/?#;]+)(\?|#|$|;)/);
622
function getURLSpecFromFile (file)
627
const IOS_CTRID = "@mozilla.org/network/io-service;1";
628
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
630
const nsIIOService = Components.interfaces.nsIIOService;
631
const nsILocalFile = Components.interfaces.nsILocalFile;
633
if (typeof file == "string")
636
Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
637
fileObj.initWithPath(file);
641
var service = Components.classes[IOS_CTRID].getService(nsIIOService);
642
/* In sept 2002, bug 166792 moved this method to the nsIFileProtocolHandler
643
* interface, but we need to support older versions too. */
644
if ("getURLSpecFromFile" in service)
645
return service.getURLSpecFromFile(file);
647
var nsIFileProtocolHandler = Components.interfaces.nsIFileProtocolHandler;
648
var fileHandler = service.getProtocolHandler("file");
649
fileHandler = fileHandler.QueryInterface(nsIFileProtocolHandler);
650
return fileHandler.getURLSpecFromFile(file);
653
function getCommonPfx (list)
658
for (var i = 1; i < l; i++)
660
for (var c = 0; c < pfx.length; c++)
661
if (pfx[c] != list[i][c])
662
pfx = pfx.substr (0, c);
669
function renameProperty (obj, oldname, newname)
672
if (oldname == newname)
675
obj[newname] = obj[oldname];
680
function newObject(contractID, iface)
682
if (!jsenv.HAS_XPCOM)
685
var obj = Components.classes[contractID].createInstance();
688
switch (typeof iface)
691
rv = obj.QueryInterface(Components.interfaces[iface]);
695
rv = obj.QueryInterface[iface];
709
var rv = new Array();
718
function parseSections (str, sections)
720
var rv = new Object();
723
for (var s in sections)
730
var i = str.search(sections[s]);
733
rv[currentSection] = str.substr(0, i);
735
str = RegExp.rightContext;
736
str = str.replace(/^(\n|\r|\r\n)/, "");
741
rv[currentSection] = str;
750
function replaceStrings (str, obj)
755
str = str.replace(RegExp(p, "g"), obj[p]);
759
function stringTrim (s)
763
s = s.replace (/^\s+/, "");
764
return s.replace (/\s+$/, "");
767
function formatDateOffset (seconds, format)
769
seconds = Math.floor(seconds);
770
var minutes = Math.floor(seconds / 60);
771
seconds = seconds % 60;
772
var hours = Math.floor(minutes / 60);
773
minutes = minutes % 60;
774
var days = Math.floor(hours / 24);
779
var ary = new Array();
781
ary.push (days + " days");
783
ary.push (hours + " hours");
785
ary.push (minutes + " minutes");
787
ary.push (seconds + " seconds");
789
format = ary.join(", ");
793
format = format.replace ("%d", days);
794
format = format.replace ("%h", hours);
795
format = format.replace ("%m", minutes);
796
format = format.replace ("%s", seconds);
802
function arrayHasElementAt(ary, i)
804
return typeof ary[i] != "undefined";
807
function arraySpeak (ary, single, plural)
823
rv = ary[0] + " and " + ary[1];
829
for (var i = 0; i < ary.length - 1; ++i)
831
rv += "and " + ary[ary.length - 1];
841
function arrayOrFlag (ary, i, flag)
849
function arrayAndFlag (ary, i, flag)
857
function arrayContains (ary, elem)
859
return (arrayIndexOf (ary, elem) != -1);
862
function arrayIndexOf (ary, elem, start)
867
var len = ary.length;
869
if (typeof start == "undefined")
872
for (var i = start; i < len; ++i)
881
function arrayInsertAt (ary, i, o)
884
ary.splice (i, 0, o);
888
function arrayRemoveAt (ary, i)
895
function getRandomElement (ary)
897
var i = Math.floor (Math.random() * ary.length)
898
if (i == ary.length) i = 0;
904
function zeroPad (num, decimals)
906
var rv = String(num);
908
for (var i = 0; i < decimals - len; ++i)
914
function leftPadString (str, num, ch)
918
for (var i = len; i < num; ++i)
924
function roundTo (num, prec)
926
return Math.round(num * Math.pow (10, prec)) / Math.pow (10, prec);
929
function randomRange (min, max)
932
if (typeof min == "undefined")
935
if (typeof max == "undefined")
938
var rv = (Math.floor(Math.round((Math.random() * (max - min)) + min )));
944
function getStackTrace ()
947
if (!jsenv.HAS_XPCOM)
948
return "No stack trace available.";
950
var frame = Components.stack.caller;
955
var name = frame.name ? frame.name : "[anonymous]";
956
str += "\n" + name + "@" + frame.lineNumber;
957
frame = frame.caller;
964
function getInterfaces (cls)
966
if (!jsenv.HAS_XPCOM)
969
var rv = new Object();
972
for (var i in Components.interfaces)
976
var ifc = Components.interfaces[i];
977
cls.QueryInterface(ifc);
990
function makeExpression (items)
992
function escapeItem (item, first)
995
if (item.match(/^[0-9]+$/i))
996
return "[" + item + "]";
997
// Words/other items that don't need quoting.
998
if (item.match(/^[a-z_][a-z0-9_]+$/i))
999
return (!first ? "." : "") + item;
1000
// Quote everything else.
1001
return "[" + item.quote() + "]";
1004
var expression = escapeItem(items[0], true);
1006
for (var i = 1; i < items.length; i++)
1007
expression += escapeItem(items[i], false);
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3
* ***** BEGIN LICENSE BLOCK *****
4
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
* The contents of this file are subject to the Mozilla Public License Version
7
* 1.1 (the "License"); you may not use this file except in compliance with
8
* the License. You may obtain a copy of the License at
9
* http://www.mozilla.org/MPL/
11
* Software distributed under the License is distributed on an "AS IS" basis,
12
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
* for the specific language governing rights and limitations under the
16
* The Original Code is mozilla.org code.
18
* The Initial Developer of the Original Code is
19
* New Dimensions Consulting, Inc.
20
* Portions created by the Initial Developer are Copyright (C) 1999
21
* the Initial Developer. All Rights Reserved.
24
* Robert Ginda, rginda@ndcico.com, original author
26
* Alternatively, the contents of this file may be used under the terms of
27
* either the GNU General Public License Version 2 or later (the "GPL"), or
28
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29
* in which case the provisions of the GPL or the LGPL are applicable instead
30
* of those above. If you wish to allow use of your version of this file only
31
* under the terms of either the GPL or the LGPL, and not to allow others to
32
* use your version of this file under the terms of the MPL, indicate your
33
* decision by deleting the provisions above and replace them with the notice
34
* and other provisions required by the GPL or the LGPL. If you do not delete
35
* the provisions above, a recipient may use your version of this file under
36
* the terms of any one of the MPL, the GPL or the LGPL.
38
* ***** END LICENSE BLOCK ***** */
43
const nsIBaseWindow = Components.interfaces.nsIBaseWindow;
44
const nsIXULWindow = Components.interfaces.nsIXULWindow;
45
const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor;
46
const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
47
const nsIDocShellTreeItem = Components.interfaces.nsIDocShellTreeItem;
49
var utils = new Object();
51
if (typeof document == "undefined") /* in xpcshell */
57
if (typeof dump == "function")
58
dumpln = function (str) {dump (str + "\n");}
59
else if (jsenv.HAS_RHINO)
61
dumpln = function (str) {
62
var out = java.lang.System.out;
63
out.println(str); out.flush();
67
dumpln = function () {} /* no suitable function */
72
var _dd_singleIndent = " ";
73
var _dd_indentLength = _dd_singleIndent.length;
74
var _dd_currentIndent = "";
75
var _dd_lastDumpWasOpen = false;
76
var _dd_timeStack = new Array();
77
var _dd_disableDepth = Number.MAX_VALUE;
78
var _dd_currentDepth = 0;
79
dd = function _dd (str) {
80
if (typeof str != "string") {
82
} else if (str[str.length - 1] == "{") {
84
if (_dd_currentDepth >= _dd_disableDepth)
86
if (str.indexOf("OFF") == 0)
87
_dd_disableDepth = _dd_currentDepth;
88
_dd_timeStack.push (new Date());
89
if (_dd_lastDumpWasOpen)
91
dump (_dd_pfx + _dd_currentIndent + str);
92
_dd_currentIndent += _dd_singleIndent;
93
_dd_lastDumpWasOpen = true;
94
} else if (str[0] == "}") {
95
if (--_dd_currentDepth >= _dd_disableDepth)
97
_dd_disableDepth = Number.MAX_VALUE;
98
var sufx = (new Date() - _dd_timeStack.pop()) / 1000 + " sec";
100
_dd_currentIndent.substr (0, _dd_currentIndent.length -
102
if (_dd_lastDumpWasOpen)
103
dumpln (str + " " + sufx);
105
dumpln (_dd_pfx + _dd_currentIndent + str + " " + sufx);
106
_dd_lastDumpWasOpen = false;
108
if (_dd_currentDepth >= _dd_disableDepth)
110
if (_dd_lastDumpWasOpen)
112
dumpln (_dd_pfx + _dd_currentIndent + str);
113
_dd_lastDumpWasOpen = false;
120
var jsenv = new Object();
121
jsenv.HAS_SECURITYMANAGER = ((typeof netscape == "object") &&
122
(typeof netscape.security == "object"));
123
jsenv.HAS_XPCOM = ((typeof Components == "object") &&
124
(typeof Components.classes == "object"));
125
jsenv.HAS_JAVA = (typeof java == "object");
126
jsenv.HAS_RHINO = (typeof defineClass == "function");
127
jsenv.HAS_DOCUMENT = (typeof document == "object");
129
/* Dumps an object in tree format, recurse specifiec the the number of objects
130
* to recurse, compress is a boolean that can uncompress (true) the output
131
* format, and level is the number of levels to intitialy indent (only useful
132
* internally.) A sample dumpObjectTree (o, 1) is shown below.
138
* | + nakkezzzz (object)
142
* + topic (string) 'ircclient.js:59: nothing is not defined'
143
* + getUsersLength (function) 9 lines
146
function dumpObjectTree (o, recurse, compress, level)
151
if (typeof recurse == "undefined")
153
if (typeof level == "undefined")
155
if (typeof compress == "undefined")
158
for (var i = 0; i < level; i++)
159
pfx += (compress) ? "| " : "| ";
161
var tee = (compress) ? "+ " : "+- ";
173
var sfunc = String(o[i]).split("\n");
174
if (sfunc[2] == " [native code]")
175
sfunc = "[native code]";
177
sfunc = sfunc.length + " lines";
178
s += pfx + tee + i + " (function) " + sfunc + "\n";
182
s += pfx + tee + i + " (object) " + o[i] + "\n";
185
if ((i != "parent") && (recurse))
186
s += dumpObjectTree (o[i], recurse - 1,
187
compress, level + 1);
191
if (o[i].length > 200)
192
s += pfx + tee + i + " (" + t + ") " +
193
o[i].length + " chars\n";
195
s += pfx + tee + i + " (" + t + ") '" + o[i] + "'\n";
199
s += pfx + tee + i + " (" + t + ") " + o[i] + "\n";
204
s += pfx + tee + i + " (exception) " + ex + "\n";
218
function safeHTML(str)
220
function replaceChars(ch)
237
return String(str).replace(/[<>&]/g, replaceChars);
240
function alert(msg, parent, title)
242
var PROMPT_CTRID = "@mozilla.org/embedcomp/prompt-service;1";
243
var nsIPromptService = Components.interfaces.nsIPromptService;
244
var ps = Components.classes[PROMPT_CTRID].getService(nsIPromptService);
249
ps.alert (parent, title, msg);
252
function confirm(msg, parent, title)
254
var PROMPT_CTRID = "@mozilla.org/embedcomp/prompt-service;1";
255
var nsIPromptService = Components.interfaces.nsIPromptService;
256
var ps = Components.classes[PROMPT_CTRID].getService(nsIPromptService);
261
return ps.confirm (parent, title, msg);
264
function prompt(msg, initial, parent, title)
266
var PROMPT_CTRID = "@mozilla.org/embedcomp/prompt-service;1";
267
var nsIPromptService = Components.interfaces.nsIPromptService;
268
var ps = Components.classes[PROMPT_CTRID].getService(nsIPromptService);
273
rv = { value: initial };
275
if (!ps.prompt (parent, title, msg, rv, null, {value: null}))
281
function getChildById (element, id)
283
var nl = element.getElementsByAttribute("id", id);
287
function openTopWin (url)
289
var window = getWindowByType ("navigator:browser");
292
var base = getBaseWindowFromWindow (window);
296
window._content.location.href = url;
301
return openDialog (getBrowserURL(), "_blank", "chrome,all,dialog=no", url);
304
function getWindowByType (windowType)
306
const MEDIATOR_CONTRACTID =
307
"@mozilla.org/appshell/window-mediator;1";
308
const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
311
Components.classes[MEDIATOR_CONTRACTID].getService(nsIWindowMediator);
313
return windowManager.getMostRecentWindow(windowType);
316
function htmlVA (attribs, href, contents)
319
attribs = {"class": "venkman-link", target: "_content"};
320
else if (attribs["class"])
321
attribs["class"] += " venkman-link";
323
attribs["class"] = "venkman-link";
325
if (typeof contents == "undefined")
327
contents = htmlSpan();
328
insertHyphenatedWord (href, contents);
331
return htmlA (attribs, href, contents);
334
function insertHyphenatedWord (longWord, containerTag)
336
var wordParts = splitLongWord (longWord, MAX_WORD_LEN);
337
containerTag.appendChild (htmlWBR());
338
for (var i = 0; i < wordParts.length; ++i)
340
containerTag.appendChild (document.createTextNode (wordParts[i]));
341
if (i != wordParts.length)
342
containerTag.appendChild (htmlWBR());
346
function insertLink (matchText, containerTag)
352
ary = matchText.match(/([.,]+)$/);
355
linkText = RegExp.leftContext;
360
linkText = matchText;
363
var ary = linkText.match (/^(\w[\w-]+):/);
366
if (!("schemes" in utils))
368
var pfx = "@mozilla.org/network/protocol;1?name=";
371
utils.schemes = new Object();
372
for (var c in Components.classes)
374
if (c.indexOf(pfx) == 0)
375
utils.schemes[c.substr(len)] = true;
379
if (!(ary[1] in utils.schemes))
381
insertHyphenatedWord(matchText, containerTag);
389
href = "http://" + linkText;
392
var anchor = htmlVA (null, href, "");
393
insertHyphenatedWord (linkText, anchor);
394
containerTag.appendChild (anchor);
396
insertHyphenatedWord (trailing, containerTag);
400
function insertQuote (matchText, containerTag, msgtype)
402
if (msgtype[0] == "#")
404
containerTag.appendChild(document.createTextNode(matchText));
408
if (matchText == "``")
409
containerTag.appendChild(document.createTextNode("\u201c"));
411
containerTag.appendChild(document.createTextNode("\u201d"));
414
/* length should be an even number >= 6 */
415
function abbreviateWord (str, length)
417
if (str.length <= length || length < 6)
420
var left = str.substr (0, (length / 2) - 1);
421
var right = str.substr (str.length - (length / 2) + 1);
423
return left + "..." + right;
426
function toBool (val)
441
return (val.search(/true|on|yes|1/i) != -1);
447
/* some of the drag and drop code has an annoying appetite for exceptions. any
448
* exception raised during a dnd operation causes the operation to fail silently.
449
* passing the function through one of these adapters lets you use "return
450
* false on planned failure" symantics, and dumps any exceptions caught
452
function Prophylactic (parentObj, fun)
461
rv = fun.apply (parentObj, arguments);
465
dd ("Prophylactic caught an exception:\n" +
478
function argumentsAsArray (args, start)
480
if (typeof start == "undefined")
483
if (start >= args.length)
486
var rv = new Array();
488
for (var i = start; i < args.length; ++i)
494
function splitLongWord (str, pos)
496
if (str.length <= pos)
499
var ary = new Array();
502
while (right.length > pos)
504
/* search for a nice place to break the word, fuzzfactor of +/-5,
505
* centered around |pos| */
507
right.substring(pos - 5, pos + 5).search(/[^A-Za-z0-9]/);
509
splitPos = (splitPos != -1) ? pos - 4 + splitPos : pos;
510
ary.push(right.substr (0, splitPos));
511
right = right.substr (splitPos);
519
function wrapText (str, width)
522
while (str.length > width)
524
rv += str.substr(0, width) + "\n";
525
str = str.substr(width);
530
function wordCap (str)
535
return str[0].toUpperCase() + str.substr(1);
539
* Clones an existing object (Only the enumerable properties
540
* of course.) use as a function..
541
* var c = Clone (obj);
542
* or a constructor...
543
* var c = new Clone (obj);
547
var robj = new Object();
556
function getXULWindowFromWindow (win)
559
//dd ("getXULWindowFromWindow: before: getInterface is " + win.getInterface);
562
var requestor = win.QueryInterface(nsIInterfaceRequestor);
563
var nav = requestor.getInterface(nsIWebNavigation);
564
var dsti = nav.QueryInterface(nsIDocShellTreeItem);
565
var owner = dsti.treeOwner;
566
requestor = owner.QueryInterface(nsIInterfaceRequestor);
567
rv = requestor.getInterface(nsIXULWindow);
572
//dd ("not a nsIXULWindow: " + formatException(ex));
573
/* ignore no-interface exception */
576
//dd ("getXULWindowFromWindow: after: getInterface is " + win.getInterface);
580
function getBaseWindowFromWindow (win)
583
//dd ("getBaseWindowFromWindow: before: getInterface is " + win.getInterface);
586
var requestor = win.QueryInterface(nsIInterfaceRequestor);
587
var nav = requestor.getInterface(nsIWebNavigation);
588
var dsti = nav.QueryInterface(nsIDocShellTreeItem);
589
var owner = dsti.treeOwner;
590
requestor = owner.QueryInterface(nsIInterfaceRequestor);
591
rv = requestor.getInterface(nsIBaseWindow);
596
//dd ("not a nsIXULWindow: " + formatException(ex));
597
/* ignore no-interface exception */
600
//dd ("getBaseWindowFromWindow: after: getInterface is " + win.getInterface);
604
function getSpecialDirectory(name)
606
if (!("directoryService" in utils))
608
const DS_CTR = "@mozilla.org/file/directory_service;1";
609
const nsIProperties = Components.interfaces.nsIProperties;
611
utils.directoryService =
612
Components.classes[DS_CTR].getService(nsIProperties);
615
return utils.directoryService.get(name, Components.interfaces.nsIFile);
618
function getPathFromURL (url)
620
var ary = url.match(/^(.*\/)([^\/?#]+)(\?|#|$)/);
627
function getFileFromPath (path)
629
var ary = path.match(/\/([^\/?#;]+)(\?|#|$|;)/);
636
function getURLSpecFromFile (file)
641
const IOS_CTRID = "@mozilla.org/network/io-service;1";
642
const LOCALFILE_CTRID = "@mozilla.org/file/local;1";
644
const nsIIOService = Components.interfaces.nsIIOService;
645
const nsILocalFile = Components.interfaces.nsILocalFile;
647
if (typeof file == "string")
650
Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
651
fileObj.initWithPath(file);
655
var service = Components.classes[IOS_CTRID].getService(nsIIOService);
656
/* In sept 2002, bug 166792 moved this method to the nsIFileProtocolHandler
657
* interface, but we need to support older versions too. */
658
if ("getURLSpecFromFile" in service)
659
return service.getURLSpecFromFile(file);
661
var nsIFileProtocolHandler = Components.interfaces.nsIFileProtocolHandler;
662
var fileHandler = service.getProtocolHandler("file");
663
fileHandler = fileHandler.QueryInterface(nsIFileProtocolHandler);
664
return fileHandler.getURLSpecFromFile(file);
667
function getCommonPfx (list)
672
for (var i = 1; i < l; i++)
674
for (var c = 0; c < pfx.length; c++)
675
if (pfx[c] != list[i][c])
676
pfx = pfx.substr (0, c);
683
function renameProperty (obj, oldname, newname)
686
if (oldname == newname)
689
obj[newname] = obj[oldname];
694
function newObject(contractID, iface)
696
if (!jsenv.HAS_XPCOM)
699
var obj = Components.classes[contractID].createInstance();
702
switch (typeof iface)
705
rv = obj.QueryInterface(Components.interfaces[iface]);
709
rv = obj.QueryInterface[iface];
723
var rv = new Array();
732
function parseSections (str, sections)
734
var rv = new Object();
737
for (var s in sections)
744
var i = str.search(sections[s]);
747
rv[currentSection] = str.substr(0, i);
749
str = RegExp.rightContext;
750
str = str.replace(/^(\n|\r|\r\n)/, "");
755
rv[currentSection] = str;
764
function replaceStrings (str, obj)
769
str = str.replace(RegExp(p, "g"), obj[p]);
773
function stringTrim (s)
777
s = s.replace (/^\s+/, "");
778
return s.replace (/\s+$/, "");
781
function formatDateOffset (seconds, format)
783
seconds = Math.floor(seconds);
784
var minutes = Math.floor(seconds / 60);
785
seconds = seconds % 60;
786
var hours = Math.floor(minutes / 60);
787
minutes = minutes % 60;
788
var days = Math.floor(hours / 24);
793
var ary = new Array();
795
ary.push (days + " days");
797
ary.push (hours + " hours");
799
ary.push (minutes + " minutes");
801
ary.push (seconds + " seconds");
803
format = ary.join(", ");
807
format = format.replace ("%d", days);
808
format = format.replace ("%h", hours);
809
format = format.replace ("%m", minutes);
810
format = format.replace ("%s", seconds);
816
function arrayHasElementAt(ary, i)
818
return typeof ary[i] != "undefined";
821
function arraySpeak (ary, single, plural)
837
rv = ary[0] + " and " + ary[1];
843
for (var i = 0; i < ary.length - 1; ++i)
845
rv += "and " + ary[ary.length - 1];
855
function arrayOrFlag (ary, i, flag)
863
function arrayAndFlag (ary, i, flag)
871
function arrayContains (ary, elem)
873
return (arrayIndexOf (ary, elem) != -1);
876
function arrayIndexOf (ary, elem, start)
881
var len = ary.length;
883
if (typeof start == "undefined")
886
for (var i = start; i < len; ++i)
895
function arrayInsertAt (ary, i, o)
898
ary.splice (i, 0, o);
902
function arrayRemoveAt (ary, i)
909
function getRandomElement (ary)
911
var i = Math.floor (Math.random() * ary.length)
912
if (i == ary.length) i = 0;
918
function zeroPad (num, decimals)
920
var rv = String(num);
922
for (var i = 0; i < decimals - len; ++i)
928
function leftPadString (str, num, ch)
932
for (var i = len; i < num; ++i)
938
function roundTo (num, prec)
940
return Math.round(num * Math.pow (10, prec)) / Math.pow (10, prec);
943
function randomRange (min, max)
946
if (typeof min == "undefined")
949
if (typeof max == "undefined")
952
var rv = (Math.floor(Math.round((Math.random() * (max - min)) + min )));
958
function getStackTrace ()
961
if (!jsenv.HAS_XPCOM)
962
return "No stack trace available.";
964
var frame = Components.stack.caller;
969
var name = frame.name ? frame.name : "[anonymous]";
970
str += "\n" + name + "@" + frame.lineNumber;
971
frame = frame.caller;
978
function getInterfaces (cls)
980
if (!jsenv.HAS_XPCOM)
983
var rv = new Object();
986
for (var i in Components.interfaces)
990
var ifc = Components.interfaces[i];
991
cls.QueryInterface(ifc);
1004
function makeExpression (items)
1006
function escapeItem (item, first)
1009
if (item.match(/^[0-9]+$/i))
1010
return "[" + item + "]";
1011
// Words/other items that don't need quoting.
1012
if (item.match(/^[a-z_][a-z0-9_]+$/i))
1013
return (!first ? "." : "") + item;
1014
// Quote everything else.
1015
return "[" + item.quote() + "]";
1018
var expression = escapeItem(items[0], true);
1020
for (var i = 1; i < items.length; i++)
1021
expression += escapeItem(items[i], false);