[webkit-dev] Web Notifications API

John Gregg johnnyg at google.com
Thu Feb 9 11:01:56 PST 2012


On Thu, Feb 9, 2012 at 9:53 AM, Jon Lee <jonlee at apple.com> wrote:

>
> On Feb 8, 2012, at 5:41 PM, John Gregg wrote:
>
> 3. Use static functions on the notification constructor for permissions
>> checks.
>>
>> By moving them there, it allows us to remove window.webkitNotifications
>> and the NotificationCenter class, cleaning up the API.
>>
>
> I think that would be consistent with moving from a factory model to a
> constructor model.  The Feature-permissions effort was intended to create a
> common interface for handling permissions, but it may still be too far off
> and sticking with a scoped approach is more practical.  The only concern is
> that it is an implementation change that only partially reaches what has
> been spec'd, which might leave some continuing confusion among users of
> Notifications as to the authoritative version of the interface.
>
>
> Which missing aspects of the Feature permissions spec are you concerned
> about?
>

I was only referring to the fact that the spec calls for a separate generic
interface for permissions with a parameter that identifies the feature
[FeaturePermissions.permissionLevel("notifications")], and in this case it
would still be attached to the Notifications interface
[Notifications.permissionLevel()].


>  4. Adjust the permission functions.
>>
>> WebKitNotification.permissionLevel() --> String
>>
>> Similar to checkPermissions(), synchronous call. The name aligns with
>> similar functionality in the DAP Feature Permissions spec [FEAT], but
>> scoped specifically to Web Notifications. Returns one of three strings:
>> "granted", "denied", and "default". This follows the current best practice
>> from the WebApps WG where strings are being used instead of enums.
>>
>> WebKitNotification.requestPermission(callback)
>>
>> An asynchronous call, as it is currently. The callback specified includes
>> one argument which represents the permission, similar to the return values
>> in permissionLevel(). (Currently it is just a void callback.) If the user
>> had already made a policy decision, then the callback is invoked
>> immediately (with either "granted" or "denied"). Otherwise the UA may ask
>> the user for permission, and the callback is invoked when the user makes a
>> decision (cancelling the request does not invoke the callback). Any
>> notifications posted in the meantime would be queued until then. Multiple
>> calls to this function should just result in one visible request.
>>
>
> This matches the FeaturePermissions spec with the exception of the
> decision as a parameter, which is reasonable though redundant since the
> current permission level is already easily read.  The queueing of
> notifications discussed later.
>
>
> It could work either way. But for me, it seems weird from a programming
> flow perspective to have to explicitly fetch the level again within the
> callback; I would expect the response to be included in some form as an
> argument.
>
>
>> 5. Remove replaceId.
>>
>> This could already be done by canceling a previous notification and
>> posting a new one. The idea of replacing a notification with another one
>> without alerting the user is a feature that we don't intend on supporting.
>>
>
> Just so the use case is clear here, it is not equivalent to canceling and
> showing from the webapp's perspective, though it is to the browser.  The
> reason for replaceId is when the same application (e.g., Gmail) is open in
> multiple browser windows.  When a new message arrives, both tabs will
> discover this and lacking communication between them, attempt to show a
> notification.  But if both notifications are tagged as corresponding to the
> same real-world event, they are seamlessly merged and the user only sees
> one.
>
>
> But in this case, wouldn't the second notification just be ignored,
> instead of replacing the first notification?
>

Ignored or replaced, you still need a way of tagging them.  I still think
replacement is better, since it also gives you the benefit of the most
recent information when it's something other than exact copies.  That
brings up another use case when you do get frequent updates, say for chat
notifications (one per incoming line of text, typically) - use a single
replaceId for the chat session and just update it with the latest message.
This can be done with cancel/show, but multiple chats or other
notifications, the notifications would be constantly re-ordering and the
end-user experience is not good.


> Also, does Chrome keep track of IDs that have been shown, even after the
> notification has been closed? For example, if one page gets the new email
> before the other, it posts a notification, the user clicks on that
> notification, and the page closes that notification _before_ the other page
> has had a chance to query Gmail's servers for new emails, does Chrome still
> remember that a notification of that ID was posted before?
>
> Or does this only apply for notifications that are shown but not closed?
>

The replacement logic in Chrome only applies for notifications that are
still active (shown or in the display queue).  You are correct that there
is a potential race condition that would allow the double show.  In
practice (Gmail actually does this) I've never encountered this... I think
Gmail's use of replaceId has probably saved me hundreds of duplicate
notifications due to multiple tabs.

Overall my opinion on replaceId is that it's quite useful practically, and
we already have real world examples of that usefulness. The argument
against is it's too complicated?  I don't agree - chromium already does it,
some platforms support it natively (e.g., Ubuntu NotifyOSD) and other user
agents can easily do close+open internally if live-replacement is not
practical.


>  6. Improve show() behavior.
>>
>> Calling show() when the site has been denied permission should call
>> onerror(). If no decision was made, then the notification should remain
>> queued, and only until after the user has decided should onshow() or
>> onerror() be called. I also think show() can only be used once. Subsequent
>> invocations should call onerror().
>>
>
> The permission-denied behavior you want is as spec'd (error event).  The
> permission-unknown behavior you propose seems more difficult for authors,
> since at the point of calling show() it would be impossible to distinguish
> between being queued for space limitation and being queued waiting for
> permission.  If you limit this to the case where requestPermission() has
> already been called, as opposed to any permissionLevel=unknown state, that
> might make more sense.  We could even introduce a new constant for
> permissionLevel of "request-pending" which would make this easy to specify
> cleanly.
>
>
> I think authors should use available API. So those who choose not to use
> requestPermission() end up having to deal with that ambiguity. Also, why
> does that ambiguity need to be differentiated? How would a website change
> its behavior based on that knowledge?
>

I assume permissions might change.  Maybe a user goes into their browser
settings and reverts to the default permission.  The app doesn't know this
and will continue showing notifications without knowing that these are
queued up waiting for permission that hasn't been requested yet.  In the
current design there is no ambiguity, because those show() calls will fail
informing the app it needs to request permissions.

Adding the "request-pending" permission state separate from "unknown" (and
queueing in the "request-pending" state only) would address that problem
and allow for the deferred-show behavior you want.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-dev/attachments/20120209/09a3dd42/attachment.html>


More information about the webkit-dev mailing list