Re: Adding Web Intents to the Webapps WG deliverables

On Wed, 21 Sep 2011, Paul Kinlan wrote:
> > On Tue, 20 Sep 2011, Paul Kinlan wrote:
> > >
> > > Q: Why are the verbs URLs?
> > >
> > > Verbs don't have to be URL's but a URL will allow us a point of 
> > > reference to documentation, versioning and namespacing allowing 
> > > verbs with similar names but by a different provider to not conflict 
> > > with each other (thus allowing developers to come up with their own 
> > > schemes and APIs outside of standardisation).
> >
> > If they're just arbitrary strings, this should be made clearer.
> 
> We will strongly encourage a URL, so we might have to say it must be a 
> URI to make developers think of that first. A URL gives us a lot of 
> advantages (more below on your sharing point).
>
> > > Q: Why are some verbs hard-coded into the API?
> > >
> > > Convenience and ensuring there is a consistent use of the first set 
> > > of intents that cover the most common initial use cases.
> >
> > If the strings are inconvenient enough that you feel the need to 
> > provide a constant for them, maybe that's a sign that the strings 
> > should be changed!
> >
> > Rather than 'http://webintents.org/share', why not just 'share' for 
> > the share intent, for example?
> 
> Providing a single verb will vastly increase the chances that of 
> collision of competing providers saying they handle the action but 
> provide a completely different API.

There's no difference between two people coming up with the name "foo" and 
two people coming up with the name "http://webintents.org/foo", unless 
you're saying you're confident that people won't use the prefix the spec 
uses for its verbs for their verbs.

But this is a non-problem. In practice, we have plenty of examples of 
spaces where conflicts don't happen despite not having used long names 
such as URLs. For example:

 - rel="" values in HTML
 - element names in HTML
 - MIME type names
 - scheme names


> A verb on its own will imply that it is a web intents verb managed by 
> the webintents project and all the documentation for that will live 
> under webintents, which means we would then need to think about 
> standardisation and stewardship for the entire namespace.

I don't see why. Just have a wiki page that people can list their verbs on 
and then point to their documentation.


> Android is a good example, the intent system is fabulous, if you look at 
> http://www.openintents.org/en/intentstable most developers end up 
> reverse name-spacing the intent and I believe when people want to 
> namespace their API they will either use this syntax or some other 
> inconsistent naming.  Having a URL is nice and consistent with the web.

I think having a URL is very _in_consistent with the Web. Few technologies 
use URLs for verbs, and most of them have gone nowhere fast.

URLs are Web pages. Authors find it confusing when they are used for other 
things.


> > I'm not saying to actually use navigator.registerContentHandler and 
> > navigator.registerProtocolHandler, but why not base something on that 
> > API rather than reinventing the wheel?
> 
> We have two bits, one is registering the intent which we think is better 
> declaratively (explain more later in the email) and the second is the 
> invocation which we believe WI has a far simpler usage of the API and 
> can take advantage of postMessage.

I disagree that what you have is as simple as what you could have. In 
particular, what you have is definitely not as simple (nor as powerful) as 
the proposal I put at the end of my e-mail, for instance.


> Specifically we want to get away from having to wait for the remote app 
> to tell us it is ready before we pass it the data - which is what 
> happens if we currently use window.open with a scheme register with RPH 
> RCH etc.

The proposal I put forward does not have this problem.


> var intent = new Intent("http://webintents.org/share",
> "image/png", getData());
> window.navigator.startActivity(intent, function(data) {
>     doSomethingAwesome(data);
> });

   var port = navigator.handleIntent("share", "image/png");
   port.postMessage(getData());
   port.onmessage = function (event) { doSomethingAwesome(event.data) };


> > Sure, but what if the full interface is already open? Maybe Google+ is 
> > a better example: you could envisage the "Share" dialog appearing on 
> > the open Google+ page rather than opening an entirely new page just to 
> > share a post.
> >
> > I think this is an important case to support.
> 
> We thought about this, we didn't want to overwrite the current task that 
> the user was performing and we didn't want to have a user launch two 
> intents and overwrite what they we working on the previous invocation.

By not supporting the use case at all I think you are overcompensating. :-)

If an application wants to support this case, why not let it? With a model 
such as the one I propose, it's essentially free.


> > > Q: In particular, why are intents registered via a new HTML element 
> > > rather than an API? How do you unregister? How do you determine if 
> > > the intent was registered or not? How do you conditionally register 
> > > (e.g. once the user has paid for the service)?
> > >
> > > External discoverability, indexing and scraping is a very important 
> > > part of the intent tag understanding the API points of an 
> > > application is very powerful to external systems - via an API we 
> > > lose this ability, or at least make it fiendishly hard to discover.
> >
> > Could you elaborate on this need? What use case does it address?
> 
> We want to index and discover these apps so that we can provide a way to 
> offer suggested apps if the user doesn't have an app already installed.

That is an interesting use cae.

Are you interested in providing the same kind of functionality for scheme 
and content type handlers?


> We believe we have more flexibility with how we present registration of 
> intents to user by using a declarative markup.  The UA will be able to 
> batch up and aggregate requests to the user to install intents more 
> easily if they are present in the DOM than if there were arbitrary 
> individual requests to a register API.

There is no difference on this front. There's no reason an API call 
couldn't be batched up too.


> We also reduce the JS API surface by using the tag.

Actually you increase it, since elements have DOM interfaces.


> > Adding new elements (especially to <head>) is a high-cost affair and 
> > should be avoided unless there are really good reasons for it.
> 
> Sorry, in what sense?  In specification terms or implementation and 
> performance terms?

All three, as well as testing.


> > > Flexibility for the UA; the UA gets a much richer understanding of 
> > > the capabilities of an application, allowing it to have more control 
> > > of how it presents and manages the intents and registration to the 
> > > user.
> >
> > Could you elaborate on this? As far as I can tell it doesn't make any 
> > difference to the UA whether the registrations are declared via markup 
> > or via an API.
> 
> In particular the batching and aggregation of intent information to 
> present to the user at install time, we can do a lot of things easily if 
> it is in the DOM.

I don't see any difference here based on whether it's an element or an 
API.


> > > If it is available as a tag it allows screen-readers or other 
> > > accessibility tools to be able to indicate that A) and intent might 
> > > need to be installed, or that B) the application is a handler for 
> > > something at load time rather than at some point in the applications 
> > > lifecycle.
> >
> > So does an API.
> 
> Only when it is invoked.

No; when it is invoked or any later time. Same as with an element: when 
it's added to the document or any later time.


> > > Developer experience is another important reason for the tag: We 
> > > didn't want the developers to have to think too hard about enabling 
> > > their apps to receive data; questions developers ask often of an API 
> > > is "when should I call the code", should it be in onload, before, 
> > > after? Given our experience working with developers, the more steps 
> > > or potential questions that are raised in a developers head about 
> > > implementing functionality, the more likely they are to 
> > > de-prioritise the work in favor of other work.
> >
> > I think this dramatically overstates the complexity here. Authors 
> > could call the API whenever they want; simple guidelines can be 
> > trivially given in the same amount of room as it takes to tell authors 
> > to use a new element.
> 
> hmm, not sure, I have worked supporting developers on a lot of web apis 
> (to me they were very simple APIs) and I have heard a lot of them with 
> the troubles mentioned and they simply de-prioritise the work in favor 
> their other priorities.

The same happens with elements, attributes, everythign on the Web 
platform. Nothing new here. :-)


> > > Unregistering would be handled by the UA's management interface 
> > > directly by the user.
> >
> > So how does a site that has stopped providing a feature unregister its 
> > handler for that feature?
> 
> I would be surprised if apps use any unregister feature.

We've received requests -- including from Google! -- to allow sites to 
unregister content and protocol handlers. I see no reason to think it 
would be different here.


> We need to update the spec.  The UA should track the pages that declare 
> intent registration and if the user has the intent installed and the tag 
> is no longer on the tracked page(s) the UA should remove the 
> registration.

This would not work well with sites that only show the intent element to 
users who are logged in with an account that is fully paid up...


> > Here's a possibly simpler proposal:
> >
> >  - to register:
> >
> >   navigator.registerIntentHandler(intent, filter, url, kind);
> >     intent = string like "share", "play"
> >     filter = MIME type (foo/bar) or MIME wildcard (foo/* or */*)
> >     url = page to load to handle intent
> >     kind = a flag indicating if the page should be:
> >       - always opened in a new tab
> >       - opened in the intent handler dialog (inline/pop-up)
> >       - opened in an existing tab if possible, else a new tab
> >
> >  - to check if registered, to unregister:
> >
> >   navigator.isIntentHandlerRegistered(intent, filter, url);
> >   navigator.unregisterIntentandler(intent, filter, url);
> >
> >  - to invoke intent:
> >
> >   var port = navigator.handleIntent(intent, filter);
> >   port.postMessage(data);
> >   port.onmessage = function (event) { handle(event.data) };
> 
> We thought about this, we didn't want developers to have to worry about 
> when they think they should start to postMessage, or finish listening to 
> the onmessage event.

What is there to think about? They send one message, they receive one 
back. I don't understand why this would be complicated.


> The temptation would be to port.postMessage(data); 
> port.postMessage(data); and in this case what should happen in the app.

That's entirely up to the definers of the protocol for that action. 
Indeed, if, as you point out, you can pass a port to the other side as 
part of the data anyway, the exact same problem exists with your current 
API. It's just simpler to do in the proposal above.

-- 
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

Received on Thursday, 22 September 2011 21:39:16 UTC