| 04:12 | zcorpan | back from vacation |
| 04:30 | <MikeSmith> | zcorpan: time for you to get back to writing some w3cmemes |
| 04:30 | <zcorpan> | yeah man |
| 04:35 | <zewt> | well, that's awesome: system crashed and firefox completely lost my session |
| 04:38 | <zewt> | wow, it just uses a text file with json, not sqlite |
| 04:40 | <SamB> | what, you wanted an sqlite DB with JSON? |
| 04:40 | <zewt> | better than a raw file for important user data |
| 04:53 | <roc> | performance of JSON is much better |
| 04:53 | <roc> | and I suspect robustness is too |
| 04:53 | <roc> | overall |
| 04:54 | <SamB> | well, robustness would be more better either way if FF told you when the disk was full ;-P |
| 05:06 | <zewt> | json has zero robustness since it's a text format, not a data storage system |
| 05:06 | <zewt> | sqlite's journalling would probably have prevented me ending up with a nulled out session and having to dig out an old backup |
| 05:17 | <SamB> | zewt: yes, but it'd probably be missing random tabs or pages or something |
| 05:17 | <SamB> | depending on the cause of the problem |
| 05:20 | <zewt> | ... no, it wouldn't ... |
| 05:21 | <SamB> | well if you ran out of storage it likely would |
| 05:21 | <SamB> | at least that's what happens to my history |
| 05:21 | <zewt> | if you ran out of storage sqlite would throw an error and nothing would be changed |
| 05:21 | <zewt> | but they're just doing ad hoc writing to a file so who knows what happens |
| 07:28 | <JakeA> | Domenic: If I wanted to pipe a response into a cache and the browser (for rendering), how can I do that without the whole response ending up in memory? |
| 07:29 | <Domenic> | JakeA: in that case if you tee and then pipe both ends of the tee into places immediately, the data will just flow through |
| 07:29 | <JakeA> | Domenic: cool, that's what I thought |
| 07:29 | <Domenic> | JakeA: the problematic case is teeing and then piping only one end |
| 07:29 | <Domenic> | sorry I still haven't had time to process your reply |
| 07:29 | <Domenic> | Working on a talk I'll be giving in ... 7 hours? :P |
| 07:30 | <JakeA> | NOT ACCEPTABLE |
| 07:30 | <JakeA> | Domenic: no worries! I'm only just replying to that thread myself |
| 07:30 | <JakeA> | Good luck with the talk |
| 07:30 | <Domenic> | :) thanks |
| 07:40 | <Domenic> | JakeA: what do you mean by a transaction story that works for both IDB and fetchstore |
| 07:40 | <Domenic> | JakeA: my point was that .batch() is a better primitive to build anything more complicated on top of. For *both* APIs |
| 07:41 | <Domenic> | JakeA: the only thing I could think of that works for both would be some kind of strange global variable that is "in a transaction", that IDB and fetchstore both consult |
| 07:41 | <JakeA> | Domenic: slightlyoff was talking about a way to have the same story for both, rather than something cache specific. Maybe even something that can be a single transaction across both |
| 07:41 | <Domenic> | Bleh, I will try taking things up with him then |
| 07:41 | <JakeA> | Yeah, I like .batch, but happy to keep it as an algorithm for the sake of getting cache out of the door |
| 07:42 | <Domenic> | That is totally fair |
| 07:42 | <Domenic> | But I want to convince him that it is the correct primitive :) |
| 07:42 | <JakeA> | Domenic: Go for it :D |
| 07:42 | <Domenic> | Or hear what his thoughts are for something else, if there are concrete ideas |
| 07:43 | <JakeA> | Domenic: Just to confirm, if the active consumer of a stream errors/dies, something consuming the tee of the original stream is unaffected right? |
| 07:43 | <Domenic> | JakeA: right |
| 07:43 | <JakeA> | cool |
| 07:49 | <JakeA> | Domenic: Thinking of adding response.clone() and request.clone() rather than doing any implicit teeing. How does that sound? |
| 07:50 | <Domenic> | JakeA: I think I like it, but kind of want to read through the thread first |
| 07:50 | <JakeA> | No worries, don't worry about it until after your talk |
| 07:50 | <Domenic> | Seems related to "structured cloning of streams" discussion I kinda-started a while ago |
| 08:13 | <annevk> | Why are we changing the design of responses and requests? |
| 08:17 | <JakeA> | annevk: looking for ways to allow a response to have multiple consumers without adding magic |
| 08:17 | <JakeA> | (or indeed, a request) |
| 08:18 | <JakeA> | Domenic: if I tee a stream, can I read it without the original stream being read? If a teed (or original) stream isn't read, and data builds up in memory, what's expected to happen when memory runs out? All active streams fail? |
| 08:20 | <JakeA> | annevk: The use cases are, read a response as two types, send a response to cache & browser, read a request's body before deciding whether to fetch it or not |
| 08:20 | <annevk> | note that there is some tee'ing going on already per algorithms in Fetch |
| 08:21 | <annevk> | e.g. because of redirects a request can be tee'd several times |
| 08:25 | <JakeA> | good point |
| 08:25 | <annevk> | and at least once |
| 08:25 | <JakeA> | annevk: So .clone() would give that to the user. We'll be able to explain it in terms of new Response & a teed stream, but I think we need it sooner than streams |
| 08:25 | <annevk> | JakeA: why .clone() and not structured clone? |
| 08:25 | <annevk> | we want structured clones |
| 08:25 | <annevk> | and maybe structured clones need an API |
| 08:25 | <JakeA> | annevk: What's the API… aha |
| 08:26 | <JakeA> | annevk: so there isn't a way to structured-clone with script (aside from going back & forth between a dedicated worker I suppose) |
| 08:26 | <JakeA> | annevk: In fact, is there a sync way to create a structured clone? |
| 08:26 | <annevk> | you can always do window.postMessage |
| 08:27 | <annevk> | I don't think there's a synchronous API at this point |
| 08:27 | <annevk> | although there's a couple of spec algorithms that do it |
| 08:29 | <JakeA> | annevk: so, can we have .clone() that returns a structured clone, or are you thinking more window.createStructuredClone(obj); |
| 08:29 | <annevk> | the latter, something TC39-designed |
| 08:30 | <annevk> | e.g. you can clone `{ data: obj }` too |
| 08:30 | JakeA | plays Oh Fortuna |
| 08:31 | <annevk> | there's several open issues on this |
| 08:31 | <annevk> | including a big red note in Fetch |
| 08:32 | <JakeA> | annevk: You mean https://github.com/slightlyoff/ServiceWorker/issues/313? |
| 08:33 | <Domenic> | It would be good if structure clone were async |
| 08:33 | <Domenic> | I can't remember why off the top of my head but IIRC it enabled some scenarios |
| 08:35 | <Domenic> | JakeA: the way to think of teeing is you have created two new streams which are hooked up to the original stream. So when you read from one of the new streams, it pulls from the original stream into both new streams. The one you are reading from then gets the data handed to the user, but the other one just gets the data sitting there in the queue. |
| 08:35 | <Domenic> | If memory runs out ... usual platform OOM behavior, I suppose? Which is pretty undefined IIRC? |
| 08:35 | <annevk> | JakeA: yup |
| 08:36 | <annevk> | OOM is undefined |
| 08:36 | <annevk> | There was a thread recently about defining stack limits |
| 08:36 | <Domenic> | You could also imagine the platform swapping out all the data to disk and letting you read it later... the details are hidden enough that this is possible. I wouldn't want to write such a tee-with-disk-intermediating myself, but it could be done. |
| 08:37 | <Domenic> | You'd want to avoid that if possible though. Ideally you want .read() to translate straight into a syscall, and the more layers of teeing and caching you add in between, the less likely that is. |
| 08:38 | <JakeA> | Domenic: in your example there, were you thinking of two calls to tee? Otherwise I'm not sure where the *two* new streams come from |
| 08:38 | <Domenic> | JakeA: a tee is meant to create two new streams from the original, thus the "T" shape |
| 08:38 | <Domenic> | or "Y" shape |
| 08:39 | <Domenic> | one stream goes in, gets consumed, two unconsumed streams come out |
| 08:39 | <Domenic> | well, "consumed" isn't quite right, we don't wait for you to read to the end |
| 08:39 | <JakeA> | Got it |
| 08:40 | <JakeA> | I guess that makes request.clone() either weird or all the more useful. It'd have to replace its own stream with one part of the tee |
| 08:41 | <JakeA> | starting to understand the issues around structured cloning and streams |
| 08:41 | <Domenic> | hmm |
| 08:42 | <annevk> | Domenic: is there an explanation somewhere of why an IO stream needs to have both readable and writeable parts? |
| 08:42 | <annevk> | Domenic: e.g. why it can't be more like the simplest asynchronous iterable object you can imagine (that has both push and async read) |
| 08:42 | <Domenic> | annevk: not sure exactly what you mean... a stream is either readable (someone else controls data production) or writable (someone else controls consumption of data you put in it) |
| 08:43 | <annevk> | Domenic: why can't it be more like a promise, where that can be the case, but you can also control both ends |
| 08:44 | <Domenic> | annevk: a readable stream is much like a promise. (And a writable stream, in reverse.) But the creator controls one end, and does not give the ability to others via the public API |
| 08:44 | <Domenic> | a readable stream is only readable, although its creator says how to get the data that consumers read from it |
| 08:45 | <Domenic> | you could imagine a stream API that leaves both ends open for people to shove data through, but that has some ergonomic issues: |
| 08:45 | <Domenic> | instead of writing e.g. "when someone writes data to me, put it in the file descriptor," you have to continually be reading from the output end, and then putting the results of what you read into the file descriptor |
| 08:47 | <annevk> | I guess it's needed for perf, but it seems weird that we're focused that much on current low-level implementation details, rather than what is the best abstraction for what we want. |
| 08:47 | <Domenic> | It's not really perf, it's ergonomics |
| 08:49 | <annevk> | If read returns a promise, you don't have to continuously read for instance |
| 08:49 | <Domenic> | You have to recurse at the very least |
| 08:49 | <Domenic> | But hmm |
| 08:49 | <annevk> | It would just fulfill with the next chunk or error |
| 08:50 | <Domenic> | I am starting to do perf benchmarks and it is possible promise-returning read() might make a comeback if those show non-failure |
| 08:50 | <annevk> | Yes, and with recursion you get nice ergonomics. Especially with synchronous notation |
| 08:50 | <annevk> | Sounds good |
| 08:54 | <JakeA> | Domenic: if I tee a stream but don't read either of the tees, is the original stream consumed or does it wait for the first read on one of the tees? |
| 08:54 | <Domenic> | JakeA: it waits. Although trying to read from it would race with the tee mechanism, which is also trying to read from it |
| 08:55 | <JakeA> | yeah, was just trying to work out when it starts filling memory. Got it. |
| 08:55 | <Domenic> | I am looking forward to thinking harder about how to implement clone() ... clearly it is not quite the same as teeing |
| 09:07 | <JakeA> | Domenic: can it be explained with a tee and taking one part of the tee for itself? |
| 09:16 | <Domenic> | JakeA: seems weird. maybe possible, but i think i'd use something slightly different than a tee... |
| 09:29 | <JakeA> | annevk: In https://github.com/slightlyoff/ServiceWorker/issues/398, what's the difference between "use a local file if available" and "conditional request", does the former not care about freshness? |
| 09:57 | <annevk> | JakeA: maybe, not sure; I'm not that familiar with cache implementations and what options they have |
| 09:57 | <annevk> | JakeA: I can imagine if you're offline you might decide to not care about freshness |
| 10:00 | <Ms2ger> | annevk, r? https://github.com/w3c/web-platform-tests/pull/1131 |
| 10:00 | <JakeA> | annevk: fair enough, we do that in Chrome (behind a flag, I think) |
| 10:03 | <annevk> | Ms2ger: should I merge it after I reviewed it? |
| 10:03 | <Ms2ger> | Either way |
| 10:04 | <annevk> | Ms2ger: bit surprised the critic bot didn't post anything back |
| 10:56 | <JakeA> | annevk: thought… do we need to make fetch('//other-origin/whatever', {mode: 'no-cors'}) revalidate against the server? Else, if I get a response back, and navigator.offLine == true, we're exposing the user's history |
| 10:56 | <JakeA> | annevk: more so if the developer can go to the cache despite the cached entry being stale |
| 11:05 | <annevk> | JakeA: can't you probe that already with <img>? |
| 11:05 | <annevk> | JakeA: agreed that with the cache settings stuff, if we add that for v1, we'll need to carefully consider privacy |
| 11:06 | <JakeA> | annevk: for images, yeah. Scripts too I guess. |
| 11:06 | <JakeA> | annevk: hmm, maybe anything with iframes |
| 11:09 | <tobie> | Boy, SW issue 372 is now officially all over the place. |
| 11:09 | <JakeA> | yeah, ok, iframes too. Not a new problem then. |
| 11:10 | <JakeA> | tobie: is it? Felt like it was zoning in. |
| 11:12 | <tobie> | JakeA: well, you need to be familiar with Stream API status, teeing, stream cloning, advantages of async structured cloning over sync one, future tc39 plans for structured cloning, transactional requests in indexedDB, etc. |
| 11:13 | <tobie> | Did I mention request had a stream too? How that interact at the SW level just blew my mind. |
| 11:14 | <JakeA> | when you submit a form (with a mixture of files and form fields) that's a body stream that's sent to the server |
| 11:15 | <tobie> | Of course. Makes complete sense. It's just. Woah. |
| 11:15 | <JakeA> | yeah, it goes all the way down |
| 11:21 | <tobie> | JakeA: why does cache.addAll deplete a request's body stream? Do we cache non GET requests or does fetch send body of GET requests? |
| 11:21 | <tobie> | (asking for a friend) |
| 11:22 | <tobie> | ;) |
| 11:22 | <JakeA> | tobie: bloody good point. No, it rejects with non-GET requests, so it's a non-issue |
| 11:23 | <JakeA> | updated |
| 11:23 | <tobie> | JakeA: how are GET requests with a body handled though? |
| 11:24 | <tobie> | Wasn't it you writing recently about how these were a thing? |
| 11:26 | <JakeA> | not that I know of. annevk, should we throw if a GET request is constructed with a body? |
| 11:26 | <annevk> | Domenic: so btw, the read-write distinction for streams is problematic for Request and potentially Response objects btw |
| 11:26 | <annevk> | Domenic: nobody had a good answer there so far and we plan on shipping this end of Q3... |
| 11:27 | <annevk> | JakeA: hmm, might not be handled specifically at the moment |
| 11:27 | <annevk> | JakeA: XMLHttpRequest ignores the body for GET/HEAD |
| 12:20 | <JakeA> | annevk: if we're not throwing for headers, we shouldn't throw for body I guess |
| 12:22 | <annevk> | I guess I should try to handle this in Fetch itself so we don't have to reinvent it for each API |
| 12:22 | <JakeA> | agreed |
| 12:22 | <annevk> | JakeA: there's also https://github.com/slightlyoff/ServiceWorker/issues/120 I just noticed |
| 12:23 | <annevk> | JakeA: maybe willchan & co should look at that |
| 12:23 | <JakeA> | annevk: Yeah, I don't have strong feelings there |
| 12:45 | <annevk> | Declares us-ascii, expects windows-1252; nice find zcorpan! http://futbolenlatele.com/ |
| 12:45 | <zcorpan> | np |
| 12:46 | <zcorpan> | found it while eating my lunch :-) |
| 12:49 | <zcorpan> | "there are no pages doing X" is basically always false on the web |
| 12:50 | jgraham | wonders if that will fit in the topic :) |
| 12:51 | <annevk> | fits in a tweet |
| 12:52 | <zcorpan> | Hixie: – works with the new pipeline i take it? |
| 14:09 | <zcorpan> | https://www.w3.org/Bugs/Public/show_bug.cgi?id=9785#c10 - no pages doing X for X = moznofilter :-) |
| 14:30 | <zcorpan> | Hixie: ok if i close srcset bugs that are fixed by <picture>? |
| 14:31 | <annevk> | zcorpan: at least some time ago it was fine to close bugs given solid rationale |
| 14:44 | <zcorpan> | MikeSmith: do you have opinions on https://www.w3.org/Bugs/Public/show_bug.cgi?id=25552 ? |
| 15:17 | <hemanth> | meow, Object.keys returns an arrayLike object or an array ? |
| 15:18 | <hemanth> | specs says array |
| 15:18 | <hemanth> | but... |
| 15:18 | <hemanth> | >> obj = {x:1,y:2}; for (k in Object.keys(obj)) {console.log(k)} |
| 15:18 | <hemanth> | gives '0', '1' |
| 15:19 | <hemanth> | indices |
| 15:21 | <caitp> | Object.getPrototypeOf(Object.keys(...)) === [] |
| 15:22 | <Ms2ger`> | What else? |
| 15:23 | <caitp> | Array.isArray(Object.keys(...)) === true ? |
| 15:23 | <caitp> | etc :c |
| 15:23 | <caitp> | Object.prototype.toString(Object.keys(...)) === [object Array]? |
| 15:24 | <caitp> | + missing `.call` |
| 15:25 | <hemanth> | heh heh my bad, Enumeration VS Iteration |
| 15:30 | <caitp> | yes, it won't behave the same as for-of |
| 15:31 | <hemanth> | hrrm |
| 15:34 | <hemanth> | there must be a deprecated 'for each...in' as well ;) |
| 15:34 | <Ms2ger> | There is |
| 15:35 | <Ms2ger> | Thanks to E4X |
| 15:36 | <caitp> | and for-of will confuse people in other ways too, we don't know how to spec consistent languages |
| 15:36 | <hemanth> | heh heh |
| 15:41 | <hemanth> | I would stick for forEach for array and for-of for generator objects and for-in for the rest... |
| 16:39 | <JakeA> | annevk: ahh, so is https://github.com/slightlyoff/ServiceWorker/issues/398#issuecomment-51081392 correct, "conditional" mean must-revaidate? |
| 16:39 | <JakeA> | means& |
| 16:39 | <JakeA> | means** |
| 16:39 | <JakeA> | means* |
| 16:39 | <JakeA> | there, fixed. |
| 16:44 | <annevk> | JakeA: oh, yes, conditional goes via a server |
| 16:52 | <JakeA> | Riiiiiiight. I'd gotten confused. I thought "available" meant something other than "fresh" |
| 18:08 | <Hixie> | zcorpan: if they're assigned to me, comment on them first so i can check them out |
| 18:24 | <Hixie> | "There is no way to represent a promise value in IDL" |
| 18:24 | <Hixie> | what's a "promise value"? |
| 19:45 | <Domenic> | annevk: whatever form it takes it will almost certainly be { input, output } |
| 19:45 | <annevk> | Domenic: a class that has both input and output? |
| 19:46 | <annevk> | Domenic: because a plain object is unlikely to fly by Adam Barth |
| 19:47 | <Domenic> | annevk: not sure which yet. mostly a convention. |
| 19:48 | <Domenic> | annevk: but yes, something like var { input, output } = new PassThroughStream() seems reasonable. |
| 19:48 | <Domenic> | this comes back to my confusion as to how to "bootstrap" a two-ended stream |
| 19:49 | <Domenic> | if a PassThroughStream is composed of a { WritableStream input, ReadableStream output }, then WritableStream and ReadableStream should have constructors |
| 19:50 | <Domenic> | But kind of the whole point of PassThroughStream is that you should be able to use it to create either end, without creating them separately.... |
| 19:50 | <Domenic> | meh, it's solvable |
| 19:51 | <Domenic> | just need to get these damn benchmarks finished |
| 19:51 | <Domenic> | then the potential simplifications can begin |
| 20:30 | <smaug____> | does chrome warn about use of some deprecated features ? |
| 20:33 | <caitp> | yes |
| 20:38 | <smaug____> | caitp: which features for example? |
| 20:39 | <smaug____> | Hmm, looks like MutationEvent usage has dropped |
| 20:39 | <caitp> | someone filed a bug on angular about browsers (including chrome) complaining about touching Event.returnValue some time ago |
| 20:39 | <caitp> | so that would be one |
| 20:40 | <smaug____> | caitp: I guess it just doesn't warn about mutation events |
| 20:40 | <smaug____> | nor sync XHR |
| 20:40 | <caitp> | i'm not sure if synchronous XHR is properly deprecated in chromium yet |
| 20:40 | <caitp> | tyoshino would probably know |
| 20:41 | <caitp> | if there was an intent to deprecate thread for that, I missed that one |
| 20:41 | <SamB> | hmm, is it that complicated that it needs deprecating in a technical sense? |
| 20:42 | <SamB> | rather than just a "hey dumbass, don't block your script on that; it's bad for UX" |
| 20:42 | <smaug____> | caitp: it is deprecated in the spec |
| 20:42 | <smaug____> | all the browser vendors agreed about that |
| 20:42 | <caitp> | yes, but not necessarily in browsers |
| 20:43 | <caitp> | IE a browser doesn't necessarily warn you, there aren't necessarily plans to remove the feature yet |
| 20:43 | <SamB> | oh, that reminds me about trigraphs |
| 20:44 | <smaug____> | well, in Gecko the plan is to "remove-when-the-usage-low-enough-and-warn-until-then" |
| 20:45 | <caitp> | that's a reasonable approach :> |
| 21:06 | <zcorpan> | Hixie: comment and close at the same time ok? or just comment? |
| 21:11 | <jarek> | Hi |
| 21:12 | <jarek> | which spec covers the data binding functionality from Polymer? |
| 21:12 | <jarek> | the template spec is said to be moved to HTML5 spec, but I can't find any mention of data binding there |
| 21:13 | <Hixie> | zcorpan: comment, if you comment and close i won't see it for months (i only read my bugmail ~annually) |
| 21:13 | <Hixie> | jarek: there is no spec that covers data binding |
| 21:13 | <Hixie> | to my knowledge |
| 21:14 | <zcorpan> | k |
| 21:15 | <jarek> | so the stuff described here is completely non-standard? http://www.polymer-project.org/docs/polymer/databinding.html |
| 21:15 | <jarek> | is there any chance that Mozilla will implement it? |
| 21:20 | <Hixie> | jarek: yes, that is currently non-standard. |
| 21:20 | <Hixie> | jarek: no idea what mozilla's plans are, but if two browsers implement this, then it's a de facto standard |
| 21:31 | <Domenic> | chrome does not implement it either |
| 21:31 | <Domenic> | it is just a library |
| 21:31 | <Domenic> | produced by the same company that produces chrome |
| 21:31 | <Domenic> | jarek ^ |
| 21:31 | <smaug____> | and there isn't any spec for that data binding |
| 21:35 | <jarek> | every Web Components talk by Google I have seen was actually discussing Polymer |
| 21:36 | <jarek> | I thought it was just a shim like e.g. Traceur |
| 21:37 | <caitp> | it's sort of a mix |
| 21:38 | <caitp> | polyfills for custom elements/html imports/etc, as well as a library of components and some syntax for simplifying the creation of components + databinding |
| 22:07 | <caitp> | i dunno hixie, I think the arguments against the behaviour of constraint validation have been pretty well reasoned --- and not limited to my own criticisms of it. it's just not how people expect it to behave |
| 22:08 | <Hixie> | i don't understand the problem |
| 22:08 | <Hixie> | i mean, i really don't |
| 22:08 | <Hixie> | valueMissing tells you if the value is missing |
| 22:08 | <Hixie> | badInput tells you if the user has entered bad input |
| 22:08 | <Hixie> | that seems to me to cover all the bases |
| 22:08 | <Hixie> | what am i missing |
| 22:09 | <caitp> | that's basically it, but it's just more complicated than it really needs to be, there are things which are sort of misnomers (like [novalidate]), there's a lot of stuff there that really confuses users |
| 22:10 | <Hixie> | sounds like you're talking about more than just that bug |
| 22:11 | <Hixie> | if there's other things that need fixing, then please do file bugs (but bear in mind that if people depend on it, it's too late to change, you should have complained earlier when we asked for feedback!) |
| 22:11 | <caitp> | well, [novalidate] isn't related to the valueMissing issue, but it's in the same family of things which are not very intuitive to users |
| 22:14 | <Hixie> | that's fine, but then file a new bug :-) |
| 22:14 | <Hixie> | i thought you were talking about the bug i commented on |
| 22:32 | <Hixie> | TabAtkins: in css-font-loading - "unloaded" sounds very much like something that used to be loaded but is no longer loaded |
| 22:32 | <Hixie> | TabAtkins: consider e.g. onunload, onbeforeunload, etc. |
| 22:32 | <TabAtkins> | Hm, true. |
| 22:33 | <Hixie> | TabAtkins: i don't have a much better term, but fwiw the media stuff uses "none" |
| 22:34 | <Hixie> | other terms i've used include "empty", "idle", "nothing" |
| 22:35 | <Hixie> | TabAtkins: also it's more common to use readyState than status, fwiw. |
| 22:36 | <Hixie> | since i'm giving feedback, some more notes: |
| 22:36 | <Hixie> | i recommend against using ES-style [[Foo]] syntax, it is hard to read |
| 22:36 | <TabAtkins> | Hm. Unsure if I can change a property name, but I might try. I'll put up a message for it, at least. |
| 22:36 | <TabAtkins> | Yeah, not super happy about that either. I want something to indicate "internal" properties, though. |
| 22:37 | <TabAtkins> | (It's super-inconvenient to type, since it collides with Bikeshed's shorthands.) |
| 22:37 | <Hixie> | just say "FontFace objects have an internal font status promise, which..." |
| 22:37 | <Hixie> | where "font status promise" is <dfn>ed |
| 22:38 | <Hixie> | what's a Promise<boolean>? Aren't you really just promising a void? I mean, you'll never resolve to false, will you? |
| 22:38 | <Hixie> | i'd probably do a Promise<FontFace>, like load() |
| 22:38 | <Hixie> | (for loaded) |
| 22:39 | <Hixie> | not sure what "... of which one is not null and the rest are null." means. There's two things. One is null and the other not? What's the one that isn't null set to? |
| 22:39 | <TabAtkins> | Actually, that's an IDL error (Promise<boolean>). The promise it refers to resolves to the FontFace. |
| 22:40 | <TabAtkins> | "rest are null". Yeah, just two things. (Maybe there were more before, and this language is a remnant? I forget.) The one that isn't null gets set by the constructor. |
| 22:43 | <Hixie> | other than that, looks ok. I'm not sure about the whole Set thing, that looks a bit overcomplicated, but I assume that's just waiting for WebIDL to catch up. |
| 22:43 | <Domenic> | Can workers (service workers in particular) access WebRTC? |
| 22:45 | <Hixie> | Domenic: i don't think they've made that work yet, but long term i'm not aware of a reason that shouldn't work |
| 22:45 | <Domenic> | Ya that's kind of what I expected. Curious if there was a reason not; heartened that you don't think there is such a reason. |
| 22:47 | <TabAtkins> | Hixie: Yeah, the Set mimicry is me waiting for IDL to have something that'll do it for me. I had a [SetClass] attribute previously, but heycam ended up not wanting to spec that yet. |
| 22:47 | <TabAtkins> | I think we're waiting for JS to actually define a subclassable Set/Map/etc. |
| 22:48 | <TabAtkins> | (Right now, you simple can't subclass them properly. Either you have to manually copy methods (and thus don't get new methods added by future specs or by authors), or you aren't able to enforce any constraints (because authors can modify it via the core Map/Set methods instead, bypassing whatever restrictions you've added). |
| 22:48 | <TabAtkins> | ) |
| 22:52 | <Hixie> | sounds like the mess we had (have?) with Array |
| 22:55 | <TabAtkins> | Yup. |
| 22:55 | <TabAtkins> | Except it's even less explicable, because you don't even need a Proxy to get it right. |
| 22:57 | <gsnedders> | why didn't it get it right for Set/Map/etc. first time? |
| 22:57 | <caitp> | if MySpecialSet has its own special 'add' method to enforce constraints, who is to stop me from invoking Set.prototype.add.call(mySpecialSet, value) and bypass any constraints anyways? |
| 23:20 | <Domenic> | Saying that it's "right" for a subclass to impose more restrictions than its superclass is a matter of opinion |
| 23:20 | <Domenic> | http://en.wikipedia.org/wiki/Liskov_substitution_principle etc |
| 23:22 | <SamB> | caitp: on that note, I think I'm permanently confused about which is the prototype in prototype-based programming |
| 23:22 | <jyasskin_w> | I definitely understand the desire to define a class whose specification "automatically" grows any methods added to Map, say, but which adds certain restrictions onto its values. I wouldn't call that a "subclass", but it'd be worth finding a word for it that doesn't run into LSP complaints. |
| 23:23 | <caitp> | instead of this, we implement new NoInterfaceObjects in C++ which inherit from a common base in C++ and extend the behaviour appropriately, without exposing a way to do it in scriptland |
| 23:23 | <caitp> | and this makes everybody happy |
| 23:26 | <caitp> | except that I guess we aren't even really doing that yet for all of the custom containers |
| 23:26 | <Domenic> | One way of doing this would be to divide up the container classes into "core" and "mixin" methods |
| 23:27 | <Domenic> | so e.g. .add, .delete, [Symbol.iterator] would be core; .forEach would be mixinable |
| 23:27 | <Domenic> | and if we later added e.g. .map it would be mixinable, delegating to [Symbol.iterator] |
| 23:27 | <caitp> | but you don't want to use core .add, you want to impose restrictions on what can be added to your magic collection |
| 23:27 | <Domenic> | that way you can do Object.define(MyMap, MapMixins) as long as MyMap implements the core interface |
| 23:27 | <Domenic> | yes |
| 23:28 | <Domenic> | you implement your own .add etc.; you don't subclass Map |
| 23:28 | <Domenic> | then you mixin MapMixins to get all the non-core methods |
| 23:28 | <Domenic> | I wonder if this has anything to do with traits |
| 23:28 | <caitp> | traits would have been neat, I was sad that didn't make it =( |
| 23:29 | <caitp> | [[into harmony]] |
| 23:29 | <Domenic> | this looks to be exactly related to traits |
| 23:29 | <Domenic> | based on http://soft.vub.ac.be/~tvcutsem/traitsjs/tutorial.html |