]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/components/venkman-service.js
Wrap upgrade script for "pretty-print XML" function
[working/Evergreen.git] / Open-ILS / xul / staff_client / components / venkman-service.js
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * ***** BEGIN LICENSE BLOCK *****
4  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5  *
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/
10  *
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
14  * License.
15  *
16  * The Original Code is The JavaScript Debugger.
17  *
18  * The Initial Developer of the Original Code is
19  * Netscape Communications Corporation.
20  * Portions created by the Initial Developer are Copyright (C) 1998
21  * the Initial Developer. All Rights Reserved.
22  *
23  * Contributor(s):
24  *   Robert Ginda, <rginda@netscape.com>, original author
25  *
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.
37  *
38  * ***** END LICENSE BLOCK ***** */
39
40 /* components defined in this file */
41 const CLINE_SERVICE_CTRID =
42     "@mozilla.org/commandlinehandler/general-startup;1?type=venkman";
43 const CLINE_SERVICE_CID =
44     Components.ID("{18269616-1dd2-11b2-afa8-b612439bda27}");
45 const JSDPROT_HANDLER_CTRID =
46     "@mozilla.org/network/protocol;1?name=x-jsd";
47 const JSDPROT_HANDLER_CID =
48     Components.ID("{12ec790d-304e-4525-89a9-3e723d489d14}");
49 const JSDCNT_HANDLER_CTRID =
50     "@mozilla.org/uriloader/content-handler;1?type=x-application-jsd";
51 const JSDCNT_HANDLER_CID =
52     Components.ID("{306670f0-47bb-466b-b53b-613235623bbd}");
53
54 /* components used by this file */
55 const CATMAN_CTRID = "@mozilla.org/categorymanager;1";
56 const STRING_STREAM_CTRID = "@mozilla.org/io/string-input-stream;1";
57 const MEDIATOR_CTRID =
58     "@mozilla.org/appshell/window-mediator;1";
59 const ASS_CONTRACTID =
60     "@mozilla.org/appshell/appShellService;1";
61 const SIMPLEURI_CTRID = "@mozilla.org/network/simple-uri;1";
62
63 const nsIWindowMediator    = Components.interfaces.nsIWindowMediator;
64 const nsIAppShellService   = Components.interfaces.nsIAppShellService;
65 const nsICmdLineHandler    = Components.interfaces.nsICmdLineHandler;
66 const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar;
67 const nsICategoryManager   = Components.interfaces.nsICategoryManager;
68 const nsIContentHandler    = Components.interfaces.nsIContentHandler;
69 const nsIProtocolHandler   = Components.interfaces.nsIProtocolHandler;
70 const nsIURI               = Components.interfaces.nsIURI;
71 const nsIURL               = Components.interfaces.nsIURL;
72 const nsIStringInputStream = Components.interfaces.nsIStringInputStream;
73 const nsIChannel           = Components.interfaces.nsIChannel;
74 const nsIRequest           = Components.interfaces.nsIRequest;
75 const nsIProgressEventSink = Components.interfaces.nsIProgressEventSink;
76 const nsISupports          = Components.interfaces.nsISupports;
77 const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler;
78 const nsICommandLine        = Components.interfaces.nsICommandLine;
79
80 function findDebuggerWindow ()
81 {
82     var windowManager =
83         Components.classes[MEDIATOR_CTRID].getService(nsIWindowMediator);
84     return windowManager.getMostRecentWindow("mozapp:venkman");
85 }
86
87 function openDebuggerWindow(args)
88 {
89     var ass = Components.classes[ASS_CONTRACTID].getService(nsIAppShellService);
90     var window = ass.hiddenDOMWindow;
91     window.openDialog("chrome://venkman/content/venkman.xul", "_blank",
92                       "chrome,menubar,toolbar,status,resizable,dialog=no",
93                       args);
94 }
95
96 function safeHTML(str)
97 {
98     function replaceChars(ch)
99     {
100         switch (ch)
101         {
102             case "<":
103                 return "&lt;";
104             
105             case ">":
106                 return "&gt;";
107                     
108             case "&":
109                 return "&amp;";
110                     
111             case "'":
112                 return "&#39;";
113                     
114             case '"':
115                 return "&quot;";
116         }
117
118         return "?";
119     };
120         
121     return String(str).replace(/[<>&"']/g, replaceChars);
122 }
123
124 /* Command Line handler service */
125 function CLineService()
126 {}
127
128 /* nsISupports */
129 CLineService.prototype.QueryInterface =
130 function handler_QI(iid)
131 {
132     if (iid.equals(nsISupports) || 
133         (nsICommandLineHandler && iid.equals(nsICommandLineHandler)) ||
134         (nsICmdLineHandler && iid.equals(nsICmdLineHandler)))
135     {
136         return this;
137     }
138
139     throw Components.results.NS_ERROR_NO_INTERFACE;
140 }
141
142 /* nsICmdLineHandler */
143 CLineService.prototype.commandLineArgument = "-venkman";
144 CLineService.prototype.prefNameForStartup = "general.startup.venkman";
145 CLineService.prototype.chromeUrlForTask = "chrome://venkman/content";
146 CLineService.prototype.helpText = "Start with JavaScript Debugger (Venkman).";
147 CLineService.prototype.handlesArgs = false;
148 CLineService.prototype.defaultArgs = "";
149 CLineService.prototype.openWindowWithArgs = false;
150
151 /* nsICommandLineHandler */
152
153 CLineService.prototype.handle =
154 function handler_handle(cmdLine)
155 {
156     try
157     {
158         if (cmdLine.handleFlag("venkman", false))
159             openDebuggerWindow(null);
160     }
161     catch (e)
162     {
163         debug(e);
164     }
165 }
166
167 CLineService.prototype.helpInfo =
168  "  -venkman         Start with JavaScript debugger (Venkman).\n"
169
170 /* factory for command line handler service (CLineService) */
171 var CLineFactory = new Object();
172
173 CLineFactory.createInstance =
174 function clf_create (outer, iid) {
175     if (outer != null)
176         throw Components.results.NS_ERROR_NO_AGGREGATION;
177
178     return new CLineService().QueryInterface(iid);
179 }
180
181 /* x-jsd: protocol handler */
182
183 const JSD_DEFAULT_PORT = 2206; /* Dana's apartment number. */
184
185 /* protocol handler factory object */
186 var JSDProtocolHandlerFactory = new Object();
187
188 JSDProtocolHandlerFactory.createInstance =
189 function jsdhf_create (outer, iid) {
190     if (outer != null)
191         throw Components.results.NS_ERROR_NO_AGGREGATION;
192
193     if (!iid.equals(nsIProtocolHandler) && !iid.equals(nsISupports))
194         throw Components.results.NS_ERROR_INVALID_ARG;
195
196     return new JSDProtocolHandler();
197 }
198
199 function JSDURI (spec, charset)
200 {
201     this.spec = this.prePath = spec;
202     this.charset = this.originCharset = charset;
203 }
204
205 JSDURI.prototype.QueryInterface =
206 function jsdch_qi (iid)
207 {
208     if (!iid.equals(nsIURI) && !iid.equals(nsIURL) &&
209         !iid.equals(nsISupports))
210         throw Components.results.NS_ERROR_NO_INTERFACE;
211
212     return this;
213 }
214
215 JSDURI.prototype.scheme = "x-jsd";
216
217 JSDURI.prototype.fileBaseName =
218 JSDURI.prototype.fileExtension =
219 JSDURI.prototype.filePath  =
220 JSDURI.prototype.param     =
221 JSDURI.prototype.query     =
222 JSDURI.prototype.ref       =
223 JSDURI.prototype.directory =
224 JSDURI.prototype.fileName  =
225 JSDURI.prototype.username  =
226 JSDURI.prototype.password  =
227 JSDURI.prototype.hostPort  =
228 JSDURI.prototype.path      =
229 JSDURI.prototype.asciiHost =
230 JSDURI.prototype.userPass  = "";
231
232 JSDURI.prototype.port = JSD_DEFAULT_PORT;
233
234 JSDURI.prototype.schemeIs =
235 function jsduri_schemeis (scheme)
236 {
237     return scheme.toLowerCase() == "x-jsd";
238 }
239
240 JSDURI.prototype.getCommonBaseSpec =
241 function jsduri_commonbase (uri)
242 {
243     return "x-jsd:";
244 }
245
246 JSDURI.prototype.getRelativeSpec =
247 function jsduri_commonbase (uri)
248 {
249     return uri;
250 }
251
252 JSDURI.prototype.equals =
253 function jsduri_equals (uri)
254 {
255     return uri.spec == this.spec;
256 }
257
258 JSDURI.prototype.clone =
259 function jsduri_clone ()
260 {
261     return new JSDURI (this.spec);
262 }
263
264 JSDURI.prototype.resolve =
265 function jsduri_resolve(path)
266 {
267     //dump ("resolve " + path + " from " + this.spec + "\n");
268     if (path[0] == "#")
269         return this.spec + path;
270     
271     return path;
272 }
273
274 function JSDProtocolHandler()
275 {
276     /* nothing here */
277 }
278
279 JSDProtocolHandler.prototype.scheme = "x-jsd";
280 JSDProtocolHandler.prototype.defaultPort = JSD_DEFAULT_PORT;
281 JSDProtocolHandler.prototype.protocolFlags = nsIProtocolHandler.URI_NORELATIVE |
282                                              nsIProtocolHandler.URI_NOAUTH;
283 if ("URI_DANGEROUS_TO_LOAD" in nsIProtocolHandler) {
284   JSDProtocolHandler.prototype.protocolFlags |=
285       nsIProtocolHandler.URI_DANGEROUS_TO_LOAD;
286 }
287
288 JSDProtocolHandler.prototype.allowPort =
289 function jsdph_allowport (aPort, aScheme)
290 {
291     return false;
292 }
293
294 JSDProtocolHandler.prototype.newURI =
295 function jsdph_newuri (spec, charset, baseURI)
296 {
297     var clazz = Components.classes[SIMPLEURI_CTRID];
298     var uri = clazz.createInstance(nsIURI);
299     uri.spec = spec;
300     return uri;
301 }
302
303 JSDProtocolHandler.prototype.newChannel =
304 function jsdph_newchannel (uri)
305 {
306     return new JSDChannel (uri);
307 }
308
309 function JSDChannel (uri)
310 {
311     this.URI = uri;
312     this.originalURI = uri;
313     this._isPending = false;
314     var clazz = Components.classes[STRING_STREAM_CTRID];
315     this.stringStream = clazz.createInstance(nsIStringInputStream);
316 }
317
318 JSDChannel.prototype.QueryInterface =
319 function jsdch_qi (iid)
320 {
321
322     if (!iid.equals(nsIChannel) && !iid.equals(nsIRequest) &&
323         !iid.equals(nsISupports))
324         throw Components.results.NS_ERROR_NO_INTERFACE;
325
326     return this;
327 }
328
329 /* nsIChannel */
330 JSDChannel.prototype.loadAttributes = null;
331 JSDChannel.prototype.contentType = "text/html";
332 JSDChannel.prototype.contentLength = -1;
333 JSDChannel.prototype.owner = null;
334 JSDChannel.prototype.loadGroup = null;
335 JSDChannel.prototype.notificationCallbacks = null;
336 JSDChannel.prototype.securityInfo = null;
337
338 JSDChannel.prototype.open =
339 function jsdch_open()
340 {
341     throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
342 }
343
344 JSDChannel.prototype.asyncOpen =
345 function jsdch_aopen (streamListener, context)
346 {
347     this.streamListener = streamListener;
348     this.context = context;
349     this._isPending = true;
350     
351     if (!window && this.URI.spec == "x-jsd:debugger")
352     {
353         this.contentType = "x-application-jsd";
354         this.contentLength = 0;
355         streamListener.onStartRequest(this, context);
356         return;
357     }
358     
359     var window = findDebuggerWindow();
360     var ary = this.URI.spec.match (/x-jsd:([^:]+)/);
361     var exception;
362
363     if (this.loadGroup)
364         this.loadGroup.addRequest (this, null);
365
366     if (window && "console" in window && ary)
367     {
368         try
369         {
370             window.asyncOpenJSDURL (this, streamListener, context);
371             return;
372         }
373         catch (ex)
374         {
375             exception = ex;
376         }
377     }
378
379     var str =
380         "<html><head><title>Error</title></head><body>Could not load &lt;<b>" +
381         safeHTML(this.URI.spec) + "</b>&gt;<br>";
382     
383     if (!ary)
384     {
385         str += "<b>Error parsing uri.</b>";
386     }
387     else if (exception)
388     {
389         str += "<b>Internal error: " + safeHTML(exception) + "</b><br><pre>" + 
390             safeHTML(exception.stack);
391     }
392     else
393     {
394         str += "<b>Debugger is not running.</b>";
395     }
396     
397     str += "</body></html>";
398     
399     this.respond (str);
400 }
401
402 JSDChannel.prototype.respond =
403 function jsdch_respond (str)
404 {
405     this.streamListener.onStartRequest (this, this.context);
406
407     var len = str.length;
408     this.stringStream.setData (str, len);
409     this.streamListener.onDataAvailable (this, this.context,
410                                          this.stringStream, 0, len);
411     this.streamListener.onStopRequest (this, this.context,
412                                        Components.results.NS_OK);
413     if (this.loadGroup)
414         this.loadGroup.removeRequest (this, null, Components.results.NS_OK);
415     this._isPending = false;    
416 }
417
418 /* nsIRequest */
419 JSDChannel.prototype.isPending =
420 function jsdch_ispending ()
421 {
422     return this._isPending;
423 }
424
425 JSDChannel.prototype.status = Components.results.NS_OK;
426
427 JSDChannel.prototype.cancel =
428 function jsdch_cancel (status)
429 {
430     if (this._isPending)
431     {
432         this._isPending = false;
433         this.streamListener.onStopRequest (this, this.context, status);
434         if (this.loadGroup)
435         {
436             try
437             {
438                 this.loadGroup.removeRequest (this, null, status);
439             }
440             catch (ex)
441             {
442                 debug ("we're not in the load group?\n");
443             }
444         }
445     }
446     
447     this.status = status;
448 }
449
450 JSDChannel.prototype.suspend =
451 JSDChannel.prototype.resume =
452 function jsdch_notimpl ()
453 {
454     throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
455 }
456
457 /*****************************************************************************/
458
459 /* x-application-jsd content handler */
460 function JSDContentHandler ()
461 {}
462
463 JSDContentHandler.prototype.QueryInterface =
464 function jsdh_qi(iid)
465 {
466     if (!iid.equals(nsIContentHandler) && !iid.equals(nsISupports))
467         throw Components.results.NS_ERROR_NO_INTERFACE;
468
469     return this;
470 }
471
472 JSDContentHandler.prototype.handleContent =
473 function jsdh_handle(contentType, windowTarget, request)
474 {
475     var e;
476     var channel = request.QueryInterface(nsIChannel);
477     
478     // prevent someone from invoking the debugger remotely by serving
479     // up any old file with the x-application-jsd content type.
480     if (channel.URI.spec != "x-jsd:debugger")
481     {
482         debug ("Not handling content from unknown location ``" +
483                channel.URI.spec + "''");
484         return;
485     }
486     
487     var window = findDebuggerWindow()
488
489     if (window)
490     {
491         window.focus();
492     }
493     else
494     {
495         var ass =
496             Components.classes[ASS_CONTRACTID].getService(nsIAppShellService);
497         window = ass.hiddenDOMWindow;
498
499         var args = new Object();
500         args.url = channel.URI.spec;
501
502         openDebuggerWindow(args);
503      }
504 }
505
506 /*****************************************************************************/
507
508 /* content handler factory object (IRCContentHandler) */
509 var JSDContentHandlerFactory = new Object();
510
511 JSDContentHandlerFactory.createInstance =
512 function jsdhf_create(outer, iid)
513 {
514     if (outer != null)
515         throw Components.results.NS_ERROR_NO_AGGREGATION;
516
517     if (!iid.equals(nsIContentHandler) && !iid.equals(nsISupports))
518         throw Components.results.NS_ERROR_INVALID_ARG;
519
520     return new JSDContentHandler();
521 }
522
523 /*****************************************************************************/
524
525 var Module = new Object();
526
527 Module.registerSelf =
528 function (compMgr, fileSpec, location, type)
529 {
530     debug("*** Registering -venkman handler.\n");
531     
532     compMgr = compMgr.QueryInterface(nsIComponentRegistrar);
533
534     compMgr.registerFactoryLocation(CLINE_SERVICE_CID,
535                                     "Venkman CommandLine Service",
536                                     CLINE_SERVICE_CTRID, 
537                                     fileSpec,
538                                     location, 
539                                     type);
540
541     catman = Components.classes[CATMAN_CTRID].getService(nsICategoryManager);
542     catman.addCategoryEntry("command-line-argument-handlers",
543                             "venkman command line handler",
544                             CLINE_SERVICE_CTRID, true, true);
545
546     catman.addCategoryEntry("command-line-handler",
547                             "venkman command line handler",
548                             CLINE_SERVICE_CTRID, true, true);
549
550     debug("*** Registering x-jsd protocol handler.\n");
551     compMgr.registerFactoryLocation(JSDPROT_HANDLER_CID,
552                                     "x-jsd protocol handler",
553                                     JSDPROT_HANDLER_CTRID, 
554                                     fileSpec, 
555                                     location,
556                                     type);
557
558     debug("*** Registering x-application-jsd content handler.\n");
559     compMgr.registerFactoryLocation(JSDCNT_HANDLER_CID,
560                                     "x-application-jsd content handler",
561                                     JSDCNT_HANDLER_CTRID, 
562                                     fileSpec, 
563                                     location,
564                                     type);
565     try
566     {
567         const JSD_CTRID = "@mozilla.org/js/jsd/debugger-service;1";
568         const jsdIDebuggerService = Components.interfaces.jsdIDebuggerService;
569         var jsds = Components.classes[JSD_CTRID].getService(jsdIDebuggerService);
570         jsds.initAtStartup = true;
571     }
572     catch (ex)
573     {
574         debug ("*** ERROR initializing debugger service");
575         debug (ex);
576     }
577 }
578
579 Module.unregisterSelf =
580 function(compMgr, fileSpec, location)
581 {
582     compMgr = compMgr.QueryInterface(nsIComponentRegistrar);
583
584     compMgr.unregisterFactoryLocation(CLINE_SERVICE_CID, fileSpec);
585     catman = Components.classes[CATMAN_CTRID].getService(nsICategoryManager);
586     catman.deleteCategoryEntry("command-line-argument-handlers",
587                                CLINE_SERVICE_CTRID, true);
588     catman.deleteCategoryEntry("command-line-handler",
589                                CLINE_SERVICE_CTRID, true);
590 }
591
592 Module.getClassObject =
593 function (compMgr, cid, iid) {
594     if (cid.equals(CLINE_SERVICE_CID))
595         return CLineFactory;
596
597     if (cid.equals(JSDPROT_HANDLER_CID))
598         return JSDProtocolHandlerFactory;
599
600     if (cid.equals(JSDCNT_HANDLER_CID))
601         return JSDContentHandlerFactory;
602     
603     if (!iid.equals(Components.interfaces.nsIFactory))
604         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
605
606     throw Components.results.NS_ERROR_NO_INTERFACE;
607     
608 }
609
610 Module.canUnload =
611 function(compMgr)
612 {
613     return true;
614 }
615
616 /* entrypoint */
617 function NSGetModule(compMgr, fileSpec) {
618     return Module;
619 }