01:14
<MikeSmith>
anybody know if there's a WebKit implementation bug open for datalist
01:15
<MikeSmith>
https://bugs.webkit.org/show_bug.cgi?id=27247
01:15
<MikeSmith>
It seems
01:18
<MikeSmith>
now myquestion is, what's blocking it
07:15
<annevk>
MikeSmith: probably just someone to work on it
07:19
<MikeSmith>
annevk: yeah, seems so
07:20
<MikeSmith>
tkent points out that the interactive form validation stuff is in the same state
08:35
<JakeA>
annevk: when is the right time to make response/request.body a ReadableStream in the fetch spec?
09:05
<annevk>
JakeA: I was waiting for "tee" to be defined
09:05
<annevk>
JakeA: seems to be the only issue left: https://github.com/yutakahirano/fetch-with-streams/issues
09:05
<JakeA>
annevk: gotcha, cheers
09:05
<annevk>
JakeA: well, and also, I'm waiting for some confirmation that this design is okay
09:06
<annevk>
JakeA: I wish there was a second implementation
09:12
<hsivonen>
MikeSmith: If I tweak the TLS config for the validator, do you have a preference whether I should set properties procedurally in Main.java or via external files and command line switches managed by build.py?
09:13
<hsivonen>
I'm leaning towards Main.java, because the command line is pretty crazy already
09:13
<MikeSmith>
hsivonen: yeah, in Main.java sounds better to me as well
09:14
<hsivonen>
MikeSmith: OK. thanks
09:14
<MikeSmith>
hai
10:27
<mounir>
am I correct that per webidl, if I want a dictionary parameters with values depending on other parameters, i need to have a base dictionary in the method parameter type?
10:32
<Ms2ger>
What
10:33
<mounir>
Ms2ger: I have navigator.permissions.query(name, options)
10:33
<mounir>
options will depend on "name"
10:33
<Ms2ger>
You mean like canvas.getContext()?
10:33
<Ms2ger>
I thought we decided that wasn't a pattern we wanted to repeat
10:35
<mounir>
Ms2ger: except that "name" is part of an enum
10:35
<mounir>
and it's only used to know a permission state, not to get a feature
12:07
<JakeA>
Domenic: let me know when you're free to drown in the lands of cancellable promises
12:49
<zcorpan>
why is there no TouchEvent constructor?
12:56
<wilsonpage>
roc ping
13:01
<annevk>
wanderview: hey, where are we at with https://github.com/yutakahirano/fetch-with-streams/issues/25 and streams in general?
13:29
<annevk>
zcorpan: do you know if Chromium has an origin associated with the global?
13:33
<zcorpan>
annevk: don't know
13:39
<wanderview>
annevk: at this point I do not feel comfortable implementing that... I'm planning to talk to sicking in a couple weeks to try to iron out our differences
13:42
<annevk>
JakeA: given wanderview's statement and not hearing anything from Apple/Microsoft I'm inclined to hold off on integrating streams for now
13:44
<JakeA>
annevk: makes sense, wasn't aware of wanderview's concerns
13:44
<wanderview>
annevk: I guess to clarify, I'm personally ok with implementing the fetch body stream bit... but I need to address sicking's concerns first... and it feels like we're further away from agreement than I thought before
13:45
<wanderview>
JakeA: not my personal concerns... we need some internal consensus before moving forward, though
13:46
<wanderview>
if that makes sense
14:19
<jgraham>
Anyone know of a version of something like jsfiddle or the live dom viewer with support for multiple origins?
15:25
<Domenic>
JakeA: let's do this
15:25
<Domenic>
wow that thread really got overrun
15:26
<JakeA>
Domenic: yeah. Where's the best place to do this, here?
15:26
<Domenic>
seems reasonable
15:26
<Domenic>
Unless you want VC or something for higher bandwidth
15:28
<JakeA>
We'll try here and if that isn't good enough (or annoys people here) we'll go VC
15:28
<JakeA>
Will be back in a min
15:32
<JakeA>
Domenic: so, I get the feeling you've been around the ref-counting idea before, and every other cancellable-promise proposal, and you don't think it's possible outside of a token-based system. Is that true?
15:34
<Domenic>
JakeA: I think ref-counting is tricky business with lots of edge cases and potential usability hazards. I'd want to see it worked out in excruciating detail before saying it's workable.
15:34
<Domenic>
I'm also sympathetic to the argument that it's philosophically "wrong", i.e. cancellation should be a property of the operation and not of the result.
15:35
<Domenic>
JakeA: as an example I'd wonder if Promise.prototype.then.call(cancelablePromise, f, r) increases the ref count, or even works at all.
15:36
<JakeA>
Domenic: I think it would increase ref count. I initially thought otherwise, that the parent should only count cancellable children, but I think all children is more consistent
15:37
<Domenic>
JakeA: OK, so this would involve modifying the spec for Promise to be aware of CancelablePromise?
15:39
<JakeA>
Domenic: does a promise have a link to its children? (eg, a way to iterative over the and look at their state?)
15:40
<Domenic>
JakeA: only before it gets fulfilled or rejected; after that it aggressively cuts off references in order to avoid memory "leaks".
15:42
<JakeA>
Domenic: that seems ok then, since a settled promise cannot cancel. Promise.prototype.then.call(cancelablePromise, f, r) would still create a cancellable promise
15:42
<Domenic>
Hmm OK, so @@species is still CancelablePromise
15:42
<JakeA>
Promise.resolve(cancellablePromise) will create a child plain Promise
15:43
<Domenic>
right
15:43
<Domenic>
So you can't use this to just cancel a fetch operation then, if the headers have already been received
15:43
<Domenic>
You need to do the chaining thing
15:43
<Domenic>
But you can't e.g. create a token, do some fetches (which shar ethe token), then when people navigate the page, cancel the token and thus destroy all chained processing
15:44
<Domenic>
instead you have to keep track of all child promises
15:44
<Domenic>
and cancel them, when people navigate the page
15:44
<Domenic>
("navigate the page" = within a single-page app, not browser navigation)
15:44
<JakeA>
fetch(url).then(r => r.json()) - both fetch() and r.json() are cancellable
15:44
<Domenic>
right, but
15:44
<Domenic>
compare with:
15:45
<Domenic>
var canceller = new Canceller(); var p1 = fetch(url1, { canceller }); var p2 = fetch(url2, { canceler }); doStuffWith(p1, p2); doMoreStuffWith(p1, p2); /* later */ canceller.cancel();
15:45
<Domenic>
tokens allow you, as the initiator of fetch, to decide when to stop
15:46
<Domenic>
instead of depending on your consumers to coordinate and say "oh, we'd better all cancel at the same time"
15:46
<Domenic>
I guess you could build that on top of promise.cancel() though
15:47
<Domenic>
well, but not for after-headers-have-arrived...
15:47
<Domenic>
unsure
15:47
<JakeA>
Domenic: var p1 = fetch(url); /* pass p1 to some other code which does whatever it wants */ p1.cancel(); /* kill the downward chain */
15:47
<Domenic>
right but you don't actually kill the downward chain because of ref-counting
15:48
<Domenic>
if "whatever it wants" includes a .then, you lose.
15:48
<Domenic>
I guess you could Promise.resolve() it first
15:49
<Domenic>
Can we turn things around for a bit? Why do you find the ref-counting solution more attractive? It seems less flexible and harder to reason about, to me.
15:49
<JakeA>
Domenic: ref-counting isn't used on the promise you call .cancel on, it stops straight away & cancels all children. Ref counting is used to decide if the parent should now be cancelled
15:49
<Domenic>
JakeA: oh interesting... so cancel flows in both directions
15:50
<Domenic>
down like rejection, but also up to parents
15:50
<JakeA>
If you call p.cancel() this promise will always cancel as long as it hasn't settled, as will all its children and so on. p's parent may cancel, if p was its only child or all its children have cancelled
15:50
<JakeA>
That's what I was thinking
15:50
<Domenic>
huh
15:50
<Domenic>
hmm ok back to the modifying-Promise-spec
15:51
<Domenic>
because there's no linkage from child to parent right now
15:51
<Domenic>
i guess it's only necessary for CancelablePromises
15:51
<Domenic>
I worry a bit about the implicit reference causing memory leaks
15:52
<JakeA>
Domenic: once the promise settles it can kill its parent link
15:52
<JakeA>
as it can no longer be cancelled
15:52
<Domenic>
var q = cancelablePromise.then(x).then(y).then(z).then(w) keeps 5 promises alive whereas for normal promises it'd be just 1
15:52
<Domenic>
hmm right ok so maybe it's the same then
15:52
<Domenic>
probably
15:54
<JakeA>
So when p.cancel() is called, it walks up the chain to find the highest promise that can be cancelled. That promise gets its cancel callback called, then the others get [rejected/hung/something else]
15:55
<Domenic>
the others?
15:55
<JakeA>
Sorry, down the chain from the one that gets cancelled
15:55
<Domenic>
right, ok
15:55
<Domenic>
so unwinding the stack a bit ... why do you like this design?
15:58
<JakeA>
Domenic: var p1 = fetch(url); var child1 = p1.then(r => consumeStream(r)); var child11 = child1.then(doSomethingElse); child11.cancel();
15:58
<JakeA>
Taking that example:
15:59
<JakeA>
If there's another p1.then(…), the child11 will appear cancelled, but the underlying fetch will not, so the branch is safe
16:00
<Domenic>
yep, i got that
16:00
<Domenic>
not sure why you think it's a good experience though, in comparison to the initiator of the fetch being in control
16:00
<JakeA>
If there's no branch, then either the fetch or the stream read will be cancelled. If they've both finished, doSomethingElse will appear cancelled even if it carries on its work (because it returns a normal promise)
16:01
<Domenic>
what does "doSomethingElse will appear cancelled" mean?
16:02
<JakeA>
Domenic: its call to resolve/reject will not do anything, because the promise has been cancelled. What happens on promise cancel is still up for grabs, perhaps reject with undefined or an AbortError
16:03
<Domenic>
whose call to resolve/reject?! I thought doSomethingElse was just a function? Maybe write out its body...
16:04
<JakeA>
Sorry, yeah, that would be more helpful: .then(r => setTimeout(_ => r("Hello"), 1000))
16:04
<JakeA>
hang on
16:04
<JakeA>
that's wrong
16:04
<Domenic>
thta's... not how .then works...
16:04
<JakeA>
yeah sorry, brain break
16:04
<Domenic>
np
16:05
<JakeA>
.then(_ => new Promise(r => setTimeout(_ => r("Hello"), 1000)))
16:05
<JakeA>
Basically, doSomethingElse resolves in 1 second with "Hello"
16:06
<frivoal>
Does anyone remember who was involved in thinking / making -o-double-rainbow() ?
16:07
JakeA
thinks about the token solution some more
16:07
<annevk>
frivoal: I think I suggested that to whoever was implementing gradients at the time
16:07
<Domenic>
OK, so I think what you meant was "doSomethingElse isn't even called"
16:08
<frivoal>
annevk: thanks, I suspected you might be the one to thank for that.
16:08
<JakeA>
Domenic: if it's called, but the second hasn't passed, .cancel() would still "work" in that the promise won't resolve with "Hello"
16:09
<JakeA>
r("Hello") will be called, but since the promise is in a cancelled state (which could just mean rejected) it's ignored
16:09
<Domenic>
oh hmm that's weird
16:09
<Domenic>
so child11 is resolved already but you un-resolve it when you cancel
16:09
<Domenic>
or change its resolution or something
16:09
<frivoal>
annevk: Would I be wrong to attribute this work of art to Bruce Lawson: http://media.opera.com/media/press/2011/unicorn/ ?
16:09
<Domenic>
(child1 is pending-but-resolved in your example)
16:10
<JakeA>
Domenic: that doesn't sound right…
16:10
<Domenic>
JakeA: child11 is pending, since doSomethingElse returns a promise that is still pending-for-a-second. But it's resolved to that pending-for-a-second promise.
16:11
<Domenic>
normally that would mean it's locked in to follow that pending-for-a-second promise without fail.
16:11
<annevk>
frivoal: not sure
16:12
<annevk>
frivoal: was it Leif Arne who should get the credit?
16:12
annevk
forgot :-(
16:12
<frivoal>
annevk: possibly
16:13
<JakeA>
Domenic: child11 is pending, calling .cancel() makes it (let's say) reject, the timeout hits, resolve is called, it's ignored
16:14
<Domenic>
JakeA: let's break this down. `var p = new Promise(r => setTimeout(() => r("Hello"), 1000))`
16:14
<Domenic>
function doSomethingElse() { return p; }
16:14
<Domenic>
var child11 = child1.then(doSomethingElse)
16:14
<Domenic>
This immediately does PromiseResolve(child11, p)
16:15
<wanderview>
if we make fetch() return an extended promise with a fetch-specific cancel... can we later switch to a CancellablePromise once we see that it works out?
16:15
<frivoal>
annevk: Yep, it seems to be Leif Arne: https://twitter.com/rchl2k/status/135129843170947072
16:15
<Domenic>
You cannot reject a resolved promise
16:15
<annevk>
frivoal: nice find
16:16
<Domenic>
JakeA: similar example: var q = new Promise((res, rej) => res(p); rej(new Error("foo"))); q will be pending for 1 second then fulfilled with "Hello"
16:16
<annevk>
wanderview: that's the terminate() proposal, and yeah, I think there's agreement that can work, though there's still the open question there whether to do forever-pending or reject or allow for both
16:17
<JakeA>
Domenic: hmm, yeah, I see *thinks*
16:18
<wanderview>
annevk: I guess the problem with that is it just breaks the Promise API niceness.. you can't really chain off the fetch() any more
16:19
<annevk>
wanderview: yup, though if you want to do complicated things you can't really chain anyway I think
16:19
<Domenic>
I'm still not sure keeping terminate-ability through a chain is desirable
16:19
<Domenic>
i kind of feel it should only belong to the initiator
16:19
<Domenic>
that's a key difference here I think
16:19
<Domenic>
I could be convinced otherwise but that's my conservative position
16:20
<wanderview>
annevk: I wonder if we could so something like fetch(req).control(function(controller) { .. }).then(function (response) { });
16:20
<wanderview>
and controller.cancel()
16:20
<annevk>
wanderview: why .control?
16:21
<wanderview>
annevk: the idea being fetch() returns an extended promise with a .control()... letting you get a handle to the controller for later use... because the decision to cancel will be async most likely
16:21
<annevk>
Domenic: if there was an established API pattern that would be an easy sell
16:21
<wanderview>
and .control() returns a Promise for the response
16:21
<annevk>
wanderview: why not just make control an argument to fetch()?
16:22
<wanderview>
annevk: that works for me too
16:22
<wanderview>
pretty sure we've discussed this before... I think I just like that approach from a "how I would want to use it in code" point of view
16:23
<wanderview>
annevk: I guess .control() seems slightly nicer than a fetch arg because then it fits into the chaining pattern nicely
16:23
wanderview
shrugs
16:23
<annevk>
fetch(url, control: c => c.abort()) just seems rather ugly
16:24
<annevk>
fetch(url).control(c => c.abort()) doesn't seem too different
16:25
<wanderview>
annevk: it would really be fetch(url).control(c => savedControl = c).then(response => ...);
16:26
<Domenic>
I still like `var c = new FetchController()`; fetch(url, { controller })` or similar.
16:26
<wanderview>
Domenic: thats nice
16:26
<Domenic>
the upside being you can hand out the same controller to multiple fetches
16:29
<wanderview>
Domenic: yea... and if we make individual Promises cancellable... then the page has to rebuild a controller for themself by aggregating a promise for each fetch() in the place where the "cancel now" event happens
16:29
<Domenic>
wanderview: right, that was kind of my worry... although you could probably build a wrapper that implements either on top of the other
16:31
<wanderview>
I just can't think of a use case where you want to stick .cancel() at the end of a Promise chain... and Promise chain syntax does not lend itself to getting a reference to the promise itself, except at the end of the chain
16:33
<Domenic>
Well, I dunno, it's fairly believable for non-branching chains
16:34
<JakeA>
wanderview: fetch(url).then(r => r.json())
16:34
<Domenic>
var result = fetch(url).then(r => r.json()).then(parseJSONIntoModel).then(updateUI); router.on("hashchange", () => result.cancel())
16:34
<JakeA>
right
16:35
<Domenic>
not much different from `var canceller = new Canceller(); fetch(url, { canceller }).then(...).then(...).then(...); router.on("hashchange", () => canceller.cancel())` admittedly.
16:35
<wanderview>
ok
16:36
<Domenic>
but less work if the router.on(...) code is located somewhere else; becomes an issue of passing it a { promise, canceller } pair vs. a promise by itself
16:36
<Domenic>
unsure though, this example is kind of unrealistic
16:36
<wanderview>
Domenic: I guess the Canceller example is more clear it only effects fetch()... the first example suggests you can cancel parseJSONIntoModel, etc
16:36
<Domenic>
wanderview: ah yeah hmm i guess that's actually a downside though...
16:37
<JakeA>
Domenic: so, going back to what you said earlier, var p = fetch(url).then(r => r.json()) - calling .cancel() wouldn't work if we had headers, since the .then is immediately resolved with the r.json() promise.
16:37
<wanderview>
Domenic: downside for the controller approach? how so?
16:37
<Domenic>
that's a pretty bad downside really
16:37
<Domenic>
wanderview: because you want an easy way to stop parsing or updating the UI too
16:38
<wanderview>
Domenic: they may not be cancellable, though... for example if the parse is synchronous (which is probably is)
16:38
<Domenic>
wanderview: so it becomes fetch(url, { canceller }).then(r => r.json({ canceller })).then(j => parseJSONIntoModel(j, { canceller })).then(m => updateUI(m, { canceller }))
16:38
<Domenic>
wanderview: yeah true
16:40
<Domenic>
JakeA: hmm yes that's true -_-
16:40
<JakeA>
Domenic: So the resolved value needs to be treated as a chain too
16:40
<wanderview>
Domenic: if you want a cancellable parse, use a Stream? :-)
16:41
<Domenic>
wanderview: haha true.
16:41
<Domenic>
JakeA: not sure what the implications of that are.
16:41
<JakeA>
Domenic: me neither
16:42
<JakeA>
I feel we're getting closer to fetch() returning a FetchPromise with an abort() methods with a @@species of Promise
16:42
<Domenic>
the terminate() solution, you mean?
16:42
<JakeA>
yeah, terminate()
16:42
<Domenic>
why is that better than canceller?
16:43
<JakeA>
Canceller seems ugly to me, maybe I'll get used to it
16:43
<Domenic>
the weight of minting a new promise subclass, especially one of such limited use, makes me hesitant.
16:43
<JakeA>
I'll probably get used to it
16:44
<Domenic>
if we had more methods to put on it then i'd feel better
16:44
<Domenic>
e.g. http2 priority-adjuster?
16:45
<wanderview>
how do cancel response.json?
16:45
<wanderview>
response.body.cancel(), doesn't work right?
16:45
<wanderview>
Domenic: JakeA: ^^^
16:45
<JakeA>
wanderview: it would have to take a canceller or similar
16:45
<Domenic>
yeah, that
16:45
<wanderview>
JakeA: or have response.cancel()
16:46
<Domenic>
do we really want to give that authority to anyone though?
16:46
<wanderview>
Domenic: how does one get a handle to the same Response object without being the same code that sets up the cancel?
16:46
<Domenic>
i dunno the ergonomics argument is making me want to reconsider JakeA's ideas... if we can make them work somehow...
16:47
<Domenic>
wanderview: doSomethingWith(response) :)
16:47
<Domenic>
wanderview: it's a matter of, when you give someone a response, are you also giving them ability to blow up the response? or just to read it (if it's not locked)?
16:47
<Domenic>
i think we made res.headers immutable for similar reasons?
16:48
<wanderview>
Domenic: if you don't trust the code you can call doSomethingWith(response.clone())
16:48
<Domenic>
wanderview: true true.
16:48
<wanderview>
Domenic: because they could drain the body and "blow up" the Response as well
16:48
<Domenic>
wanderview: not if it's locked though.
16:49
<wanderview>
Domenic: I find the lock blocking cancel very unexpected, to be honest
16:49
<JakeA>
Domenic: https://github.com/slightlyoff/ServiceWorker/issues/592#issuecomment-68853209 - here I say "If the user hits X (or even closes the tab) while /whatever.json is fetching, I don't think we can simply cancel the request", this is because the tab isn't consuming the stream at this point. With a chaining cancellable promise, this is no longer an issue
16:49
<Domenic>
:-S
16:49
<JakeA>
This is a case where you want the party you give the promise to to be able to cancel, rather than the initiator
16:50
<wanderview>
Domenic: simultaneous reads is good to block with a lock... but having some async thing cancel a stream while another bit of code is reading seems pretty commonplace to me
16:50
<Domenic>
JakeA: is "we" the browser or author code in that sentence?
16:50
<JakeA>
Domenic: the browser
16:50
<Domenic>
wanderview: this is kind of just a principle of least authority thing I think
16:50
<Domenic>
JakeA: I think the stream becomes errored if it's prematurely terminated.
16:51
<annevk>
Domenic: we'd use a promise-subclass for other things too
16:51
<annevk>
Domenic: e.g. postMessage() with the SW
16:51
<wanderview>
Domenic: this forces Response.json(canceller) as the only solution then
16:51
<annevk>
Domenic: or changing priority of the fetch
16:51
<wanderview>
which is fine I guess
16:51
<Domenic>
wanderview: right, or a CancelablePromise solution that I've been arguing is complicated.
16:52
<wanderview>
I guess, keep in mind that everything with the body stream effects Cache produced Responses as well... but canceling "before the headers" is fetch only
16:52
<wanderview>
unless Cache grows something similar to fetch
16:52
wanderview
doesn't want to allow canceling Cache.match(), etc.
16:53
<annevk>
Domenic: the only reason headers is immutable at the moment is because that's the easiest
16:53
<annevk>
Domenic: but we'll make it mutable together with request's headers
16:53
<Domenic>
annevk: hmm ok
16:53
<annevk>
Domenic: just needs some careful consideration of all the implications
16:53
<wanderview>
I wonder how much pain here is due to separating "we have headers" event from the body stream its parsed from
16:54
<wanderview>
^body stream^data stream
16:54
<Domenic>
JakeA: now I'm curious if you can make CancelablePromise work generally. I think you need: 1) compelling ergonomics examples vs. canceller; 2) work through the semantics and edge cases in detail.
16:54
<Domenic>
JakeA: I can try to help with 2)...
16:54
<annevk>
wanderview: having headers also means no more redirects, it's a rather important milestone
16:55
<wanderview>
annevk: yes... but treating them as separate cancelable things when really there is one underlying stream supplying both
16:55
<annevk>
Domenic: I think the case for CancelablePromise is indeed primarily ergonomics
16:55
<Domenic>
wanderview: annevk: yeah, the have-headers milestone being separable is quite nice in practice, I think. Certainly can be a leaky abstraction in some cases though.
16:55
<annevk>
Domenic: having to construct a controller is awkward
16:55
<Domenic>
annevk: to me that's not the awkward part, the awkward part is lack of propagation
16:56
<annevk>
Domenic: when would it be a leaky abstraction?
16:56
<annevk>
Domenic: this is exactly as atomic as implementations are
16:56
<Domenic>
annevk: well it's leaky here because an implementation could cancel the underlying TCP stream at any point, but here we have this two-stage thing => potentially two cancel mechanisms
16:58
<Domenic>
lunchtime...
16:58
<wanderview>
I guess it does fit Cache better.... load meta-data separate from body data stream
16:59
<JakeA>
Domenic: I'll do as much of 1 as I can tomorrow
17:37
<JakeA>
Domenic: has there been any further discussion on window.onerror alternatives for promises? onpromiseerror and onpromiseerrorhandled perhaps?
17:38
<JakeA>
Where the former would fire if a promise rejects without a reject handler, and the latter fires if it's later handled
17:39
<JakeA>
wanderview: ohh, how are you cancelling those fetching in Gecko (from the promises thread)
17:41
<wanderview>
JakeA: all network requests in gecko have an associated "LoadGroup"... right now we call LoadGroup.cancel() when the ServiceWorker is shutdown
17:41
<Domenic>
JakeA: people liked it, nobody said "yeah let's implement it"
17:41
<wanderview>
JakeA: non-SW cases share the LoadGroup with the document and the LoadGroup.cancel() is triggered by navigation, etc
17:42
<wanderview>
JakeA: we also have a way of cancelling things when the worker thread is shutting down
17:42
<JakeA>
wanderview: ahh yeah, but that doesn't work if the SW stays alive, eg if the page is navigated within scope it's likely to stay alive
17:42
<wanderview>
JakeA: its poorly defined in the spec, I think :-(
17:42
<wanderview>
JakeA: for example... does the SW stay alive until respondWith() resolves a Response?
17:42
<wanderview>
or until the underlying Response body completes?
17:43
<wanderview>
what if there is an outstanding Cache.put() in operation? do we cancel that?
17:43
<JakeA>
wanderview: receives a response should be enough. We may need a fetchEvent.waitUntil for further tasks
17:43
<JakeA>
yeah, exactly
17:44
<wanderview>
JakeA: right... I think we may actually have to keep the worker thread alive until body is fully copied in... but that could just be our implementation
17:44
<wanderview>
right now we don't explicitly do that... probably a bug
17:44
<wanderview>
JakeA: I guess my point, though... is the browser can cancel this stuff regardless of what script does (without script using something like waitUntil() )
17:44
<JakeA>
wanderview: welllll it's not really a bug. The browser is allowed to keep the SW alive as long as it wants
17:45
<JakeA>
wanderview: those requests can only be cancelled if the promise has resolved, or if the browser can shut the SW down
17:45
<wanderview>
JakeA: I think we may stop the SW too soon in gecko right now
17:46
<wanderview>
JakeA: I haven't looked, but if navigation caused the FetchEvent to no longer be valid... we should be able to stop the SW and cancel those operations
17:46
<wanderview>
FetchEvent holds SW alive... Document should hold FetchEvent
17:46
<wanderview>
I'd have to check, though
17:47
<JakeA>
wanderview: but if the navigation is to another page in scope, the SW needs to be alive for that new page and its resources
17:47
<wanderview>
JakeA: true... these mechanisms will not cancel in that case
17:48
<JakeA>
wanderview: maybe an edge case though
17:48
<wanderview>
JakeA: canceling per FetchEvent seems reasonable... if the FetchEvent is going nowhere
17:49
<JakeA>
wanderview: will design fetchEvent.waitUntil tomorrow
17:49
<wanderview>
JakeA: I suppose the FetchEvent could be for a window.fetch() that gets canceled too :-)
17:49
<wanderview>
FetchEvent cancellation I mean
17:49
<JakeA>
haha
19:03
<mounir>
Domenic: ping
19:03
<mounir>
marcosc: ping
19:04
<Domenic>
pong
19:05
marcosc
here
19:05
<mounir>
marcosc: Domenic suggests to remove the base interface
19:05
<mounir>
or maybe use "implements"
19:05
<mounir>
I don't mind both, FWIW
19:05
<Domenic>
https://gist.github.com/domenic/db44ae9dd73534d63e46
19:05
<mounir>
my main concern now is to figure out which way to go: strong types or strings
19:06
<wanderview>
JakeA: can we just remove VARY headers completely and make Cache key-value? :-)
19:06
<Domenic>
mounir: I think hanging methods off of types (instead of having a string-param to a generic method) is OK; not much preference either way. But, a strong preference *against* passing those types around.
19:07
<mounir>
Domenic: then we should try to see how we could add a .request() on top of that
19:07
<mounir>
Domenic: I want the design to allow .request() to take multiple permissions
19:07
<mounir>
the string based solution would allow that fairly easily
19:07
<Domenic>
yeah. .request(["midi", "geolocation"]), etc. seems fine. They are keys into Permissions.prototype.
19:09
<mounir>
Domenic: except that you would need to pass some options
19:09
<marcosc>
sorry, was chatting to other people at moz about the API at the same time
19:09
<Domenic>
Oh, interesting
19:10
<Domenic>
I suppose you guys have already explored and rejected coalescing separate requests?
19:10
<Domenic>
So e.g. the natural Promise.all([n.p.midi.request({ sysex: true }), n.p.geolocation.request()]) is not good enough?
19:11
<marcosc>
that's what we would want, yes
19:11
<Domenic>
oh, then, seems good...
19:12
<marcosc>
I don't have a strong preference about the strings vs the attributes
19:12
<mounir>
for .request(), I'm not sure Promise.all() is the right solution
19:13
<Domenic>
People will do it, even if you don't think they should
19:13
<marcosc>
you can handle individual rejects as needed, so what's the problem?
19:14
<marcosc>
"Oh, without Camera you are going to have a bad time... but ok..."
19:14
<mounir>
or UI coallescing, it's better if it's clear that the permission requests have to be bundled
19:14
<mounir>
instead of guessing
19:24
<mounir>
Domenic: the more I think about it, the more I prefer the original design with only a dictionary passed to .query()
19:24
<mounir>
no name + options
19:24
<Domenic>
oh interesting
19:25
<mounir>
Domenic: a permission isn't defined by it's name but by the name and the options even if some doesn't
19:25
<Domenic>
hmmmm that makes sense
19:25
<mounir>
Domenic: you can't query() 'midi' or 'push', it's more a side effect that some options will have a default value
19:26
<mounir>
Domenic: how terrible is navigator.permissions.query({'name': 'foo'}); to you?
19:27
<mounir>
knowing that sometimes there would be other values?
19:27
<Domenic>
mounir: not so bad now that you explain the conceptual backing
19:27
<Domenic>
i wonder if it's coherent to have an overload that takes a string and converts it to { name: s } though
19:28
<Domenic>
Just for pure convenience
19:28
<mounir>
Domenic: that's exactly what I had, but slightlyoff hated it
19:28
<Domenic>
-_-
19:28
<mounir>
;)
19:28
<Domenic>
{ name: 'foo' } it is then!
19:28
<zcorpan>
MikeSmith: fwiw, w3c ip block issue turned out to be quite the mystery. something was hammering the svg blog, but we couldn't identify what. now it doesn't happen anymore. issue closed, mystery prevails
19:45
<darobin>
zcorpan: that happened at my office, we tracked it down to someone having a misbehaved Chrome extension that kept hitting a bunch of W3C pages for no reason
19:47
<Domenic>
probably dtds
19:58
<darobin>
Domenic: nope, it was weirder
19:59
<darobin>
I *think* that it was somehow trying to refresh an RSS feed that it autodetected from a page but getting it very wrong
19:59
<zcorpan>
the url here involved something about rss in the query string (but it didn't point to the svg blog's feed). also the request had no User-Agent.
20:00
<zcorpan>
know which extension?
20:46
<[swift]>
does anyone have an opinion on delivering visibilitychange events to iframes when they enter and exit the viewport?
20:46
<[swift]>
ack, znc keeps changing my nick
20:46
<sethf>
(or perhaps nickserv)
20:48
<sethf>
at any rate, the idea here would be to allow iframes to take actions to throttle themselves if they're not currently visible. think for example HTML5 ads - they may be performing a variety of kinds of work when visible that they may want to throttle down when the user has scrolled them off the page
20:56
<zcorpan>
sethf: seems like it could be useful. send a mail to the list?
20:59
<sethf>
zcorpan: that was step two =)
20:59
<jamesr___>
it's definitely come up
21:01
<sethf>
jamesr___: i looked around for previous discussions but didn't have much luck finding any
21:01
<sethf>
i may well be using the wrong keywords to search, though
21:23
<Ms2ger>
Someone killed irc.w3.org?
21:24
<gsnedders>
So it appears. It wasn't me, though, honest!
21:27
jgraham
blames gsnedders
21:28
<gsnedders>
Nah, I'm way too busy cursing SCSS to care.
21:29
<jgraham>
Should have called it CUSS
21:30
<jgraham>
Did I already spam this channel with https://docs.google.com/document/d/1K-mKOqiUiSjgZTEscBLjtjd6E67oiK8H2ztOiq5tigk/pub ?
21:30
<jgraham>
A most interesting look at web perf problems
21:35
<gsnedders>
tl;dr: JS makes everything slow?
21:47
<jgraham>
gsnedders: tldr for web authors is "if you want good perf you have to be super-careful about the code you actually run, rather than carelessly slinging about high level abstractions"
21:47
<darobin>
jgraham: wow, great doc
21:47
<jgraham>
But there are also messages for platform engineers and people working on tools
21:48
<darobin>
I'd say tl;dr is "ads will kill your perf"
21:48
<jgraham>
Well that was certainly the most egregious thing
21:48
<darobin>
"a loading spinner, that’s a canvas element, is rotated with css transforms every 42ms, via setInterval."
21:48
<darobin>
that's, like, wat?
21:49
<gsnedders>
hey gifs are so 90s
21:49
<gsnedders>
LIKE THIS GIF IF YOU'RE A 90S KID
21:49
<jgraham>
I was particularly horrified by the adsense script running in a scroll handler and taking 25ms
21:49
<darobin>
gsnedders: sure, I mean, why not. but do you need to replace the gif by using setInterval to animate a CSS transform that CSS could animate itself, to rotate a fucking canvas that could rotate itself?
21:49
<tantek>
lol adsense. NoScript. block adsense everywhere.
21:50
<darobin>
tantek: this is for performance for real users
21:50
<gsnedders>
darobin: yes
21:50
<tantek>
darobin: in that case, just install NoScript. if a site doesn't work, use a different one.
21:50
<darobin>
ok, you have a point gsnedders
21:51
<darobin>
tantek: I think a better solution is the one they advocate "Tell Google Adsense this is unacceptable"
21:51
<darobin>
AdSense is basically using 30ms of JS every second
21:51
<darobin>
times the number of tabs in the world this is run on, that's a lot of energy
21:51
<tantek>
where do you think all that distributed computing was going to come from? their own compute farms? nah. why bother with a compute cloud when you can hijack 30ms of user browser time every 1s?
21:52
<jgraham>
Well in this case I think it's more than that
21:52
<tantek>
the cloud … it's made of users!
21:52
<jgraham>
(it was 25ms on a phone, so probably less on a desktop, but still)
21:52
<darobin>
hehe
21:52
<tantek>
SoylentCloud™
21:53
<jgraham>
To be fair, doing compute on the client is totally legitimate. Running any ad related script in scroll handlers isn't
21:53
<gsnedders>
are there any UAs people actually use that use anything except screen or print media types?
21:53
<jgraham>
But the impression I get is that for the (biased) sample of sites they looked at, people had *no idea* what was actually running
21:54
<gsnedders>
jgraham, darobin: IIRC AdSense have stats on how often the ads scroll into view, I presume that's what it's there for… and that involves touching CSSOM and that's dear
21:55
<jgraham>
Yeah, well they clearly can't do that the way they are doing it without killing performance of the platform
21:55
<jgraham>
Oh hurrah, roc posted this to dev.platform
21:58
<darobin>
"Any flash ad that’s being transpiled to HTML5 clientside is more costly than it should be." — wait, you are doing *what* on the client?
21:58
<jgraham>
Yeah, I mean I understand shumway, but are people really producing new content like that?
21:58
<Ms2ger>
"You blocked flash? Let me work around that"
21:58
<jgraham>
I suspect this means that HTML authoring environments are still terrible
21:59
<jgraham>
Ms2ger: But they could just write HTML in the first place
21:59
<tschneidereit>
Ms2ger: that's not how we roll, though
21:59
<jgraham>
anyway, it seems like one message here is "the more third-party code you run, the less likely you are to win at perf"
21:59
<tschneidereit>
Shumway won't run for ads if you have Flash disabled
22:00
<jgraham>
And since ads are all third-party code…
22:00
<Ms2ger>
tschneidereit, no, I mean that the ad would do that itself
22:00
<tschneidereit>
Ms2ger: oh, ok. Yeah, obviously ads will move to html/js more and more
22:01
<jgraham>
tschneidereit: In this case it seems like the ads had been compiled from flash to html or something
22:01
<jgraham>
Presumably using something shumway-like
22:02
<sethf>
jgraham: doesn't google have something like that? swiffy? thought it was server-side, though
22:03
<jgraham>
That could be it. But presumably it emits js that runs on the client
22:03
<sethf>
oh yeah, sure, the js runs on the client
22:03
<tschneidereit>
jgraham: almost certainly Swiffy, yes. Do you have a URL?
22:04
<jgraham>
Oh, yeah it says that in the screenshot
22:04
<tschneidereit>
heh
22:04
<jgraham>
Search for flash in the document I linked above
22:07
<jgraham>
So I guess a cynical takeaway is that Google is an enabler for bad web perf :)
22:10
<tantek>
wow that google doc is amazing
22:10
<tantek>
had no idea so much overengineering was going on in webpages. no wonder the silo web keeps getting slower.
22:11
<jgraham>
I'm not sure it's over-engineering as such
22:11
<jgraham>
I think that there are two related dev-side problems
22:12
<tantek>
I think you only get to code messes / overengineering like that by having massive engineering staffs that divide up everything, and everyone has to deliver some code, so it becomes an n-layers mess of inefficient crap
22:12
<tantek>
or, don't understand this layer? add a layer!
22:12
<jgraham>
1) A culture of just throwing random scripts onto a page without much clue what they're doing (e.g. ad scripts, analytics scripts). This unfortunately is lots of the revenue-providing stuff.
22:12
<tantek>
yes that big time
22:14
<jgraham>
2) A culture of favouring high levels of abstraction rather than optimising perf. This is partially because it's historically been needed to use jQuery or whatever to smooth over browser differences, but that's less true now
22:14
<jgraham>
Also, we haven't given great tools for people to identify jank
22:16
<jgraham>
(the wikipedia example is instructive for point 2 because they are using apparently simple jQuery methods in favour of simple DOM manipulations without realising that the jQuery methods bury lots of expensive calls)
22:16
<tantek>
a lack of "good examples" to copy from is also a problem
22:16
<tantek>
good *running* examples that is. that you can view source on and figure out "how did they do that?"
22:16
<jgraham>
With perf it's often more about what you *didn't* do
22:17
<jgraham>
It's harder to get the idea of "I didn't call any layout-computing functions" from an example
22:17
<tantek>
if you start with something performant, at least you can measure regressions when stuff gets added and like the doctor says, don't do that.
22:18
<tantek>
also when you have big engineering staffs, you're biased towards adding more crap code, and thus anti-performant by default.
22:18
<tantek>
it becomes hard to cut code for political reasons
22:18
<jgraham>
I think blaming this on "big engineering staff" is an over-simplification
22:18
<tantek>
people's managers feelings getting hurt etc.
22:19
<jgraham>
companies with lots of staff can produce performant code
22:19
<tantek>
can but rarely do
22:19
<gsnedders>
Is that not more a problem with too many managers? :)
22:19
<jgraham>
That seems hugely [citation needed]
22:20
<tantek>
citation was provided with that google doc - orgs with big-ish engineering staffs. Wikipedia was perhaps the exception.
22:20
<jgraham>
That's so clearly not valid
22:20
<tantek>
to provide a counter-point of anecdata, FB has a big engineering staff yet seems to be quite good at web perf, desktop or mobile
22:21
<tantek>
so yes, it is possible to have a big engineering staff and be performant, it's just rare.
22:21
<jgraham>
Since "slow and well-known" were presumably the defining features of the sample it seems much more reasonable to assume that well-known sites are produced by larger companies with more engineers
22:21
<terinjokes>
from what i understand, they have a smallish group dedicated to ensuring the rest of the org is performant on the web
22:22
<tantek>
jgraham - this is just a specific instance of http://en.wikipedia.org/wiki/Conway%27s_Law
22:23
<paul_irish>
jgraham: change /pub to /view to get the full comment thread along the side. good discussion in there
22:23
<JonathanNeal>
In CSS, can I have a variable written only if it has not already been declared? In other words, do CSS variables allow for something like !default in Sass?
22:24
<jgraham>
tantek: This whole sub-discussion is just a projection of biases about the merits of different organisational structure
22:24
<jgraham>
paul_irish: Oooh!
22:24
<jgraham>
paul_irish: Did I already mention this is awesome btw?
22:25
<paul_irish>
:) thanks! it was fun to write up
22:25
<paul_irish>
We're now talking to some folks in adsense. But I didnt want to gate publishing this on resolving those issues.
22:26
<paul_irish>
one of the big challenges for all ads/analytics is Viewability, which is now in the IAB mandatory guidelines for Ad Platform providers.
22:26
<paul_irish>
http://www.iab.net/iablog/2014/03/viewability-has-arrived-what-you-need-to-know-to-see-through-this-sea-change.html
22:27
<paul_irish>
tl;dr: ads need to know if they are at least 50% visible to the user for 1 continuous second.
22:27
<jgraham>
paul_irish: Not sure I can see the comments
22:28
paul_irish
ah. you're right. flipped off commenting to address trolls deleting content. one sec.
22:28
<tantek>
paul_irish: on that URL, scripts currently forbidden: <script>: 42
22:28
<tantek>
of course 42
22:28
<paul_irish>
turns out that the web platform is totally lacking performant APIs to evaluate those visibility concerns
22:28
<paul_irish>
which is why you see so many things binding to touch handlers and/or polling
22:29
<gsnedders>
What's the status of idlharness.js nowadays?
22:29
<tantek>
paul_irish: do they provide any guidance for how to performantly implement measuring that 50% visible for 1s+? or is this just an unfunded IAB mandate?
22:29
<paul_irish>
jgraham: https://docs.google.com/document/d/1K-mKOqiUiSjgZTEscBLjtjd6E67oiK8H2ztOiq5tigk/view is comment-enabled now.
22:30
<jgraham>
gsnedders: It works. It occasionally gets patches
22:30
<gsnedders>
jgraham: are we using it for most things now? last I knew there were concerns over the noisiness of results from it?
22:30
<paul_irish>
tantek: there is some text around "you need to poll every 100ms for 10+ times to confirm its a continuous second." beyond that, there is no suggestion on how one would acquire those metrics.
22:31
<jgraham>
paul_irish: THanks
22:31
<jgraham>
gsnedders: It's being used. I'm not sure what the noise concerns are/were but it's largely stable on gecko
22:32
<paul_irish>
tantek: http://www.mediaratingcouncil.org/063014%20Viewable%20Ad%20Impression%20Guideline_Final.pdf
22:32
<gsnedders>
jgraham: just so many fails because of people not using WebIDL for everything
22:32
<gsnedders>
jgraham: so it being unclear what fails are significant
22:33
<gsnedders>
jgraham: like, what failures are subtle parts of WebIDL, what failures are fundemental bugs in the implementation of the API
22:36
<paul_irish>
jgraham, tantek: http://www.sfgate.com/ was what kicked off this series. the amount of external script slowing down that site is just mind-blowing. and publishers are the web's bread and butter. :/
22:38
<jgraham>
gsnedders: Oh, in that sense. Well yes, sometimes browsers don't implement the WebIDL spec correctly and so fail tests. I'm not sure that's a problem for anything other than artifical things like progressing specs
22:38
<jgraham>
So if you mean "do they get used for CR transitions" then no, I think they are typically ignored
22:39
<jsbell>
yep; we had that debate for IDB for example since all the fails were in idl tests
22:39
<tantek>
paul_irish: perhaps it is time for faster independent publishers to displace the inefficient ones.
22:39
<jsbell>
"It would be nice if..." testharness/report could group errors somehow, e.g. "39 failures because [[Class]] is wrong on your prototypes".
22:41
<tantek>
paul_irish: going to www.sfgate.com without loading scripts results in empty page content body. so at some point they already killed themselves.
22:41
<paul_irish>
my point being more that monetizing free content on the web conflicts with delivering a fast (and good) user experience
22:41
<JakeA>
wanderview: hah you want to make that change now you've implemented it all? :D
22:41
<jsbell>
wanderview: you around?
22:44
<tantek>
viewing source on sfgate.com...
22:44
<tantek>
paul_irish: this is hilarious. sfgate is doing the exact *opposite* of the minimum of what you should put in the HTML. they are rendering all the "furniture" (heading, sidebar) nav / boxes statically, and leaving out the article body itself.
22:45
<tantek>
in ~420k of just the page HTML. Because it's not like adding the article inline would have added much size to 420k of JS, nav, sidebar crap.
22:46
<paul_irish>
yeah. it's a trainwreck.
22:47
<tantek>
because of course you need 33 static copies of <div class="social-links " social-url=".." social-hashId="" social-blurb="> instead of the thing you might actually be sharing.
22:49
<tantek>
correction: article permalinks are more viewable
22:49
<gsnedders>
jgraham: I just mean in terms of seeing how interoperable support for things is. "Can I use feature [x] in general and expect it to work?"
22:49
<tantek>
the home page is the total disaster
22:51
<jgraham>
gsnedders: Well I wouldn't load interfaces.html for a feature and expect all the failures to mean "this feature doesn't work" without understanding what the tests are
22:52
<jgraham>
But I wouldn't recommend doing that with any test
22:53
<tantek>
paul_irish: e.g. this page shows article text without needing JS: http://www.sfgate.com/news/article/California-drought-Sour-water-a-new-normal-6168768.php
22:57
<roc>
ad visibility detection is a great use-case for async geometry APIs
23:01
<JakeA>
roc: https://www.w3.org/Bugs/Public/show_bug.cgi?id=20246 seems like a good idea
23:02
<jgraham>
karlcow: I don't understand your point
23:02
<gsnedders>
jgraham: well yes, but it just seems worse than the general case :P
23:02
<roc>
JakeA: seems like not quite the right thing to me
23:03
<karlcow>
jgraham: hmm? did I send anything on whatwg list?
23:03
<roc>
I'll comment in the bug
23:03
<jgraham>
karlcow: dev.platform
23:04
<jgraham>
gsnedders: Well perhaps? I mean it's clearer *what*'s being tested here. The tests are rather simple. OTOH some complex tests might need a lot of study to work out if they're edge cases or major parts of the functionality
23:05
<gsnedders>
jgraham: aye, I guess
23:05
<sethf>
roc: is there a proposal for an async geometry api?
23:06
<roc>
not exactly
23:06
<sethf>
googling didn't find me anything concrete
23:06
<roc>
there has been some discussion
23:06
<roc>
F2F
23:06
<sethf>
i see
23:07
<karlcow>
I didn't make a point. Or at least I thought so. :) I gave context. It was on dev.platform. Mozilla Brain Parser Activation. Reading the email at first I have read "audit perf" then see the URI, click and then understood. CLICK. Ah it's BLINK. OK. Not what I was expected. it was in the context of Blink rendering engine. Some of these sites behave differently in Firefox.
23:07
<karlcow>
So if there are other people as brain dead as me, I have context. That's all.
23:07
<karlcow>
I guess I confused you more.
23:07
<karlcow>
/expected/expecting/
23:09
<jsbell>
gsnedders/jgraham: other than Chrome (which I'm intimately familiar with...), at this point how badly do the other browsers tend to fail idlharness tests for nitpicky IDL reasons vs actual feature reasons?
23:13
<jgraham>
jsbell: Gecko does pretty well I think
23:13
<jgraham>
We have quite reasonable WebIDL conformance these days, although it's surely not perfect
23:14
<jsbell>
jgraham: yeah, I got IndexedDB/interfaces.html to 100% on gecko
23:14
<jgraham>
karlcow: Oh, OK
23:15
<jgraham>
karlcow: Then my reply probably isn't as useful as I would like :)
23:15
<karlcow>
heh. Poetry!
23:22
<gsnedders>
jgraham: I thought it depended on which binding API Gecko was using for that API?
23:23
<karlcow>
ok jgraham I tried to make it more confusing :p ;) replied.
23:24
<jgraham>
gsnedders: I think the WebIDL bindings are used ~everywhere now, but ask bz or Ms2ger if you actually want to know
23:24
jgraham
-> sleep
23:25
<gsnedders>
jgraham: I could just well be out of touch with what's happened :)
23:26
<gsnedders>
jgraham: I don't exactly pay much attention to "how is Gecko implementing it's DOM bindings?"