michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// Constants michael@0: michael@0: const Ci = Components.interfaces; michael@0: const Cr = Components.results; michael@0: const Cc = Components.classes; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// nsWebHandler class michael@0: michael@0: function nsWebHandlerApp() {} michael@0: michael@0: nsWebHandlerApp.prototype = { michael@0: ////////////////////////////////////////////////////////////////////////////// michael@0: //// nsWebHandler michael@0: michael@0: classDescription: "A web handler for protocols and content", michael@0: classID: Components.ID("8b1ae382-51a9-4972-b930-56977a57919d"), michael@0: contractID: "@mozilla.org/uriloader/web-handler-app;1", michael@0: michael@0: _name: null, michael@0: _detailedDescription: null, michael@0: _uriTemplate: null, michael@0: michael@0: ////////////////////////////////////////////////////////////////////////////// michael@0: //// nsIHandlerApp michael@0: michael@0: get name() { michael@0: return this._name; michael@0: }, michael@0: michael@0: set name(aName) { michael@0: this._name = aName; michael@0: }, michael@0: michael@0: get detailedDescription() { michael@0: return this._detailedDescription; michael@0: }, michael@0: michael@0: set detailedDescription(aDesc) { michael@0: this._detailedDescription = aDesc; michael@0: }, michael@0: michael@0: equals: function(aHandlerApp) { michael@0: if (!aHandlerApp) michael@0: throw Cr.NS_ERROR_NULL_POINTER; michael@0: michael@0: if (aHandlerApp instanceof Ci.nsIWebHandlerApp && michael@0: aHandlerApp.uriTemplate && michael@0: this.uriTemplate && michael@0: aHandlerApp.uriTemplate == this.uriTemplate) michael@0: return true; michael@0: michael@0: return false; michael@0: }, michael@0: michael@0: launchWithURI: function nWHA__launchWithURI(aURI, aWindowContext) { michael@0: michael@0: // XXX need to strip passwd & username from URI to handle, as per the michael@0: // WhatWG HTML5 draft. nsSimpleURL, which is what we're going to get, michael@0: // can't do this directly. Ideally, we'd fix nsStandardURL to make it michael@0: // possible to turn off all of its quirks handling, and use that... michael@0: michael@0: // encode the URI to be handled michael@0: var escapedUriSpecToHandle = encodeURIComponent(aURI.spec); michael@0: michael@0: // insert the encoded URI and create the object version michael@0: var uriSpecToSend = this.uriTemplate.replace("%s", escapedUriSpecToHandle); michael@0: var ioService = Cc["@mozilla.org/network/io-service;1"]. michael@0: getService(Ci.nsIIOService); michael@0: var uriToSend = ioService.newURI(uriSpecToSend, null, null); michael@0: michael@0: // if we have a window context, use the URI loader to load there michael@0: if (aWindowContext) { michael@0: michael@0: // create a channel from this URI michael@0: var channel = ioService.newChannelFromURI(uriToSend); michael@0: channel.loadFlags = Ci.nsIChannel.LOAD_DOCUMENT_URI; michael@0: michael@0: // load the channel michael@0: var uriLoader = Cc["@mozilla.org/uriloader;1"]. michael@0: getService(Ci.nsIURILoader); michael@0: // XXX ideally, whether to pass the IS_CONTENT_PREFERRED flag should be michael@0: // passed in from above. Practically, the flag is probably a reasonable michael@0: // default since browsers don't care much, and link click is likely to be michael@0: // the more interesting case for non-browser apps. See michael@0: // for details. michael@0: uriLoader.openURI(channel, Ci.nsIURILoader.IS_CONTENT_PREFERRED, michael@0: aWindowContext); michael@0: return; michael@0: } michael@0: michael@0: // since we don't have a window context, hand it off to a browser michael@0: var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"]. michael@0: getService(Ci.nsIWindowMediator); michael@0: michael@0: // get browser dom window michael@0: var browserDOMWin = windowMediator.getMostRecentWindow("navigator:browser") michael@0: .QueryInterface(Ci.nsIDOMChromeWindow) michael@0: .browserDOMWindow; michael@0: michael@0: // if we got an exception, there are several possible reasons why: michael@0: // a) this gecko embedding doesn't provide an nsIBrowserDOMWindow michael@0: // implementation (i.e. doesn't support browser-style functionality), michael@0: // so we need to kick the URL out to the OS default browser. This is michael@0: // the subject of bug 394479. michael@0: // b) this embedding does provide an nsIBrowserDOMWindow impl, but michael@0: // there doesn't happen to be a browser window open at the moment; one michael@0: // should be opened. It's not clear whether this situation will really michael@0: // ever occur in real life. If it does, the only API that I can find michael@0: // that seems reasonably likely to work for most embedders is the michael@0: // command line handler. michael@0: // c) something else went wrong michael@0: // michael@0: // it's not clear how one would differentiate between the three cases michael@0: // above, so for now we don't catch the exception michael@0: michael@0: // openURI michael@0: browserDOMWin.openURI(uriToSend, michael@0: null, // no window.opener michael@0: Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, michael@0: Ci.nsIBrowserDOMWindow.OPEN_NEW); michael@0: michael@0: return; michael@0: }, michael@0: michael@0: ////////////////////////////////////////////////////////////////////////////// michael@0: //// nsIWebHandlerApp michael@0: michael@0: get uriTemplate() { michael@0: return this._uriTemplate; michael@0: }, michael@0: michael@0: set uriTemplate(aURITemplate) { michael@0: this._uriTemplate = aURITemplate; michael@0: }, michael@0: michael@0: ////////////////////////////////////////////////////////////////////////////// michael@0: //// nsISupports michael@0: michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebHandlerApp, Ci.nsIHandlerApp]) michael@0: }; michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// Module michael@0: michael@0: this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsWebHandlerApp]); michael@0: