From: phasefx Date: Mon, 22 Oct 2007 05:04:39 +0000 (+0000) Subject: integrating venkman javascript debugger X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=cd1b4f3cf0f2050a363591ba00170671d59749d2;p=Evergreen.git integrating venkman javascript debugger git-svn-id: svn://svn.open-ils.org/ILS/branches/rel_1_2@7899 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/xul/staff_client/chrome/chrome.manifest b/Open-ILS/xul/staff_client/chrome/chrome.manifest index 747267314d..cec0d7bfa9 100644 --- a/Open-ILS/xul/staff_client/chrome/chrome.manifest +++ b/Open-ILS/xul/staff_client/chrome/chrome.manifest @@ -2,3 +2,6 @@ content open_ils_staff_client content/ locale open_ils_staff_client en-US locale/en-US/ skin open_ils_staff_client open_ils_staff_client skin/ locale branding en-US branding/locale/en-US/ +content venkman jar:venkman.jar!/content/venkman/ +locale venkman en-US jar:venkman.jar!/locale/en-US/venkman/ +skin venkman modern/1.0 jar:venkman.jar!/skin/modern/venkman/ diff --git a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js index 125201a1b4..43ef5d4805 100644 --- a/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js +++ b/Open-ILS/xul/staff_client/chrome/content/OpenILS/global_util.js @@ -200,3 +200,9 @@ } } + function toOpenWindowByType(inType, uri) { + var winopts = "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar"; + window.open(uri, "_blank", winopts); + } + + diff --git a/Open-ILS/xul/staff_client/chrome/venkman.jar b/Open-ILS/xul/staff_client/chrome/venkman.jar new file mode 100644 index 0000000000..9aa7755d64 Binary files /dev/null and b/Open-ILS/xul/staff_client/chrome/venkman.jar differ diff --git a/Open-ILS/xul/staff_client/components/venkman-service.js b/Open-ILS/xul/staff_client/components/venkman-service.js new file mode 100644 index 0000000000..867b52a291 --- /dev/null +++ b/Open-ILS/xul/staff_client/components/venkman-service.js @@ -0,0 +1,608 @@ +/* -*- Mode: C++; tab-width: 4; 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 The JavaScript Debugger. + * + * 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, , 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 ***** */ + +/* components defined in this file */ +const CLINE_SERVICE_CTRID = + "@mozilla.org/commandlinehandler/general-startup;1?type=venkman"; +const CLINE_SERVICE_CID = + Components.ID("{18269616-1dd2-11b2-afa8-b612439bda27}"); +const JSDPROT_HANDLER_CTRID = + "@mozilla.org/network/protocol;1?name=x-jsd"; +const JSDPROT_HANDLER_CID = + Components.ID("{12ec790d-304e-4525-89a9-3e723d489d14}"); +const JSDCNT_HANDLER_CTRID = + "@mozilla.org/uriloader/content-handler;1?type=x-application-jsd"; +const JSDCNT_HANDLER_CID = + Components.ID("{306670f0-47bb-466b-b53b-613235623bbd}"); + +/* components used by this file */ +const CATMAN_CTRID = "@mozilla.org/categorymanager;1"; +const STRING_STREAM_CTRID = "@mozilla.org/io/string-input-stream;1"; +const MEDIATOR_CTRID = + "@mozilla.org/appshell/window-mediator;1"; +const ASS_CONTRACTID = + "@mozilla.org/appshell/appShellService;1"; +const SIMPLEURI_CTRID = "@mozilla.org/network/simple-uri;1"; + +const nsIWindowMediator = Components.interfaces.nsIWindowMediator; +const nsIAppShellService = Components.interfaces.nsIAppShellService; +const nsICmdLineHandler = Components.interfaces.nsICmdLineHandler; +const nsIComponentRegistrar = Components.interfaces.nsIComponentRegistrar; +const nsICategoryManager = Components.interfaces.nsICategoryManager; +const nsIContentHandler = Components.interfaces.nsIContentHandler; +const nsIProtocolHandler = Components.interfaces.nsIProtocolHandler; +const nsIURI = Components.interfaces.nsIURI; +const nsIURL = Components.interfaces.nsIURL; +const nsIStringInputStream = Components.interfaces.nsIStringInputStream; +const nsIChannel = Components.interfaces.nsIChannel; +const nsIRequest = Components.interfaces.nsIRequest; +const nsIProgressEventSink = Components.interfaces.nsIProgressEventSink; +const nsISupports = Components.interfaces.nsISupports; +const nsICommandLineHandler = Components.interfaces.nsICommandLineHandler; +const nsICommandLine = Components.interfaces.nsICommandLine; + +function findDebuggerWindow () +{ + var windowManager = + Components.classes[MEDIATOR_CTRID].getService(nsIWindowMediator); + return windowManager.getMostRecentWindow("mozapp:venkman"); +} + +function openDebuggerWindow(args) +{ + var ass = Components.classes[ASS_CONTRACTID].getService(nsIAppShellService); + var window = ass.hiddenDOMWindow; + window.openDialog("chrome://venkman/content/venkman.xul", "_blank", + "chrome,menubar,toolbar,resizable,dialog=no", args); +} + +function safeHTML(str) +{ + function replaceChars(ch) + { + switch (ch) + { + case "<": + return "<"; + + case ">": + return ">"; + + case "&": + return "&"; + } + + return "?"; + }; + + return String(str).replace(/[<>&]/g, replaceChars); +} + +/* Command Line handler service */ +function CLineService() +{} + +/* nsISupports */ +CLineService.prototype.QueryInterface = +function handler_QI(iid) +{ + if (iid.equals(nsISupports) || + (nsICommandLineHandler && iid.equals(nsICommandLineHandler)) || + (nsICmdLineHandler && iid.equals(nsICmdLineHandler))) + { + return this; + } + + throw Components.results.NS_ERROR_NO_INTERFACE; +} + +/* nsICmdLineHandler */ +CLineService.prototype.commandLineArgument = "-venkman"; +CLineService.prototype.prefNameForStartup = "general.startup.venkman"; +CLineService.prototype.chromeUrlForTask = "chrome://venkman/content"; +CLineService.prototype.helpText = "Start with JavaScript Debugger (Venkman)."; +CLineService.prototype.handlesArgs = false; +CLineService.prototype.defaultArgs = ""; +CLineService.prototype.openWindowWithArgs = false; + +/* nsICommandLineHandler */ + +CLineService.prototype.handle = +function handler_handle(cmdLine) +{ + try + { + if (cmdLine.handleFlag("venkman", false)) + openDebuggerWindow(null); + } + catch (e) + { + debug(e); + } +} + +CLineService.prototype.helpInfo = + " -venkman Start with JavaScript debugger (Venkman).\n" + +/* factory for command line handler service (CLineService) */ +var CLineFactory = new Object(); + +CLineFactory.createInstance = +function clf_create (outer, iid) { + if (outer != null) + throw Components.results.NS_ERROR_NO_AGGREGATION; + + return new CLineService().QueryInterface(iid); +} + +/* x-jsd: protocol handler */ + +const JSD_DEFAULT_PORT = 2206; /* Dana's apartment number. */ + +/* protocol handler factory object */ +var JSDProtocolHandlerFactory = new Object(); + +JSDProtocolHandlerFactory.createInstance = +function jsdhf_create (outer, iid) { + if (outer != null) + throw Components.results.NS_ERROR_NO_AGGREGATION; + + if (!iid.equals(nsIProtocolHandler) && !iid.equals(nsISupports)) + throw Components.results.NS_ERROR_INVALID_ARG; + + return new JSDProtocolHandler(); +} + +function JSDURI (spec, charset) +{ + this.spec = this.prePath = spec; + this.charset = this.originCharset = charset; +} + +JSDURI.prototype.QueryInterface = +function jsdch_qi (iid) +{ + if (!iid.equals(nsIURI) && !iid.equals(nsIURL) && + !iid.equals(nsISupports)) + throw Components.results.NS_ERROR_NO_INTERFACE; + + return this; +} + +JSDURI.prototype.scheme = "x-jsd"; + +JSDURI.prototype.fileBaseName = +JSDURI.prototype.fileExtension = +JSDURI.prototype.filePath = +JSDURI.prototype.param = +JSDURI.prototype.query = +JSDURI.prototype.ref = +JSDURI.prototype.directory = +JSDURI.prototype.fileName = +JSDURI.prototype.username = +JSDURI.prototype.password = +JSDURI.prototype.hostPort = +JSDURI.prototype.path = +JSDURI.prototype.asciiHost = +JSDURI.prototype.userPass = ""; + +JSDURI.prototype.port = JSD_DEFAULT_PORT; + +JSDURI.prototype.schemeIs = +function jsduri_schemeis (scheme) +{ + return scheme.toLowerCase() == "x-jsd"; +} + +JSDURI.prototype.getCommonBaseSpec = +function jsduri_commonbase (uri) +{ + return "x-jsd:"; +} + +JSDURI.prototype.getRelativeSpec = +function jsduri_commonbase (uri) +{ + return uri; +} + +JSDURI.prototype.equals = +function jsduri_equals (uri) +{ + return uri.spec == this.spec; +} + +JSDURI.prototype.clone = +function jsduri_clone () +{ + return new JSDURI (this.spec); +} + +JSDURI.prototype.resolve = +function jsduri_resolve(path) +{ + //dump ("resolve " + path + " from " + this.spec + "\n"); + if (path[0] == "#") + return this.spec + path; + + return path; +} + +function JSDProtocolHandler() +{ + /* nothing here */ +} + +JSDProtocolHandler.prototype.scheme = "x-jsd"; +JSDProtocolHandler.prototype.defaultPort = JSD_DEFAULT_PORT; +JSDProtocolHandler.prototype.protocolFlags = nsIProtocolHandler.URI_NORELATIVE || + nsIProtocolHandler.URI_NOAUTH; + +JSDProtocolHandler.prototype.allowPort = +function jsdph_allowport (aPort, aScheme) +{ + return false; +} + +JSDProtocolHandler.prototype.newURI = +function jsdph_newuri (spec, charset, baseURI) +{ + var clazz = Components.classes[SIMPLEURI_CTRID]; + var uri = clazz.createInstance(nsIURI); + uri.spec = spec; + return uri; +} + +JSDProtocolHandler.prototype.newChannel = +function jsdph_newchannel (uri) +{ + return new JSDChannel (uri); +} + +function JSDChannel (uri) +{ + this.URI = uri; + this.originalURI = uri; + this._isPending = false; + var clazz = Components.classes[STRING_STREAM_CTRID]; + this.stringStream = clazz.createInstance(nsIStringInputStream); +} + +JSDChannel.prototype.QueryInterface = +function jsdch_qi (iid) +{ + + if (!iid.equals(nsIChannel) && !iid.equals(nsIRequest) && + !iid.equals(nsISupports)) + throw Components.results.NS_ERROR_NO_INTERFACE; + + return this; +} + +/* nsIChannel */ +JSDChannel.prototype.loadAttributes = null; +JSDChannel.prototype.contentType = "text/html"; +JSDChannel.prototype.contentLength = -1; +JSDChannel.prototype.owner = null; +JSDChannel.prototype.loadGroup = null; +JSDChannel.prototype.notificationCallbacks = null; +JSDChannel.prototype.securityInfo = null; + +JSDChannel.prototype.open = +function jsdch_open() +{ + throw Components.results.NS_ERROR_NOT_IMPLEMENTED; +} + +JSDChannel.prototype.asyncOpen = +function jsdch_aopen (streamListener, context) +{ + this.streamListener = streamListener; + this.context = context; + this._isPending = true; + + if (!window && this.URI.spec == "x-jsd:debugger") + { + this.contentType = "x-application-jsd"; + this.contentLength = 0; + streamListener.onStartRequest(this, context); + return; + } + + var window = findDebuggerWindow(); + var ary = this.URI.spec.match (/x-jsd:([^:]+)/); + var exception; + + if (this.loadGroup) + this.loadGroup.addRequest (this, null); + + if (window && "console" in window && ary) + { + try + { + window.asyncOpenJSDURL (this, streamListener, context); + return; + } + catch (ex) + { + exception = ex; + } + } + + var str = + "ErrorCould not load <" + + safeHTML(this.URI.spec) + ">
"; + + if (!ary) + { + str += "Error parsing uri."; + } + else if (exception) + { + str += "Internal error: " + safeHTML(exception) + "
" + 
+            safeHTML(exception.stack);
+    }
+    else
+    {
+        str += "Debugger is not running.";
+    }
+    
+    str += "";
+    
+    this.respond (str);
+}
+
+JSDChannel.prototype.respond =
+function jsdch_respond (str)
+{
+    this.streamListener.onStartRequest (this, this.context);
+
+    var len = str.length;
+    this.stringStream.setData (str, len);
+    this.streamListener.onDataAvailable (this, this.context,
+                                         this.stringStream, 0, len);
+    this.streamListener.onStopRequest (this, this.context,
+                                       Components.results.NS_OK);
+    if (this.loadGroup)
+        this.loadGroup.removeRequest (this, null, Components.results.NS_OK);
+    this._isPending = false;    
+}
+
+/* nsIRequest */
+JSDChannel.prototype.isPending =
+function jsdch_ispending ()
+{
+    return this._isPending;
+}
+
+JSDChannel.prototype.status = Components.results.NS_OK;
+
+JSDChannel.prototype.cancel =
+function jsdch_cancel (status)
+{
+    if (this._isPending)
+    {
+        this._isPending = false;
+        this.streamListener.onStopRequest (this, this.context, status);
+        if (this.loadGroup)
+        {
+            try
+            {
+                this.loadGroup.removeRequest (this, null, status);
+            }
+            catch (ex)
+            {
+                debug ("we're not in the load group?\n");
+            }
+        }
+    }
+    
+    this.status = status;
+}
+
+JSDChannel.prototype.suspend =
+JSDChannel.prototype.resume =
+function jsdch_notimpl ()
+{
+    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/*****************************************************************************/
+
+/* x-application-jsd content handler */
+function JSDContentHandler ()
+{}
+
+JSDContentHandler.prototype.QueryInterface =
+function jsdh_qi(iid)
+{
+    if (!iid.equals(nsIContentHandler) && !iid.equals(nsISupports))
+        throw Components.results.NS_ERROR_NO_INTERFACE;
+
+    return this;
+}
+
+JSDContentHandler.prototype.handleContent =
+function jsdh_handle(contentType, windowTarget, request)
+{
+    var e;
+    var channel = request.QueryInterface(nsIChannel);
+    
+    // prevent someone from invoking the debugger remotely by serving
+    // up any old file with the x-application-jsd content type.
+    if (channel.URI.spec != "x-jsd:debugger")
+    {
+        debug ("Not handling content from unknown location ``" +
+               channel.URI.spec + "''");
+        return;
+    }
+    
+    var window = findDebuggerWindow()
+
+    if (window)
+    {
+        window.focus();
+    }
+    else
+    {
+        var ass =
+            Components.classes[ASS_CONTRACTID].getService(nsIAppShellService);
+        window = ass.hiddenDOMWindow;
+
+        var args = new Object();
+        args.url = channel.URI.spec;
+
+        openDebuggerWindow(args);
+     }
+}
+
+/*****************************************************************************/
+
+/* content handler factory object (IRCContentHandler) */
+var JSDContentHandlerFactory = new Object();
+
+JSDContentHandlerFactory.createInstance =
+function jsdhf_create(outer, iid)
+{
+    if (outer != null)
+        throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+    if (!iid.equals(nsIContentHandler) && !iid.equals(nsISupports))
+        throw Components.results.NS_ERROR_INVALID_ARG;
+
+    return new JSDContentHandler();
+}
+
+/*****************************************************************************/
+
+var Module = new Object();
+
+Module.registerSelf =
+function (compMgr, fileSpec, location, type)
+{
+    debug("*** Registering -venkman handler.\n");
+    
+    compMgr = compMgr.QueryInterface(nsIComponentRegistrar);
+
+    compMgr.registerFactoryLocation(CLINE_SERVICE_CID,
+                                    "Venkman CommandLine Service",
+                                    CLINE_SERVICE_CTRID, 
+                                    fileSpec,
+                                    location, 
+                                    type);
+
+    catman = Components.classes[CATMAN_CTRID].getService(nsICategoryManager);
+    catman.addCategoryEntry("command-line-argument-handlers",
+                            "venkman command line handler",
+                            CLINE_SERVICE_CTRID, true, true);
+
+    catman.addCategoryEntry("command-line-handler",
+                            "venkman command line handler",
+                            CLINE_SERVICE_CTRID, true, true);
+
+    debug("*** Registering x-jsd protocol handler.\n");
+    compMgr.registerFactoryLocation(JSDPROT_HANDLER_CID,
+                                    "x-jsd protocol handler",
+                                    JSDPROT_HANDLER_CTRID, 
+                                    fileSpec, 
+                                    location,
+                                    type);
+
+    debug("*** Registering x-application-jsd content handler.\n");
+    compMgr.registerFactoryLocation(JSDCNT_HANDLER_CID,
+                                    "x-application-jsd content handler",
+                                    JSDCNT_HANDLER_CTRID, 
+                                    fileSpec, 
+                                    location,
+                                    type);
+    try
+    {
+        const JSD_CTRID = "@mozilla.org/js/jsd/debugger-service;1";
+        const jsdIDebuggerService = Components.interfaces.jsdIDebuggerService;
+        var jsds = Components.classes[JSD_CTRID].getService(jsdIDebuggerService);
+        jsds.initAtStartup = true;
+    }
+    catch (ex)
+    {
+        debug ("*** ERROR initializing debugger service");
+        debug (ex);
+    }
+}
+
+Module.unregisterSelf =
+function(compMgr, fileSpec, location)
+{
+    compMgr = compMgr.QueryInterface(nsIComponentRegistrar);
+
+    compMgr.unregisterFactoryLocation(CLINE_SERVICE_CID, fileSpec);
+    catman = Components.classes[CATMAN_CTRID].getService(nsICategoryManager);
+    catman.deleteCategoryEntry("command-line-argument-handlers",
+                               CLINE_SERVICE_CTRID, true);
+    catman.deleteCategoryEntry("command-line-handler",
+                               CLINE_SERVICE_CTRID, true);
+}
+
+Module.getClassObject =
+function (compMgr, cid, iid) {
+    if (cid.equals(CLINE_SERVICE_CID))
+        return CLineFactory;
+
+    if (cid.equals(JSDPROT_HANDLER_CID))
+        return JSDProtocolHandlerFactory;
+
+    if (cid.equals(JSDCNT_HANDLER_CID))
+        return JSDContentHandlerFactory;
+    
+    if (!iid.equals(Components.interfaces.nsIFactory))
+        throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+
+    throw Components.results.NS_ERROR_NO_INTERFACE;
+    
+}
+
+Module.canUnload =
+function(compMgr)
+{
+    return true;
+}
+
+/* entrypoint */
+function NSGetModule(compMgr, fileSpec) {
+    return Module;
+}