Hi everyone,
Today Mounir and I worked on this and a few related APIs. The
resulting suggestions are below.
On Mon, May 7, 2012 at 12:00 PM, Kan-Ru Chen <
kc...@mozilla.com> wrote:
>> It is a bit strange that the 'onalarm' event handler is on the global
>> manager object and not on the 'Alarm' object itself.
>
> Like I said before, we need to fire the event even if the application is
> not running. The flow as I understand is like:
>
> Alarm expired -> Fire system intent -> App started -> the App binds
> the alarm handler to AlarmManager -> Fire alarm event
The problem with this approach is that it means that we can't fire the
alarm until the page is "fully loaded". However defining "fully
loaded" is a bit tricky on the web. We could fire the alarm event
sometime after DOMContentLoaded has fired. This generally means after
the whole DOM has been parsed and most of the <script>s have executed.
However not all <script>s have executed when DOMContentLoaded fires.
For example any <script>s with the async attribute set might not have
loaded. Also, it's very common today on the web to use various script
loaders which asynchronously load scripts using
createElement("script") and setting .src. Such scripts might also not
have loaded and so haven't had time to register alarm event listeners.
So we could wait until the "load" event is fired on the page. That
will ensure that <script>s with the async attribute set will have
loaded and have executed. But again, scripts loading using script
loaders might not even be started until the "load" event fires.
Additionally, waiting for "load" or DOMContentLoaded firing could in
many cases be waiting too long. An app can have been rendering for a
long time by the time that DOMContentLoaded fires. This could result
in a bad user experience where the app loads and renders in its
default state, and then suddenly changes once the alarm event fires.
Users likely expect the app to render in the correct state right away.
We had exactly this problem when designing the pushState API and ended
up having to do a last-minute change of the API and move away from
delivering data to a loading page using an event. There simply was no
good way to make events work as a delivery mechanism.
Instead we propose that we expand the capabilities of "system intents"
such that when an app is opened using a system event, the app can
request to get information about why it was started right away. I.e.
at any point during the loading of an app can the app state to the
platform that it is ready to receive events. That way it can ensure to
render in the right state right away.
So if it was started due to an alarm, the app gets the information
about this alarm using not using an event, but using the messaging
mechanism of system intents.
I'll start a separate thread about how these "system intents" will be
used to start applications and deliver messages to them.
But assuming that we remove the actual notifying part from the API,
here is the API that I suggest we use for the Alarm API:
partial interface Navigator {
readonly attribute AlarmsManager alarms;
};
interface AlarmsManager {
DOMRequest get();
long add(Date date, optional DOMString ignoreTimezone, optional any data);
void remove(long);
};
The 'add' function returns an id for the alarm. This id is used to
unregister alarms that the application is no longer interested in
receiving.
The 'remove' function simply unregisters a previously registered alarm.
The 'get' function asynchronously returns an array of all registered
alarms for that application. The array is basically a JSON object
which looks like:
[{ id: 1, date: <dateObject>, ignoreTimezone: true, data: ... },
{ id: 2, date: <dateObject>, ignoreTimezone: false, data: null },
...]
To register alarm callbacks you'd do something like:
id1 = navigator.alarms.add(new Date("2012-08-30"), "honorTimezone", {
mydata: "foo" });
id2 = navigator.alarms.add(new Date("2012-08-31"), "ignoreTimezone");
Again, since "system intents" is a somewhat orthogonal discussion,
i'll start a separate thread on how the delivery mechanism will work.
/ Jonas