Re: [whatwg] Fetch Objects and scripts/stylesheets

2014-08-18 Thread Anne van Kesteren
On Thu, Aug 14, 2014 at 5:28 PM, Nils Dagsson Moskopp
 wrote:
> Ben Maurer  writes:
>> Another concrete example with  tags: sometimes an abusive user will
>> use a site like Facebook as a CDN -- they'll upload a picture and hotlink
>> it from elsewhere. We could insert a time-stamped authentication token as a
>> custom header. Today we sometimes do this via the query string -- giving
>> the user a token that lasts for a few days. This means we bust the user's
>> cache every time we rotate the token. With a custom header, the browser
>> cache stays in tact.
>
> Why not just check the referer or origin header and act on that?

That is not tied to the user.


>> Images would also be a great example of where logging headers could be
>> extremely helpful. For example, we could log what module within a page
>> rendered an image and monitor bandwidth usage and CDN cache hit rate on a
>> per module basis. In the past it's taken us a long time to debug issues
>> that could easily be found with this method.
>
> This means more analytics and logging – privacy intrusions justified by
> the sheer complexity of systems created by several thousand monkeys on
> thousands of electronic typewriters. Incidentally, more fingerprinting.
>
> I do not see any immediate benefit to the user here.

They can get this either way. E.g. the token could be put in the URL
as well. Allowing custom headers makes the setup a bit nicer and
actually allows developers to use the "strengths" of HTTP.


-- 
http://annevankesteren.nl/


Re: [whatwg] Fetch Objects and scripts/stylesheets

2014-08-18 Thread Anne van Kesteren
On Wed, Aug 6, 2014 at 12:24 PM, Anne van Kesteren  wrote:
> I filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=26533 on
> investigating whether we can reuse the Request object (which is passed
> to fetch(), and used in service workers to expose requests from a
> window or worker). There are some complications given what can be set
> through HTML and what could be set through script and how to keep
> those best synchronized.
>
> We should be able to figure something out I think. Not sure how high
> of a priority this is though.

As an update, Ian proposed a more concrete plan in the bug that I
think will work. I recommend people copy themselves to the bug if they
want to give further feedback.


-- 
http://annevankesteren.nl/


Re: [whatwg] Feature-detectable WakeLocks

2014-08-18 Thread Kornel Lesiński

>> I'd prefer if individual lock types were instances of objects, e.g. 
>> navigator.*Lock objects could be instances of a variant of the WakeLock 
>> interface:
>> 
>> navigator.screenLock.request();
>> navigator.screenLock.isHeld();
>> 
>> navigator.cpuLock.request();
>> navigator.cpuLock.release();
>> 
> Personally, this doesn't strike me as good API design. It means having a 
> bunch of attributes that all use the same class but only differ in name.

Really?

I think clearly separating different classes of locks (with a common base 
class) is much better than conflating them behind a weakly typed string-driven 
API.

It's like:
Element.firstChild.getAttribute(…);
Element.nextSibling.getAttribute(…);
 
instead of:
Element.getAttribute("firstChild", …);
Element.getAttribute("nextSibling", …);

>> Alternatively, if the WakeLock was instantiable (to have a standard way for 
>> independent page components to share locks) then these objects could be 
>> constructors:
>> 
>> if (navigator.ScreenLock) {
>> var lock = new navigator.ScreenLock();
>> …
>> lock.release();
>> }
>> 
>> (or `new navigator.wakeLocks.Screen()`, etc.)
> We don't have any APIs like this today on the Web.  It would be weird :)  

"Weird" is subjective and a vague criticism. Can you elaborate what's wrong 
with that?

> It would just be better to have a constructor on the interface: `new 
> WakeLock("screen")` or whatever.  

I don't see any benefit in obscuring types of the objects. 

String-driven API doesn't allow simple feature detection, and a single type 
that conflates all lock types makes extensibility uglier. You won't be able to 
elegantly add methods that are valid only for some types of locks, e.g. `new 
WakeLock("cpu").dimScreen()` is nonsense, but would valid from perspective of 
WebIDL and JS prototypes.

-- 
regards, Kornel





Re: [whatwg] Proposal: Wake Lock API

2014-08-18 Thread Kornel Lesiński
> On Monday, August 18, 2014 at 6:24 PM, Kornel Lesiński wrote:
> 
>> I think it'd be unfortunate if this API had just one shared lock per 
>> browsing context and required components on the page to coordinate locking, 
>> but provided no means to do so.  
> 
> 
> The API allows scripts to check which locks are currently held (as either a 
> `isHeld()` or `getCurrentLocks()`, for which I just sent a PR for).   

I don't understand how is that helping.

Let's say I have embedded a Slideshare presentation and a YouTube video on my 
page. I start watching slides, then start playing the video, then finish 
watching slides.

When Slideshare finishes and wants to release the lock, it can't learn via this 
API whether YouTube still wants the lock. When Slideshare started isHeld was 
false, but setting it back to that original state would be incorrect. When 
Slideshare finished isHeld was true, but that doesn't tell anything either, 
since Slideshare itself set it to true.


The only way I see for coordinating lock between independent components on the 
page is not via isHeld(), but by defensively re-setting the lock.

In my previous example both Slideshare and YouTube would have to watch for 
'lost' events (but not via the Netscape-style onlost footgun!) and keep 
re-requesting the lock soon after it's been released, for as long as they need 
it.

IMHO that's really ugly.

If re-requesting is supposed to be the pattern for maintaining locks properly, 
then the whole API could be cut down to just events:

window.addEventListener('beforeScreenLock', function(e) {
if (stillShowingStuff) e.preventDefault();
}, false);

The browser would fire beforeScreenLock event every time the OS is about to 
turn the screen off. To keep the screen on for another while the page just 
needs to prevent the event.


>> This will force authors of libraries and components to create dummy iframes 
>> just to have their private lock, and libraries/pages without such workaround 
>> will be messing up each other's locks.
> 
> Currently, iframes are not allowed to have locks - only top-level browsing 
> contexts are. This is to avoid things like embedded ads from requesting wake 
> locks.   

That's a noble goal. However, it may not be effective against ads in practice, 
because majority of ads are embedded using 

Re: [whatwg] Preventing wake lock leaks with DOM nodes

2014-08-18 Thread Jonas Sicking
On Mon, Aug 18, 2014 at 5:35 PM, Marcos Caceres  wrote:
> The reason I didn't make it a boolean was because of the IPC involved and 
> because I wanted to support multiple types of locks without needing to add 
> new attributes in the future (and if we need to add the complex stuff later).

What's the problem with adding more attributes in the future?

That said, I do think that a "timeout" for screen locks make sense, so
a boolean wouldn't work. Though not as a timeout for when to release
the lock, but rather as a "minimum time I'd like to keep the screen
awake" as described at

http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2014-August/297423.html

/ Jonas


Re: [whatwg] Feature-detectable WakeLocks

2014-08-18 Thread Jonas Sicking
On Mon, Aug 18, 2014 at 5:37 PM, Marcos Caceres  wrote:
> On Monday, August 18, 2014 at 6:41 PM, Kornel Lesiński wrote:
>> WakeLock.request() expecting a string isn't very friendly to feature 
>> detection.
>
> The API tells you if a wake lock type is not supported by either rejecting 
> with a TypeError or by a DOMException whose name is NotSupportedError.

We've made this mistake before. See

http://robert.ocallahan.org/2012/05/canvas-getcontext-mistake.html

/ Jonas


Re: [whatwg] Proposal: Wake Lock API

2014-08-18 Thread Jonas Sicking
On Mon, Aug 18, 2014 at 4:37 PM, Marcos Caceres  wrote:
>> while(navigator.wakeLock.isHeld("screen")) 
>> navigator.wakeLock.release("screen"); // just release the damn thing in my 
>> leaky code!
>
> That would just halt the browser as the script would never complete: 
> currently releasing happens async once the system acknowledges that the 
> release has been granted. I'm not sure if there is a use case for that 
> behavior - it's just what is currently/sorta roughly proposed in the spec.

I don't think the sync part was the important aspect here. You could
easily rewrite that as an async loop.

The point is that it's easy for developers to end up trying to work
around bugs in their own code by simply doing extra releases. Or end
up with bugs where they accidentally release too many times and so
stomp on other components.

>> Therefore, if WakeLock needs to be purely JS API, I strongly prefer having 
>> WakeLock available only as an object instance, but without exposing GC 
>> behavior--if it's lost, it's like a missing release call.
>>
>> If devtools ever get monitoring of unhanded errors in Promise objects, they 
>> could also warn against lost WakeLock objects--it's the same type of problem 
>> dependent on GC.
>>
>> I'm assuming that release would work only once on each lock object:
>>
>> var lock = new WakeLock("screen");
>> lock.release();
>> lock.release(); // ignored, so it doesn't unlock any other component's lock
>>
>> This makes coordination easier: each page component can easily create their 
>> own lock independently (without needing to create an iframe to get their own 
>> lock), and can't release any other component's lock.
>
> Personally, I don't know if I agree that it makes coordination easier. Seems 
> that having a centralized place to check what is currently being held makes 
> life a lot easier, because it allows scripts to check if they actually need 
> to request a lock or not.

Why does the ability to check if a lock is held make coordination
easier? Checking if they need to request a lock or if someone else is
already doing it seems like a very bad code pattern which actually
makes coordination harder. It makes it very easy to get confused and
try to rely on party X to hold a lock, but then it turns out that in
reality it was Y holding the lock, but Y releases the lock much sooner
and now end up holding a lock for a shorter time than intended.

Am I missing something?

> If you have some objects requesting and others releasing, then it makes a 
> huge mess because you need to track down which object screwed up the lock.

This is not what the proposal is. The proposal is that if a WakeLock
instance x is used to grab a lock, then the lock will be held until
x.release() is called. Any calls on other WakeLock instances will not
cause the lock to be released. Only one all WakeLock instances that
have had request() called on them also gets a call to release(), does
the lock get released.

Losing track of the instance that you called request() on, then that
is equivalent to losing track of how many time you have called
wakeLock.request(x). There is no way to get correctly out of that
situation.

> And if GC also then works to release the locks, then there is no certainty as 
> to what is actually releasing the lock or when.

Can we please stop talking about GC. I don't think anyone has made a
serious proposal where GC releases a lock, or where GC is otherwise
exposed.

/ Jonas


Re: [whatwg] Feature-detectable WakeLocks

2014-08-18 Thread Marcos Caceres


On Monday, August 18, 2014 at 6:41 PM, Kornel Lesiński wrote:

> WakeLock.request() expecting a string isn't very friendly to feature 
> detection.

The API tells you if a wake lock type is not supported by either rejecting with 
a TypeError or by a DOMException whose name is NotSupportedError.  
  
>  
> I'd prefer if individual lock types were instances of objects, e.g. 
> navigator.*Lock objects could be instances of a variant of the WakeLock 
> interface:
>  
> navigator.screenLock.request();
> navigator.screenLock.isHeld();
>  
> navigator.cpuLock.request();
> navigator.cpuLock.release();
>  
Personally, this doesn't strike me as good API design. It means having a bunch 
of attributes that all use the same class but only differ in name.  
>  
>  
> Alternatively, if the WakeLock was instantiable (to have a standard way for 
> independent page components to share locks) then these objects could be 
> constructors:
>  
> if (navigator.ScreenLock) {
> var lock = new navigator.ScreenLock();
> …
> lock.release();
> }
>  
> (or `new navigator.wakeLocks.Screen()`, etc.)
We don't have any APIs like this today on the Web.  It would be weird :)  

It would just be better to have a constructor on the interface: `new 
WakeLock("screen")` or whatever.  

But then we are just back discussing the other email about GC, etc.  
> Having specific instances for different types of locks could also enable 
> elegant extensibility of the API, e.g.
>  
> var screenLock = new navigator.ScreenLock();
> screenLock.dimScreen(); // completely made-up API
>  
> var cpuLock = new navigator.CpuLock();
> cpuLock.setThreadPriority("low"); // completely made-up API
>  

IMO, this is not really different from:  

navigator.wakeLock.request("cpu", {
   setThreadPriority: "low"
});  

If we need to start returning an actual WakeLock objects in the future, we can 
add that.   






Re: [whatwg] Preventing wake lock leaks with DOM nodes

2014-08-18 Thread Marcos Caceres
(sorry, accidental send before!)


On Monday, August 18, 2014 at 8:10 PM, Domenic Denicola wrote:

> In general I feel this thread has taken a turn for the complex. Why don't we 
> just do what other platforms do, and provide a simple global request/release 
> mechanism (or toggleable Boolean property!), which developers can build on 
> top of? A lot of the ideas here seem to be trying to create the perfect, 
> developer-friendly, foolproof API. Some of them seem quite clever too, tying 
> to page visibility and the like. But all of them could be built, as 
> libraries, on top of a global request/release. That way users could get 
> reference counting if they want that, visibility-based locking if they want 
> that, promise-based locking if they want that, timeouts if they want those, 
> or even just not do any of those if their use case is simple enough that it 
> doesn't warrant anything more complicated than what they are already doing on 
> existing platforms.

The reason I didn't make it a boolean was because of the IPC involved and 
because I wanted to support multiple types of locks without needing to add new 
attributes in the future (and if we need to add the complex stuff later). The 
request()/release() mechanism is well suited for that, IMO. And it's also 
fairly simple, even if it vends a promise.

Admittedly, I could just make it a bunch of boolean attributes. The spec is 
kinda already designed to work that way (what lock is applied is just a flag, 
which is checked synchronously)... it's how `isHeld(lockType)` works.

About tying it to visibility, and time, etc. Those are nice to have, but can 
certainly do without for now. We already dropped the timeout stuff from the 
original spec - but certainly a nice to have in the future. Having said that, 
if we know that this API is going to be used in conjunction with scroll events, 
then we know we are going to have potential battery eating problems (beyond 
just keeping the screen on). 
> 
> We don't need to solve Hard Problems in Programming (TM) before we expose a 
> wake lock API. Leave that as a subsequent step, which users can do, while we 
> move on to exposing more missing platform capabilities
> 

Yeah, certainly want to keep it as simple as possible. Just want to cover 
keeping the screen on for now. 



Re: [whatwg] Preventing wake lock leaks with DOM nodes

2014-08-18 Thread Marcos Caceres



On Monday, August 18, 2014 at 8:10 PM, Domenic Denicola wrote:

> In general I feel this thread has taken a turn for the complex. Why don't we 
> just do what other platforms do, and provide a simple global request/release 
> mechanism (or toggleable Boolean property!), which developers can build on 
> top of? A lot of the ideas here seem to be trying to create the perfect, 
> developer-friendly, foolproof API. Some of them seem quite clever too, tying 
> to page visibility and the like. But all of them could be built, as 
> libraries, on top of a global request/release. That way users could get 
> reference counting if they want that, visibility-based locking if they want 
> that, promise-based locking if they want that, timeouts if they want those, 
> or even just not do any of those if their use case is simple enough that it 
> doesn't warrant anything more complicated than what they are already doing on 
> existing platforms.


 
> 
> We don't need to solve Hard Problems in Programming (TM) before we expose a 
> wake lock API. Leave that as a subsequent step, which users can do, while we 
> move on to exposing more missing platform capabilities 




Re: [whatwg] Preventing wake lock leaks with DOM nodes

2014-08-18 Thread Tab Atkins Jr.
On Mon, Aug 18, 2014 at 5:10 PM, Domenic Denicola
 wrote:
> In general I feel this thread has taken a turn for the complex. Why don't we 
> just do what other platforms do, and provide a simple global request/release 
> mechanism (or toggleable Boolean property!), which developers can build on 
> top of? A lot of the ideas here seem to be trying to create the perfect, 
> developer-friendly, foolproof API. Some of them seem quite clever too, tying 
> to page visibility and the like. But all of them could be built, as 
> libraries, on top of a global request/release. That way users could get 
> reference counting if they want that, visibility-based locking if they want 
> that, promise-based locking if they want that, timeouts if they want those, 
> or even just not do any of those if their use case is simple enough that it 
> doesn't warrant anything more complicated than what they are already doing on 
> existing platforms.
>
> We don't need to solve Hard Problems in Programming (TM) before we expose a 
> wake lock API. Leave that as a subsequent step, which users can do, while we 
> move on to exposing more missing platform capabilities

Nope, doesn't work.  You can't build anything more complex on top of a
simple request/release (or a boolean, which is equivalent), because
any other library can come along and screw with the lock.  So, if we
want this to be extensible, we still need to design it in a localized
way so that you can have multiple independent locks.

If we did that, we *could* then layer a visibility/promise-based thing
on top as an auto-release mechanism for a specific lock.  But you've
still got to solve at least one problem correctly.

~TJ


Re: [whatwg] Preventing wake lock leaks with DOM nodes

2014-08-18 Thread Domenic Denicola
In general I feel this thread has taken a turn for the complex. Why don't we 
just do what other platforms do, and provide a simple global request/release 
mechanism (or toggleable Boolean property!), which developers can build on top 
of? A lot of the ideas here seem to be trying to create the perfect, 
developer-friendly, foolproof API. Some of them seem quite clever too, tying to 
page visibility and the like. But all of them could be built, as libraries, on 
top of a global request/release. That way users could get reference counting if 
they want that, visibility-based locking if they want that, promise-based 
locking if they want that, timeouts if they want those, or even just not do any 
of those if their use case is simple enough that it doesn't warrant anything 
more complicated than what they are already doing on existing platforms.

We don't need to solve Hard Problems in Programming (TM) before we expose a 
wake lock API. Leave that as a subsequent step, which users can do, while we 
move on to exposing more missing platform capabilities

> On Aug 18, 2014, at 19:52, "Marcos Caceres"  wrote:
> 
> 
> 
>> On Monday, August 18, 2014 at 7:21 PM, Kornel Lesiński wrote:
>> 
>> My biggest concern with the WakeLock API is that it's easy to forget (or 
>> fail) to release the lock.
>> 
>> It's not a problem with the API per se, but a programming problem in 
>> general: resource management in non-trivial programs is hard. WakeLocks are 
>> especially problematic in this regard, as a "leaked" lock won't cause any 
>> immediate problems for the developer, so this type of bug can easily go 
>> unnoticed.
> 
> Sure. At least on a mobile device, it's easy enough for the user to turn off 
> the screen (or just switch apps or browser tabs)... on laptops, it could be a 
> problem. However, MacOS (at least) is pretty good at telling users if an app 
> is eating too much battery. So this could be also handled at the system 
> level.  
>>  So I think lifetime of WakeLocks needs to be attached to something visible 
>> to make failure to we release the lock immediately obvious.
>> 
>> 
>> In case of screen lock it's especially easy: the whole purpose of this lock 
>> is to keep something visible on screen, so we can require that something to 
>> be explicitly connected to the lock.
> 
> I think that would be nice, actually. It's at least a kinda workaround to 
> having to check if something is in the drawable area manually.  
> 
> However, it still doesn't really deal with the case where the dev forgets to 
> release the lock. What is nicer is combining this with a timeout:
> 
> navigator.wakeLock.request("screen", {element: myCanvas, timeout: 
> aFewMinutes});
> 
> That would be the most ideal solution for me personally. Just set it, and 
> forget it.  
> 
>> It's nearly impossible to forget to remove a visible DOM element from the 
>> document — the mistake is likely to be quite obviously visible. If screen 
>> lock lifetime was dependent on visibility of a DOM element, then it would 
>> also be very hard to leak the lock without noticing it!
>> 
>> (that's a variant of "wake-lock:display" CSS proposal, but less explicitly 
>> dependent on CSS).
> 
> Yes, absolutely. So long as CSS lacks some way to detect if something is 
> offscreen, it makes sense. The current ways of checking if an element is 
> within the viewport are quite expensive (bunch of jQuery plugins do this - 
> and I think they depend on the onscroll event).  
>> With CPU lock it's less clear cut. I think tying it to a notification may be 
>> a good idea.
> 
> Need to think about it.  
>> Alternatively, perhaps the lock itself could be an instance of the 
>>  element that author is supposed to insert to the document? ;)
> 
> heh:) Yeah, need to think about that.   
> 
> 


Re: [whatwg] Preventing wake lock leaks with DOM nodes

2014-08-18 Thread Marcos Caceres


On Monday, August 18, 2014 at 7:21 PM, Kornel Lesiński wrote:

> My biggest concern with the WakeLock API is that it's easy to forget (or 
> fail) to release the lock.
>  
> It's not a problem with the API per se, but a programming problem in general: 
> resource management in non-trivial programs is hard. WakeLocks are especially 
> problematic in this regard, as a "leaked" lock won't cause any immediate 
> problems for the developer, so this type of bug can easily go unnoticed.

Sure. At least on a mobile device, it's easy enough for the user to turn off 
the screen (or just switch apps or browser tabs)... on laptops, it could be a 
problem. However, MacOS (at least) is pretty good at telling users if an app is 
eating too much battery. So this could be also handled at the system level.  
> So I think lifetime of WakeLocks needs to be attached to something visible to 
> make failure to release the lock immediately obvious.
>  
>  
> In case of screen lock it's especially easy: the whole purpose of this lock 
> is to keep something visible on screen, so we can require that something to 
> be explicitly connected to the lock.

I think that would be nice, actually. It's at least a kinda workaround to 
having to check if something is in the drawable area manually.  

However, it still doesn't really deal with the case where the dev forgets to 
release the lock. What is nicer is combining this with a timeout:

navigator.wakeLock.request("screen", {element: myCanvas, timeout: aFewMinutes});

That would be the most ideal solution for me personally. Just set it, and 
forget it.  
  
> It's nearly impossible to forget to remove a visible DOM element from the 
> document — the mistake is likely to be quite obviously visible. If screen 
> lock lifetime was dependent on visibility of a DOM element, then it would 
> also be very hard to leak the lock without noticing it!
>  
> (that's a variant of "wake-lock:display" CSS proposal, but less explicitly 
> dependent on CSS).

Yes, absolutely. So long as CSS lacks some way to detect if something is 
offscreen, it makes sense. The current ways of checking if an element is within 
the viewport are quite expensive (bunch of jQuery plugins do this - and I think 
they depend on the onscroll event).  
> With CPU lock it's less clear cut. I think tying it to a notification may be 
> a good idea.

Need to think about it.  
> Alternatively, perhaps the lock itself could be an instance of the  
> element that author is supposed to insert to the document? ;)

heh:) Yeah, need to think about that.   




Re: [whatwg] Proposal: Wake Lock API

2014-08-18 Thread Marcos Caceres



On Monday, August 18, 2014 at 6:24 PM, Kornel Lesiński wrote:

> I think it'd be unfortunate if this API had just one shared lock per browsing 
> context and required components on the page to coordinate locking, but 
> provided no means to do so.  


The API allows scripts to check which locks are currently held (as either a 
`isHeld()` or `getCurrentLocks()`, for which I just sent a PR for).   
> This will force authors of libraries and components to create dummy iframes 
> just to have their private lock, and libraries/pages without such workaround 
> will be messing up each other's locks.

Currently, iframes are not allowed to have locks - only top-level browsing 
contexts are. This is to avoid things like embedded ads from requesting wake 
locks.   
> Having just a single shared DOM0-style event handler 
> navigator.wakeLock.onlost looks especially jarring. I would expect this to be 
> a proper DOM event that can be used with normal addEventListener (please 
> avoid repeating the mistake of matchMedia).

Oops! I forgot to put that `WakeLock` inherits from `EventTarget`. It's always 
been the intention that you will have .addEventListener! I've sent a PR to fix 
this.  
> To make some coordination possible, the simplest method could be to keep 
> track of number of lock requests and releases, like retain/release in 
> Objective-C:
>  
> navigator.wakeLock.request("screen"); // locks
> navigator.wakeLock.request("screen"); // increases lock count
> navigator.wakeLock.release("screen"); // not released yet, but decreases lock 
> count
> navigator.wakeLock.release("screen"); // now released for real


In my dummy implementation, I've just been using (the Swift equivalent of):
[UIApplication sharedApplication].idleTimerDisabled = YES;


On MacOS, I thought the "right thing to do" (tm) according to Apple was [1] 
(see listing 2)? I'm pretty sure that's what we do already in Gecko for videos 
as we've been investigating repurposing the video code for wake locks.  

So, I've not seen the request/release behavior you describe above (at least not 
in the context of wake locks on MacOS/iOS). I guess it's used as an idiom maybe 
in other places?
> However, as you probably know from Objective-C,

Full disclosure, I barely know objective-c ;)
> perfect balancing of retain/release takes care and discipline. Personally, I 
> wouldn't trust all 3rd party libraries/widgets/ads to be careful with this. 
> In fact, I expect some "clever" libraries to ruin this with:
>  
> while(navigator.wakeLock.isHeld("screen")) 
> navigator.wakeLock.release("screen"); // just release the damn thing in my 
> leaky code!
That would just halt the browser as the script would never complete: currently 
releasing happens async once the system acknowledges that the release has been 
granted. I'm not sure if there is a use case for that behavior - it's just what 
is currently/sorta roughly proposed in the spec.  
> Therefore, if WakeLock needs to be purely JS API, I strongly prefer having 
> WakeLock available only as an object instance, but without exposing GC 
> behavior—if it's lost, it's like a missing release call.  
>  
> If devtools ever get monitoring of unhanded errors in Promise objects, they 
> could also warn against lost WakeLock objects—it's the same type of problem 
> dependent on GC.
>  
> I'm assuming that release would work only once on each lock object:
>  
> var lock = new WakeLock("screen");
> lock.release();
> lock.release(); // ignored, so it doesn't unlock any other component's lock
>  
> This makes coordination easier: each page component can easily create their 
> own lock independently (without needing to create an iframe to get their own 
> lock), and can't release any other component's lock.
Personally, I don't know if I agree that it makes coordination easier. Seems 
that having a centralized place to check what is currently being held makes 
life a lot easier, because it allows scripts to check if they actually need to 
request a lock or not. If you have some objects requesting and others 
releasing, then it makes a huge mess because you need to track down which 
object screwed up the lock. And if GC also then works to release the locks, 
then there is no certainty as to what is actually releasing the lock or when.   


[1] https://developer.apple.com/library/mac/qa/qa1340/_index.html


Re: [whatwg] Preventing wake lock leaks with DOM nodes

2014-08-18 Thread Tab Atkins Jr.
On Mon, Aug 18, 2014 at 4:21 PM, Kornel Lesiński  wrote:
> My biggest concern with the WakeLock API is that it's easy to forget (or 
> fail) to release the lock.
>
> It's not a problem with the API per se, but a programming problem in general: 
> resource management in non-trivial programs is hard. WakeLocks are especially 
> problematic in this regard, as a "leaked" lock won't cause any immediate 
> problems for the developer, so this type of bug can easily go unnoticed.
>
> So I think lifetime of WakeLocks needs to be attached to something visible to 
> make failure to release the lock immediately obvious.
>
>
> In case of screen lock it's especially easy: the whole purpose of this lock 
> is to keep something visible on screen, so we can require that something to 
> be explicitly connected to the lock.
>
> For example if I were creating a widget that displays a presentation on the 
> page, I could attach the screen lock to the  or  element that 
> holds the presentation:
>
> new navigator.ScreenLock(myCanvas);
>
> and if the canvas was removed from the document or hidden in any way, then 
> the browser could turn the screen off as usual, and I wouldn't have to do 
> anything!
>
> It's nearly impossible to forget to remove a visible DOM element from the 
> document — the mistake is likely to be quite obviously visible. If screen 
> lock lifetime was dependent on visibility of a DOM element, then it would 
> also be very hard to leak the lock without noticing it!
>
> (that's a variant of "wake-lock:display" CSS proposal, but less explicitly 
> dependent on CSS).

Good, but you lose the ability to key the wake-lock to
Selectors-exposed UA state (like "video:playing"), or directly to your
app's own state (via some class that gets set/removed by your app at
some point in its lifecycle).

But if the CSS part is distasteful, I agree that this works reasonably
well - there is *absolutely no reason* to screenlock based on an
element that's not visible on screen.

> With CPU lock it's less clear cut. I think tying it to a notification may be 
> a good idea. Alternatively, perhaps the lock itself could be an instance of 
> the  element that author is supposed to insert to the document? ;)

Just pass a promise to the CpuLock constructor, and have it
auto-release when the promise is settled?  You'll generally be
CPU-locking to wait for some operation to finish, and a lot of those
types of operations vend promises these days (or will in the future).

~TJ


[whatwg] Preventing wake lock leaks with DOM nodes

2014-08-18 Thread Kornel Lesiński
My biggest concern with the WakeLock API is that it's easy to forget (or fail) 
to release the lock.

It's not a problem with the API per se, but a programming problem in general: 
resource management in non-trivial programs is hard. WakeLocks are especially 
problematic in this regard, as a "leaked" lock won't cause any immediate 
problems for the developer, so this type of bug can easily go unnoticed.

So I think lifetime of WakeLocks needs to be attached to something visible to 
make failure to release the lock immediately obvious.


In case of screen lock it's especially easy: the whole purpose of this lock is 
to keep something visible on screen, so we can require that something to be 
explicitly connected to the lock.

For example if I were creating a widget that displays a presentation on the 
page, I could attach the screen lock to the  or  element that 
holds the presentation:

new navigator.ScreenLock(myCanvas);

and if the canvas was removed from the document or hidden in any way, then the 
browser could turn the screen off as usual, and I wouldn't have to do anything!

It's nearly impossible to forget to remove a visible DOM element from the 
document — the mistake is likely to be quite obviously visible. If screen lock 
lifetime was dependent on visibility of a DOM element, then it would also be 
very hard to leak the lock without noticing it!

(that's a variant of "wake-lock:display" CSS proposal, but less explicitly 
dependent on CSS).


With CPU lock it's less clear cut. I think tying it to a notification may be a 
good idea. Alternatively, perhaps the lock itself could be an instance of the 
 element that author is supposed to insert to the document? ;)

-- 
regards, Kornel





[whatwg] Feature-detectable WakeLocks

2014-08-18 Thread Kornel Lesiński
WakeLock.request() expecting a string isn't very friendly to feature detection. 

I'd prefer if individual lock types were instances of objects, e.g. 
navigator.*Lock objects could be instances of a variant of the WakeLock 
interface:

navigator.screenLock.request();
navigator.screenLock.isHeld();

navigator.cpuLock.request();
navigator.cpuLock.release();


Alternatively, if the WakeLock was instantiable (to have a standard way for 
independent page components to share locks) then these objects could be 
constructors:

if (navigator.ScreenLock) {
var lock = new navigator.ScreenLock();
…
lock.release();
}

(or `new navigator.wakeLocks.Screen()`, etc.)

Having specific instances for different types of locks could also enable 
elegant extensibility of the API, e.g.

var screenLock = new navigator.ScreenLock();
screenLock.dimScreen(); // completely made-up API

var cpuLock = new navigator.CpuLock();
cpuLock.setThreadPriority("low"); // completely made-up API

-- 
regards, Kornel





Re: [whatwg] Proposal: Wake Lock API

2014-08-18 Thread Kornel Lesiński
I think it'd be unfortunate if this API had just one shared lock per browsing 
context and required components on the page to coordinate locking, but provided 
no means to do so. This will force authors of libraries and components to 
create dummy iframes just to have their private lock, and libraries/pages 
without such workaround will be messing up each other's locks.

Having just a single shared DOM0-style event handler navigator.wakeLock.onlost 
looks especially jarring. I would expect this to be a proper DOM event that can 
be used with normal addEventListener (please avoid repeating the mistake of 
matchMedia).


To make some coordination possible, the simplest method could be to keep track 
of number of lock requests and releases, like retain/release in Objective-C:

navigator.wakeLock.request("screen"); // locks
navigator.wakeLock.request("screen"); // increases lock count
navigator.wakeLock.release("screen"); // not released yet, but decreases lock 
count
navigator.wakeLock.release("screen"); // now released for real

However, as you probably know from Objective-C, perfect balancing of 
retain/release takes care and discipline. Personally, I wouldn't trust all 3rd 
party libraries/widgets/ads to be careful with this. In fact, I expect some 
"clever" libraries to ruin this with:

while(navigator.wakeLock.isHeld("screen")) 
navigator.wakeLock.release("screen"); // just release the damn thing in my 
leaky code!


Therefore, if WakeLock needs to be purely JS API, I strongly prefer having 
WakeLock available only as an object instance, but without exposing GC 
behavior—if it's lost, it's like a missing release call. 

If devtools ever get monitoring of unhanded errors in Promise objects, they 
could also warn against lost WakeLock objects—it's the same type of problem 
dependent on GC.

I'm assuming that release would work only once on each lock object:

var lock = new WakeLock("screen");
lock.release();
lock.release(); // ignored, so it doesn't unlock any other component's lock

This makes coordination easier: each page component can easily create their own 
lock independently (without needing to create an iframe to get their own lock), 
and can't release any other component's lock.


-- 
regards, Kornel





Re: [whatwg] Proposal: Wake Lock API

2014-08-18 Thread Jonas Sicking
On Mon, Aug 18, 2014 at 2:04 AM, Mounir Lamouri  wrote:
>
>> > It's also not clear
>> > how this solution is superior than the current solution [1] with regards
>> > to multiple releases or requests. In [1], if you call .request() or
>> > .release() multiple time, the promise reacts appropriately.
>>
>> The problem arises when you have several semi-independent pieces of
>> code within a single page. Given that request() and release() is
>> likely going to happen in response to very different UI events or IO
>> events, it makes it fairly easy to accidentally have unbalanced calls.
>>
>> Consider for example a lock which is released either when a video
>> reaches its end, when the user presses the pause button, or when the
>> user close the  in which the video is rendered. It seems quite
>> easy to end up with a race where if the user close the  right
>> when the video ends, that release() would get called twice. Or if the
>> user pause the video first and then close the  that release()
>> would get called twice.
>>
>> If there's only one subsystem of the page that uses a display lock,
>> then this is not a big deal. The extra call to release() would cause
>> an rejection, but hopefully that won't break the page.
>
> It is possible that the API might behave differently and the first
> release() will release the lock even if lock() was called multiple
> times. I guess the scope of the lock could be the browsing context so a
> website will not end up conflicting with iframes. However, if a websites
> embeds libraries that use this API, it will need to coordinate.

I'd rather have request() and release() work as they are defined now.
Otherwise coordinating becomes even harder as the specification does
not provide a coordination mechanism.

>> However if there are multiple subsystems that all use a display lock,
>> it would mean that those subsystems might stomp on each other's
>> attempts at holding a display lock. The effect would be that the
>> display lock is released too early.
>>
>> I don't care strongly about this though. It's pretty easy for pages to
>> write a wrapper around the currently proposed API to implement the API
>> that I'm proposing.
>
> I understand the problem and I agree that an object-based approach would
> be nicer in theory because the scope of the lock would be well defined.
> However, it's a very uncommon pattern as far as Web APIs are concerned
> and I would worry that developers would end up  doing things wrong and
> depend on the GC behaviour without even being aware of it.

Note that in the API that I'm proposing, there is no way to
accidentally rely on GC behavior. If a WakeLock object is GCed before
it has been release()ed, then the lock is held indefinitely (until the
user leaves the page of course).

I.e. an unbalanced request() and release() in both the currently
proposed API, and in the API that I propose behave the same, the lock
is held indefinitely. Any objects getting GCed does not change this.

Again, I don't feel terribly strongly about this as it's easy to shim
in either direction.

/ Jonas


Re: [whatwg] Proposal: Wake Lock API

2014-08-18 Thread Tab Atkins Jr.
On Sat, Aug 16, 2014 at 9:19 AM, Nils Dagsson Moskopp
 wrote:
> Jonas Sicking  writes:
>> On Fri, Aug 15, 2014 at 6:14 AM, Mounir Lamouri  wrote:
>>> On Thu, 14 Aug 2014, at 11:00, Jonas Sicking wrote:
 I am however more worried about that only having a request() and a
 release() function means that pages that contain multiple independent
 subsystems will have to make sure that they don't stomp on each
 other's locks. Simply counting request() calls vs. release() calls
 helps, but doesn't fully solve the problem. It's very easy to
 accidentally call release too many times, in response to some UI
 action for example.

 An alternative design would be something like

 x = new WakeLock("display");
 x.request();
 x.release();

 Extra calls of either request() or release() are ignored, but pages
 can create any number of WakeLocks of the same type.
>>>
>>> It seems that we already discussed using an object and this solution was
>>> dismissed because of this model being error-prone.
>>
>> Where was this discussed? Why was it considered more error prone? Was
>> it related to the patterns discussed at
>>
>> http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2014-August/297431.html
>>
>>> It's also not clear
>>> how this solution is superior than the current solution [1] with regards
>>> to multiple releases or requests. In [1], if you call .request() or
>>> .release() multiple time, the promise reacts appropriately.
>>
>> The problem arises when you have several semi-independent pieces of
>> code within a single page. Given that request() and release() is
>> likely going to happen in response to very different UI events or IO
>> events, it makes it fairly easy to accidentally have unbalanced calls.
>>
>> Consider for example a lock which is released either when a video
>> reaches its end, when the user presses the pause button, or when the
>> user close the  in which the video is rendered. It seems quite
>> easy to end up with a race where if the user close the  right
>> when the video ends, that release() would get called twice. Or if the
>> user pause the video first and then close the  that release()
>> would get called twice.
>
> Seems to me a declarative solution (like CSS) might be appropriate.
>
> @media screen {
> video:playing {
> wake-lock: display 15s;
> }
> }
>
> article.recipe:target {
> wake-lock: display;
> }

That's not a terrible idea.  The CSSWG is generally hesitant to put
behavior-altering things in CSS, but some bleed-through is fine, and
this can be argued as an aspect of appearance.

This solves the GC and locking issues (the latter by delegating state
management to CSS, which everyone already knows to use).

~TJ


Re: [whatwg] Proposal: Wake Lock API

2014-08-18 Thread Mounir Lamouri
On Sat, 16 Aug 2014, at 08:40, Jonas Sicking wrote:
> On Fri, Aug 15, 2014 at 6:14 AM, Mounir Lamouri 
> wrote:
> > On Thu, 14 Aug 2014, at 11:00, Jonas Sicking wrote:
> >> I am however more worried about that only having a request() and a
> >> release() function means that pages that contain multiple independent
> >> subsystems will have to make sure that they don't stomp on each
> >> other's locks. Simply counting request() calls vs. release() calls
> >> helps, but doesn't fully solve the problem. It's very easy to
> >> accidentally call release too many times, in response to some UI
> >> action for example.
> >>
> >> An alternative design would be something like
> >>
> >> x = new WakeLock("display");
> >> x.request();
> >> x.release();
> >>
> >> Extra calls of either request() or release() are ignored, but pages
> >> can create any number of WakeLocks of the same type.
> >
> > It seems that we already discussed using an object and this solution was
> > dismissed because of this model being error-prone.
> 
> Where was this discussed? Why was it considered more error prone? Was
> it related to the patterns discussed at
> http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2014-August/297431.html

There might have been some discussions in the DAP WG (but the archives
website isn't helping). There was definitely at thread in blink-dev [1]
and you might want to have a look at the GitHub repo [2]. By the way, it
seems that this API might be worked in the DAP WG [3].

> > It's also not clear
> > how this solution is superior than the current solution [1] with regards
> > to multiple releases or requests. In [1], if you call .request() or
> > .release() multiple time, the promise reacts appropriately.
> 
> The problem arises when you have several semi-independent pieces of
> code within a single page. Given that request() and release() is
> likely going to happen in response to very different UI events or IO
> events, it makes it fairly easy to accidentally have unbalanced calls.
> 
> Consider for example a lock which is released either when a video
> reaches its end, when the user presses the pause button, or when the
> user close the  in which the video is rendered. It seems quite
> easy to end up with a race where if the user close the  right
> when the video ends, that release() would get called twice. Or if the
> user pause the video first and then close the  that release()
> would get called twice.
> 
> If there's only one subsystem of the page that uses a display lock,
> then this is not a big deal. The extra call to release() would cause
> an rejection, but hopefully that won't break the page.

It is possible that the API might behave differently and the first
release() will release the lock even if lock() was called multiple
times. I guess the scope of the lock could be the browsing context so a
website will not end up conflicting with iframes. However, if a websites
embeds libraries that use this API, it will need to coordinate.

> However if there are multiple subsystems that all use a display lock,
> it would mean that those subsystems might stomp on each other's
> attempts at holding a display lock. The effect would be that the
> display lock is released too early.
> 
> I don't care strongly about this though. It's pretty easy for pages to
> write a wrapper around the currently proposed API to implement the API
> that I'm proposing.

I understand the problem and I agree that an object-based approach would
be nicer in theory because the scope of the lock would be well defined.
However, it's a very uncommon pattern as far as Web APIs are concerned
and I would worry that developers would end up  doing things wrong and
depend on the GC behaviour without even being aware of it.

[1]
https://groups.google.com/a/chromium.org/d/msg/blink-dev/SzVuAi2KRhA/OaNDiHOKl8gJ
[2] https://github.com/w3c/wake-lock
[3]
http://lists.w3.org/Archives/Public/public-device-apis/2014Aug/0035.html

-- Mounir