Re: Adding Web Intents to the Webapps WG deliverables

Hey Ian, comments in-line.

On Thu, Sep 22, 2011 at 2:36 PM, Ian Hickson <ian@hixie.ch> wrote:

> 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
>
>
We are following the model set by Android Intents by bootstrapping the
feature with a list of actions that we agree will be far-reaching and
useful, e.g., share, pick, edit, save.

The Android Intents system employs java-style namespacing,
e.g., android.intent.action.EDIT is the string value of the ACTION_EDIT
constant.  The idea is that vendors can add to the intent ecosystem by
creating new actions, usually by setting the namespace appropriately,
e.g., org.openintents.action.CALCULATOR.

When designing the format of the Web Intents action string, we got a lot of
feedback that the java namespacing is not native to the web and that URLS
would be a better namespacing scheme.  This gave us the added benefit that,
by setting precedence with the default list actions, action URLs serve both
as a namespace mechanism and the page at the URL contains documentation for
the particular action.  If a developer wants to find out more about
http://webintents.org/share, all she has to do is visit that URL (try it!).

If, for example, Twitter decided to add a new action, say 'tweet', they
could set the action string to http://dev.twitter.com/tweet which would
contain the input/output specification for this action.


> 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.
>
>
We plan to employ a model such as this.  openintents.org currently lists
third-party intents for the Android system, though we could use that site to
enumerate Web Intents.


>
> > 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?
>
>
I had a thought earlier today about making the <intent> tag more generic
(even in name) to include the ability to declaratively register
protocol/content handlers as well.

Android apps have declarative support via manifests, and we are currently
adding declarative support to Chrome apps (Mozilla is doing the same).
 There is a lot of room for innovation given the ability to index intent
registrations for apps and sites.


>
> > 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.
>
>
Yes, this is a common issue that we need to solve, and it's likely the
solution for Intents will apply to RPH/RCH.


>
> > 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...
>
>
Can you expand on this?  I don't see the problem.  The intent element can be
dynamically removed, if needed, and the intent will be unregistered in the
UA.  If it happens at invocation point (likely), the service has a chance to
ask the user to pay 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.
>
>
When does the port close?
What happens if I call postMessage() again, after receiving the response
from the service?

We designed the API to be as simple as possible, in this case by being
explicit.  Less questions need to be asked, less chances to shoot oneself in
the foot.


>
> > 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.   `._.-(,_..'--(,_..'`-.;.'
>

Thanks,
James

Received on Thursday, 22 September 2011 22:28:55 UTC