Implement protocol handlers for Prism

RESOLVED FIXED

Status

--
enhancement
RESOLVED FIXED
10 years ago
10 years ago

People

(Reporter: matthew.gertner, Assigned: matthew.gertner)

Tracking

Details

Attachments

(1 attachment, 2 obsolete attachments)

(Assignee)

Description

10 years ago
It should be possible to register a protocol handler for a given URI scheme and have it invoke the application when a link with that scheme is opened. This should work whether the application is running or not.
(Assignee)

Comment 1

10 years ago
Created attachment 321357 [details] [diff] [review]
WIP for Mac

This implements protocol handling on OS X. There is an nsIShellService interface to handle operating system integration and additional methods in nsIPlatformGlue for the web API.

Some issues for discussion:
- I think we probably want to keep the web API but we might want to consider adding a [Protocols] section to webapp.ini as an alternative (suggested by Mark).
- When does the handler get registered? I tested this in load() and it works fine, but we could consider adding a one-time install() method as well so the registration only happens once when the app is installed. Later we might want to implement an uninstall() method as well so the app can do cleanup.
- Right now the protocol is registered as a URI. Perhaps some web apps would want to register a JS callback instead, but this would be slightly tricky so I'd like opinions about how necessary this is.
- The protocol handler URI uses a %s placeholder for the actual URI being opened. This includes the scheme, so the mailto: prefix is included in the case of the mailto protocol. We don't want this, so we need a way to specify that the scheme should be removed for certain protocols. Maybe use a different placeholders (like %S) so it knows whether to include the scheme or not?
(Assignee)

Comment 2

10 years ago
Created attachment 321955 [details] [diff] [review]
Register protocol support for Windows and Mac

Example of usage:
window.platform.registerProtocolHandler("mailto", "http://www.mymail.com/?to=%s");

Comments:
- I went ahead and stripped the scheme from the URI (so "mailto:foo@foo.com" would add "foo@foo.com" to the URI string). Protocols that want to keep the scheme can always put it in the URI string explicitly (e.g. "http://www.foo.com/?url=http:%s").

- There is no support for Vista privilege escalation, so I'm not sure this will work on Vista. This should be pretty straightforward to add since I used NSIS for the protocol registration on Windows, but I don't have Vista so I can't test it. Mark, will you have time to look at this? If not I'll just have to buy Vista.

- There is no way to remove the registered protocol from the Launch Services database on Mac. I'm not sure how to do this or how important it is. I think it should work fine as is since if the app is ever removed, OS X will go back to the default mail app automatically.

- See https://bugzilla.mozilla.org/show_bug.cgi?id=435033. Until this is fixed, the first run will register the wrong command for the protocol on Windows (since the -override parameter will be missing). This is fixed on the next run. This is only an issue for pre-packaged apps that already include a webapp.js that registers a new protocol. If the user first runs Prism first to create a web app, no EM restart will be needed on subsequent runs.

- This approach is very inefficient for Ajax apps since they have to load the entire site again with all its JS if the app is running when the protocol handler is invoked. I'm planning to add an additional registerProtocolCallback API that calls directly into a user-defined callback for running apps, but I'd like to get this patch reviewed and checked in first.
Attachment #321357 - Attachment is obsolete: true
Attachment #321955 - Flags: review?(mark.finkle)
(Assignee)

Updated

10 years ago
Depends on: 435033
(Assignee)

Comment 3

10 years ago
Created attachment 322241 [details] [diff] [review]
Use navigator:browser and protocol handlers

The nsMacCommandLine/hidden window hack had unwanted side effects, notably the fact that popup windows didn't open properly. This is a much cleaner solution although it does unfortunately necessitate setting our window type to "navigator:browser" since this is hardcoded into some of the Mozilla platform code.
Attachment #321955 - Attachment is obsolete: true
Attachment #322241 - Flags: review?(mark.finkle)
Attachment #321955 - Flags: review?(mark.finkle)
Comment on attachment 322241 [details] [diff] [review]
Use navigator:browser and protocol handlers

>Index: runtime/components/src/nsCommandLineHandler.js
>===================================================================
>+      else {
>+        try {
>+          // Get the URI to use for the protcol
>+          var platform = Cc["@mozilla.org/platform-web-api;1"].createInstance(Ci.nsIPlatformGlue);
>+          protocolURI = platform.getProtocolURI(uri.spec);
>+        }

Comment could use a bit more explanation - "Check for a protocol handler launch..."

>+    // Check for an existing window and reuse it if there is one
>+    var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
>+    var win = windowMediator.getMostRecentWindow("webrunner:main");

Shouldn't this be "navigator:browser" ?


>Index: runtime/components/src/windows/nsDesktopEnvironmentWin.cpp
>===================================================================

>+  rv = appHelper->Append(NS_LITERAL_STRING("register.exe"));

I think  we need to be more specific in the name of the exe. Maybe "regprot.exe"

And can we use the same exe for register and unregister? Use a commandline flag to switch? "-u" for unregister.

Also, the commandline params with TitleCase seem weird (/Protocol and /ApplicationName), but if Firefox does it that way, so be it. I would have gone short and sweet (/protocol, /appname and /apppath)

>Index: runtime/components/src/nsPlatformGlue.js
>===================================================================

>+function WebRunnerProtocolHandler(contractid) {
>+  this._ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
>+}

Everything else in here is PlatformXxx, should this be too? PlatformProtocolHandler

>Index: runtime/defaults/preferences/preferences.js
>===================================================================
>+pref("toolkit.singletonWindowType", "webrunner");

I thought this should be "navigator:browser", since singletonWEindowType wants the <window windowtype="xxx" ...

>Index: runtime/chrome/content/webrunner.js
>===================================================================
>-    document.documentElement.setAttribute("windowtype", "webrunner:main");
>+    //document.documentElement.setAttribute("windowtype", "webrunner:main");

Let's just remove it


>Index: client/Makefile.in
>===================================================================
> libs::
>+ifeq ($(OS_ARCH),WINNT)
>+	cp $(srcdir)/winbuild/register.nsi $(DIST)/bin
>+	makensis $(DIST)/bin/register.nsi
>+	cp $(srcdir)/winbuild/unregister.nsi $(DIST)/bin
>+	makensis $(DIST)/bin/unregister.nsi
>+endif

Again, one EXE please

======================================

One thing that troubles me is the way we strip the protocol when sending to the handler URL. Firefox (& WHAT-WG) do _not_ do this for web-based registerProtocolHandler. The entire snippet is sent and the application (server-side) must parse the string to remove the protocol (mailto:) and parse for parameters (to=, subject=, cc=)

Why are we stripping? Should we be following the web standard or not?

r+, but let's figure this part out
Attachment #322241 - Flags: review?(mark.finkle) → review+
(Assignee)

Comment 5

10 years ago
(In reply to comment #4)
> One thing that troubles me is the way we strip the protocol when sending to the
> handler URL. Firefox (& WHAT-WG) do _not_ do this for web-based
> registerProtocolHandler. The entire snippet is sent and the application
> (server-side) must parse the string to remove the protocol (mailto:) and parse
> for parameters (to=, subject=, cc=)
> 
> Why are we stripping? Should we be following the web standard or not?
> 
> r+, but let's figure this part out

Well the issue here is that existing web apps won't expect the scheme to be included for protocols like mailto. My rationale was that it's easy to add it back in in the protocol URI string for protocols that do require it. But there are many other ways to handle this (like using different placeholders for with and without scheme). Let's discuss.
Status: ASSIGNED → RESOLVED
Last Resolved: 10 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.