Hi all - as we discussed in the last meetup, I've been circulating and discussing options for the provider's API.
As we left things at the end of the meetup, there was strong support for the window.intent approach from the Chrome team, but equally strong misgivings (from Tyler and me) that there was no secure way to include this using a JS API. We had just started to mock up a safe API (something like #4, below) but we didn't get to something concrete. I'm having a hard time getting any agreement on this side until we have something that can be on-boarded through an included JS API.
In the interest of moving things forward, here's my understanding of the options - I'm including Introducer, Tyler, since we talked about it during the last meetup.
I know that the Chrome team had previously tried something like #4 and backed away from it. Can you please give us an explanation of where you hit problems with that? That would help us understand the tradeoffs with #1.
Style 1:before page loads, window.intent is loaded with the intent object
if (window.intent) {
if (window.intent.action == SOME_ACTION) {
doWork(window.intent.data);
window.intent.postResult( ... );
}
}
Style 2:
use event listeners
document.addEventListener("onIntent", function(intent) {
if (intent.action == SOME_ACTION) {
doWork(intent.data);
intent.postResult( ... );
}
})
Style 3:
use a registration function, providing the action as input
window.registerIntentHandler(SOME_ACTION, function(intent) {
doWork(intent.data);
intent.postResult( ... );
});
Style 4:
register a single function
window.registerIntentHandler(function(intent) {
if (intent.action == SOME_ACTION) {
doWork(window.intent.data);
window.intent.postResult( ... );
}
});
Style 5:
use a registration function, passing a message port at call time
introducer.accept(function(port, intentList, origin) {
if (actionInIntentList(SOME_ACTION, intentList)) {
doWork(port.read());
...
port.write( ... );
}
});
Style 1:
+ Indicates clearly that the reason for this window is this intent
+ Unforgable if inserted by UA
+ Removes all racy-ness from API; all data is ready to go
+ Potentially very quick; intent could be satisfied on very first execute call
- Requires that intent data be assembled before window can execute (slow?)
- No clear indication that an intent is not supported; perhaps postError?
- No support for multi-step/back-and-forth interactions
- No way to reuse a single window for multiple calls; limits interactive use cases
-- Currently no safe way to do from a JS API
Style 2:
++ Very DOM-y and idiomatic for web programmers
- No clear indication that an intent is not supported; perhaps postError?
--- Insecure; can be spoofed from other pages on the same domain
Style 3:
+ Somewhat DOM-y and idiomatic for web programmers
+ Unforgable if inserted by UA
+ Has clear indication that an intent is supported
+ Can be safely injected from JS API
- Feels racy - UA is required to park the intent data and wait until it thinks it's safe to fire the intent - perhaps onload?
Style 4:
+ Perhaps a bit more DOM-y and idiomatic; feels like a special kind of addEventListener
+ Unforgable if inserted by UA
+ Can be safely injected from JS API
- No clear indication that an intent is not supported; perhaps postError?
- Somewhat less racy - can the UA fire as soon as it sees registerIntentHandler? Probably not; it would be idiomatic to let the script execution terminate before we fire.
Style 5:
+ Intent can't be replayed
+ Port is a persistent connection which can be passed to other contexts and benefits from existing MessagePort implementations
+ Persistent bidirectional communication channel
- Intent can't be replayed (e.g. if authn is required)
- Requires building an RPC format abstraction on top of raw pipe; more moving parts, more complexity