summaryrefslogtreecommitdiffabout
path: root/misc/xrdsContentHandler.js
Side-by-side diff
Diffstat (limited to 'misc/xrdsContentHandler.js') (more/less context) (ignore whitespace changes)
-rwxr-xr-xmisc/xrdsContentHandler.js401
1 files changed, 401 insertions, 0 deletions
diff --git a/misc/xrdsContentHandler.js b/misc/xrdsContentHandler.js
new file mode 100755
index 0000000..4f30310
--- a/dev/null
+++ b/misc/xrdsContentHandler.js
@@ -0,0 +1,401 @@
+
+const nsISupports = Components.interfaces.nsISupports;
+
+const nsIBrowserDOMWindow = Components.interfaces.nsIBrowserDOMWindow;
+const nsIChannel = Components.interfaces.nsIChannel;
+const nsIContentHandler = Components.interfaces.nsIContentHandler;
+const nsIDOMChromeWindow = Components.interfaces.nsIDOMChromeWindow;
+const nsIDOMWindow = Components.interfaces.nsIDOMWindow;
+const nsIFactory = Components.interfaces.nsIFactory;
+const nsIHttpProtocolHandler = Components.interfaces.nsIHttpProtocolHandler;
+const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor;
+const nsIPrefBranch = Components.interfaces.nsIPrefBranch;
+const nsIPrefLocalizedString = Components.interfaces.nsIPrefLocalizedString;
+const nsISupportsString = Components.interfaces.nsISupportsString;
+const nsIWebNavigation = Components.interfaces.nsIWebNavigation;
+const nsIWindowMediator = Components.interfaces.nsIWindowMediator;
+const nsIWindowWatcher = Components.interfaces.nsIWindowWatcher;
+const nsICategoryManager = Components.interfaces.nsICategoryManager;
+const nsIWebNavigationInfo = Components.interfaces.nsIWebNavigationInfo;
+const nsIStreamListener = Components.interfaces.nsIStreamListener;
+const nsIRequestObserver = Components.interfaces.nsIRequestObserver;
+const nsIURILoader = Components.interfaces.nsIURILoader;
+const nsIURIContentListener = Components.interfaces.nsIURIContentListener;
+
+const NS_BINDING_ABORTED = 0x80020006;
+const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
+const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
+
+function shouldLoadURI(aURI) {
+ if (aURI.schemeIs("xri"))
+ return true;
+ dump("*** Preventing external load of chrome: URI into browser window\n");
+ dump(" Use -chrome <uri> instead\n");
+ return false;
+}
+
+
+
+
+function openWindow(parent, url, target, features, args) {
+ var wwatch = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
+ .getService(nsIWindowWatcher);
+
+ var argstring;
+ if (args) {
+ argstring = Components.classes["@mozilla.org/supports-string;1"]
+ .createInstance(nsISupportsString);
+ argstring.data = args;
+ }
+ return wwatch.openWindow(parent, url, target, features, argstring);
+}
+
+
+
+
+function getMostRecentWindow(aType) {
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(nsIWindowMediator);
+ return wm.getMostRecentWindow(aType);
+}
+
+
+
+
+// this returns the most recent non-popup browser window
+function getMostRecentBrowserWindow() {
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+
+ var windowList = wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
+ if (!windowList.hasMoreElements())
+ return null;
+
+ var win = windowList.getNext();
+ while (!win.toolbar.visible) {
+ if (!windowList.hasMoreElements())
+ return null;
+
+ win = windowList.getNext();
+ }
+
+ return win;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+var xrdsContentHandler = {
+
+ /** browser window */
+ contentWindow: null,
+
+ /** XRDS buffer */
+ buf: null,
+
+ scriptableInStream: null,
+
+ init: function(contentWin) {
+ this.contentWindow = contentWindow;
+ },
+
+ close: function() {
+ this.contentWindow = null;
+ },
+
+ /* nsISupports */
+ QueryInterface : function(iid) {
+ dump("xrdsCH ... ");
+ if (iid.equals(nsISupports)) {
+ dump("QI(nsISupports)\n");
+ }
+ else if (iid.equals(nsIContentHandler)) {
+ dump("QI(nsIContentHandler)\n");
+ }
+ else if (iid.equals(nsIStreamListener)) {
+ dump("QI(nsIStreamListener)\n");
+ }
+ else if (iid.equals(nsIRequestObserver)) {
+ dump("QI(nsIRequestObserver)\n");
+ }
+ else if (iid.equals(Components.interfaces.nsIURIContentListener)) {
+ dump("QI(nsIURIContentListener)\n");
+ }
+ else if (iid.equals(nsIFactory)) {
+ dump("QI(nsIFactory)\n");
+ }
+ else {
+ dump("QI(" + iid + ") - IDONTKNOW!!!!!\n");
+ }
+
+ if (!iid.equals(nsISupports) &&
+ !iid.equals(nsIContentHandler) &&
+ !iid.equals(nsIURIContentListener) &&
+ !iid.equals(nsIStreamListener) &&
+ !iid.equals(nsIRequestObserver) &&
+ !iid.equals(nsIFactory))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+
+ dump("QI returning this..\n");
+ return this;
+ },
+
+
+ /* nsIURIContentListener */
+ loadCookie: null,
+
+ parentContentListener: null,
+
+ onStartURIOpen: function(uri)
+ {
+ dump("xrdsCH onStartURIOpen '" + uri + "'");
+ // ignore and don't abort
+ return false;
+ },
+
+ doContent: function(contentType, isContentPreferred, request, contentHandler)
+ {
+ dump("doContent called\n");
+ // forward the doContent to our content area webshell
+ var docShell = this.contentWindow.docShell;
+ var contentListener;
+ try {
+ contentListener =
+ docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+ .getInterface(Components.interfaces.nsIURIContentListener);
+ } catch (ex) {
+ dump(ex);
+ }
+
+ dump("no content listener from docShell!\n");
+ if (!contentListener) return false;
+
+ var rv = contentListener.doContent(contentType, isContentPreferred, request, contentHandler);
+
+ if (rv) {
+ dump("docShell wants to handle the load..\n");
+ }
+ else {
+ dump("docShell does NOT want to handle the load..\n");
+
+ contentHandler = contentHandler.value;
+ }
+
+ return rv;
+
+ },
+
+ isPreferred: function(contentType, desiredContentType)
+ {
+ dump("isPreferred '" + contentType + "'\n");
+ switch(contentType) {
+ case "application/xrds+xml":
+ case "application/xrd+xml":
+ dump("yes!!!\n");
+ return true;
+ }
+ dump("erm.. nope!\n");
+ return false;
+ },
+
+ canHandleContent: function(contentType, isContentPreferred, desiredContentType)
+ {
+ dump("canHandleContent '" + contentType + "'\n");
+ return this.isPreferred(contentType, desiredContentType);
+ },
+
+
+
+ /* nsIRequestObserver */
+ onStartRequest: function(request, ctx)
+ {
+ dump("xrdsContentHandler - onStartRequest\n");
+ },
+
+ onStopRequest: function(request, ctx, status)
+ {
+ dump("xrdsContentHandler - onStopRequest\n");
+ this.scriptableInStream.close();
+ },
+
+
+ /* nsIStreamListener */
+ onDataAvailable: function(request, domWindow, inputStream, offset, count)
+ {
+ dump("onDataAvailable, offset=" + offset + ", count=" + count + "\n");
+ if (offset == 0) {
+ this.scriptableInStream.init(inputStream);
+ }
+
+ buf += this.scriptableInStream.read(count);
+
+ if (!request.isPending()) {
+ dump("request finished, buf = " + buf + "\n");
+ var html = domWindow.document.createElement("html");
+ html.createTextNode(buf);
+ this.scriptableInStream = null;
+ }
+ else {
+ dump("request pending...\n");
+ }
+ },
+
+ /* nsIContentHandler */
+
+ handleContent : function(contentType, context, request)
+ {
+ dump("handleContent " + contentType + "\n");
+ var parentWin;
+ try {
+ parentWin = context.getInterface(nsIDOMWindow);
+ }
+ catch (e) {
+ alert("no parent!!!"); // XXX
+ return;
+ }
+
+ dump("getting channel\n");
+ var channel = request.QueryInterface(nsIChannel);
+ if (!channel) {
+ dump("no channel!!!\n");
+ return;
+ }
+
+ if (this.scriptableInStream) {
+ dump("Hey! You can't possibly be reusing this handler?!\n");
+ return;
+ }
+
+ dump("making scriptableInStream\n");
+ this.scriptableInStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Components.interfaces.nsIScriptableInputStream);
+
+ buf = '';
+
+/*
+ try {
+ dump("before asyncOpen\n");
+ channel.asyncOpen(this, parentWin);
+ return;
+ }
+ catch (e) {
+ dump("shit cannot asyncOpen... " + e + "\n");
+ }
+
+ dump("try blocking open\n");
+ var instream = channel.open();
+ this.scriptableinputstream.init(instream);
+ while (true) {
+ var n = this.scriptableinputstream.available();
+ if (n > 0) {
+ dump(this.scriptableinputstream.read(n) + "\n");
+ }
+ }
+
+ dump("channel opened\n");
+*/
+
+ dump("handleContent returning \n");
+ },
+
+ /* nsIFactory */
+ createInstance: function(outer, iid)
+ {
+ dump("xrdsCH createInstance called..\n");
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ dump("xrdsCH ok\n");
+ return this.QueryInterface(iid);
+ },
+
+ lockFactory : function bch_lock(lock) {
+ /* no-op */
+ }
+};
+
+const CLASS_ID = Components.ID("{e857f11b-fd59-4285-8f4a-c27cf9051a36}");
+const CLASS_NAME = "XRDS Content Handler";
+const CONTRACTID_PREFIX = "@mozilla.org/uriloader/content-handler;1?type=";
+
+
+
+var Module = {
+ /* nsISupports */
+ QueryInterface: function(iid)
+ {
+ dump("QI called\n");
+ if (iid.equals(Components.interfaces.nsIModule) ||
+ iid.equals(Components.interfaces.nsISupports))
+ return this;
+
+ dump("QI throwing!!\n");
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+
+ /* nsIModule */
+ getClassObject: function(compMgr, cid, iid)
+ {
+ dump("getClassObject called\n");
+ if (cid.equals(CLASS_ID))
+ return xrdsContentHandler.QueryInterface(iid);
+
+ dump("gCO throwing!!\n");
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ },
+
+
+ registerSelf: function(compMgr, fileSpec, location, type)
+ {
+ var compReg =
+ compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+
+ compReg.registerFactoryLocation( CLASS_ID,
+ CLASS_NAME,
+ CONTRACTID_PREFIX + "application/xrds+xml",
+ fileSpec,
+ location,
+ type );
+
+ compReg.registerFactoryLocation( CLASS_ID,
+ CLASS_NAME,
+ CONTRACTID_PREFIX + "text/uri-list",
+ fileSpec,
+ location,
+ type );
+
+ dump("done registerSelf..\n");
+ },
+
+
+ unregisterSelf: function(compMgr, location, type)
+ {
+ var compReg = compMgr.QueryInterface(nsIComponentRegistrar);
+ compReg.unregisterFactoryLocation(CLASS_ID, location);
+ },
+
+
+ canUnload: function(compMgr) {
+ return true;
+ }
+};
+
+// NSGetModule: Return the nsIModule object.
+function NSGetModule(compMgr, fileSpec) {
+ return Module;
+}