00:05
<TabAtkins>
heycam: See, for example, CSS Syntax, which declares the meaning of each token.
00:06
<heycam>
TabAtkins, CSS Syntax also defines parsing algorithms in terms of token consumption, which is something that I'd like to avoid if possible
00:06
<heycam>
TabAtkins, I think for CSS it's fine, since you can't neatly describe it with "parse with this grammar or fail"
00:07
<TabAtkins>
You're doing that anyway, if you say things like "the digit-sequence construction represents the result of evaluating the matched characters as a base-10 number", or whatever.
00:08
<TabAtkins>
heycam: Also, only the *parser* has error-recovery of that sort. Virtually all individual constructs in CSS are described in "parse correctly or fail" terms.
00:08
<heycam>
TabAtkins, ok
00:08
<heycam>
TabAtkins, well I'll see what happens when I eventually rewrite that section :)
00:08
<TabAtkins>
The three-level parsing we have is just a convenience, allowing us to do the various definition work in one place for each thing.
00:08
<TabAtkins>
Tokenizing -> Generic Parsing -> Feature Grammars
00:44
<Hixie>
othermaciej: i gotta say, "this.elements.a.value" seems vastly preferable to "this.querySelector("#a").value"
00:44
<Hixie>
othermaciej: maybe i've just got odd engineering aesthetic taste :-)
00:45
<othermaciej>
Hixie: if it's based on aesthetics and not terseness, I could go either way
00:46
<othermaciej>
(a) magic namespaces can be convenient but on the other hand they can be conceptually confusing
00:46
<othermaciej>
(b) using a very context-specific way to access an element is in some ways less elegant than using a fully general way
00:47
<TabAtkins>
(c) What happens with <div id="toString">???
00:47
<othermaciej>
if it were not for the issues with form.elements that Jonas raised, I would be all for extending it (after all, what's the downside)
00:47
<TabAtkins>
<div id="__proto__">
00:47
<othermaciej>
but the fact that it misses some kinds of form elements and is a live collection - ick
00:48
<othermaciej>
Jonas's getParticipants() could provide a symbolic magic namespace if desired, though at some cost of terseness relative to elements
00:48
<TabAtkins>
Also, we're gaining just a plain .query() (iirc the name it's ending up with?), so "this.query('#a')" versus "this.elements.a" becomes more evenly matched in terseness.
00:48
<othermaciej>
this.query('#a') is some sweet syntax IMO
00:50
<sicking>
in general, proxy like APIs do not seem that great to me. Especially when they have built-in properties like .length, .item, .namedItem and .__proto__
00:51
<othermaciej>
I tend to prefer things that are more overtly a dictionary instead of relying on the poor-man's-dictionariness of JS objects
00:51
<sicking>
I think form.control("name") is just as good as form.elements.name
00:51
<sicking>
oh, right, form.elements does the crazy thing of "return a node or a nodelist" thing
00:52
<TabAtkins>
Yes, objects as pretend dictionaries is terrible.
00:52
<sicking>
that adds another level of crazyness
00:52
<sicking>
especially considering the liveness. It means that a property can morph from being a Node to a NodeList
00:53
<sicking>
a live NodeList to make things worse
00:55
<sicking>
I'll also note that ES6's map class is based on .get() and .set() functions, rather than .foo.
00:56
<sicking>
I generally prefer to defer to the API design patterns from TC39 than the ones from the DOM
00:57
<TabAtkins>
And I've been pushing hard in the same direction, encouraging use of Map/Set methods rather than homebrew collections.
00:58
<sicking>
I'll add Array to that list
01:04
<othermaciej>
Map, Set and Array are good primitives and good ways of managing collections
01:09
<sicking>
TabAtkins: that said, the way you are inheriting Map in the fontloader looks iffy to me. I sent feedback to jdaggett (since he reached out for review). Not sure if he forwarded it to you?
01:09
<TabAtkins>
I didn't get that feedback, I don't think.
01:09
<TabAtkins>
What's iffy about it?
01:10
<TabAtkins>
(heycam also said he might have problems with how I asked for [MapClass] to work, but he hasn't worked out how to fix yet.)
01:10
<sicking>
TabAtkins: for example, what happens if a font is removed from the Set (I forget if you inherit Map or Set?)
01:10
<TabAtkins>
It's a Map.
01:10
<sicking>
TabAtkins: key'ed on?
01:10
<TabAtkins>
Blarg, sorry. It's a set.
01:11
<TabAtkins>
Anyway, this <http://dev.w3.org/csswg/css-font-loading/#font-face-set-css>; defines what happens if you mutate the set yourself.
01:11
<heycam>
TabAtkins, if we make plain Array objects the values of choice for IDL attributes that reflect list-ish things, we might be able to do the same with Map for associated array stuff. but while the browser can Object.watch the Array to watch for changes to it from script, you can't do that with Maps
01:11
<sicking>
TabAtkins: what's the purpose of keying it on FontFace objects? When would you ever want to do a lookup based on a FontFace object?
01:12
<heycam>
since the data is stored in internal properties, and there aren't real property changes that would trigger the Object.watch observer
01:12
<TabAtkins>
heycam: I know. :/ That lack of ability to hook maps/sets is super frustrating.
01:12
<TabAtkins>
sicking: I don't understand your question, since it's not keyed on anything.
01:12
<sicking>
TabAtkins: sets are keyed on their values, no?
01:12
<TabAtkins>
sicking: They're not really "keyed" on anything?
01:12
<sicking>
TabAtkins: i disagree
01:12
<TabAtkins>
I mean, technically, sets can be implemented as maps with a dummy value.
01:13
<sicking>
TabAtkins: sets are maps with no value
01:13
<sicking>
but they still have keys
01:13
<TabAtkins>
But they're just an Array with a less visible ordering, and no duplicates.
01:13
<sicking>
hence they are keyed
01:13
<TabAtkins>
I don't see how they have keys.
01:13
<TabAtkins>
There's no .get() method.
01:13
<TabAtkins>
Just .add()
01:13
<TabAtkins>
And .has()
01:14
<sicking>
TabAtkins: there's a .has() method
01:14
<TabAtkins>
And?
01:14
<sicking>
the has method does a lookup based on the value you pass in. I.e. it uses the value as a key
01:14
<TabAtkins>
Sure.
01:14
<sicking>
expectation is that .has() runs in constant time, no?
01:15
<sicking>
ish
01:15
<TabAtkins>
Yes.
01:15
<sicking>
that means that there's a hash table
01:15
<TabAtkins>
Yes.
01:15
<sicking>
hash tables have keys
01:15
<TabAtkins>
We can keep doing this all day, or you can tell me what your point is. ^_^
01:15
<othermaciej>
talking about keys in the context of a non-associative data structure is not the clearest terminology
01:16
<sicking>
TabAtkins: why would you ever want to do .has(FontFace)? Or .add(FontFace)?
01:16
<sicking>
TabAtkins: or .delete(FontFace)
01:16
<TabAtkins>
You probably don't want to do .has().
01:16
<TabAtkins>
.add() is useful if you construct your own.
01:17
<TabAtkins>
.delete() isn't useful most of the time, but if you can add, there might be use-cases for deleting.
01:17
<TabAtkins>
And it comes for free with the "act like a Set", so we keep it.
01:17
<sicking>
TabAtkins: what's the use case for de-duping FontFace objects?
01:17
<sicking>
TabAtkins: i.e. what's the use case for making the .add function not add if the FontFace instance already exists?
01:17
othermaciej
guesses is that sicking's point is that an array would be better
01:17
<TabAtkins>
the fact that dupes are meaningless?
01:18
<othermaciej>
is the sequence relevant?
01:18
<sicking>
othermaciej: right. The current API doesn't seem to take advantage of the hash at all
01:18
<TabAtkins>
Using an array means that I expose an index as well. This index isn't stable (it changes if you add/remove @font-face rules from the document's stylesheets).
01:18
<sicking>
i think having a myFontLoader.loadedFonts Array would be much more intuitive
01:19
<TabAtkins>
The only thing I really want to expose is .add() and [iterator]()
01:19
<TabAtkins>
Set is the best match for that.
01:19
<sicking>
TabAtkins: as soon as you have an iterator you have indexes
01:20
<sicking>
so you'll have to deal with that problem no matter what
01:20
<othermaciej>
index being unstable is not really a good reason to specifically not use an Array
01:20
sicking
isn't sure if Sets have stable indexes
01:20
<othermaciej>
as long as there's still an order
01:20
<TabAtkins>
Only ad-hoc ones you invent yourself. You can't use those indexes later to directly access something (and be fooled by the value at that index being swapped out).
01:20
<TabAtkins>
The worst you could do is associate it with an index in a side data structure, and assume that'll be stable across invocations.
01:20
<othermaciej>
document.queryAll() gives you an array, because element order in the document is still an order, even though indices can change if you add or remove elements
01:21
<othermaciej>
well, an array-ish thing
01:21
<TabAtkins>
But if you have modern JS, you can just use a Map (or a WeakMap) instead and key it to the FontFace directly.
01:21
<othermaciej>
rather than a set-ish one
01:21
<othermaciej>
Array doesn't really promise a stable order, but it does vaguely imply that order is in some what meaningful
01:22
<sicking>
TabAtkins: is synchronously adding fonts even a good idea. It forces parsing on the main thread, no?
01:22
<TabAtkins>
Everything has an order in JS, because we're not comfortable with enforcing randomized iteration orders, and anything less creates a compat hazard.
01:22
<TabAtkins>
sicking: Nope, read the spec. ^_^
01:22
<TabAtkins>
It doesn't force any more synchrony than adding a new @font-face to the document via script does.
01:22
<sicking>
TabAtkins: sorry, if you want me to read the full spec in full detail you won't get my review
01:23
<TabAtkins>
I wasn't aware we were doing an ad hoc review right now. ^_^
01:23
<TabAtkins>
Normally, questions that can be answered by the spec can be adequately answered by "read the spec". ^_^
01:23
<TabAtkins>
Actually parsing the font face data is done asynchronously. We expose a promise for when the font is fully loaded and ready.
01:24
<sicking>
ah
01:24
<sicking>
any reason you're not accepting URLs or Blobs in the ctor then
01:24
<sicking>
?
01:24
<TabAtkins>
I am.
01:24
TabAtkins
holds off saying "read the spec" again...
01:25
<TabAtkins>
http://dev.w3.org/csswg/css-font-loading/#font-face-constructor step 3
01:26
<TabAtkins>
Right now I only accept TypedArrays as direct data, but I could accept a Blob as well I suppose.
01:26
<sicking>
ah, URLs are indeed accepted, but not Blobs afaict
01:26
<sicking>
not a big deal as long as URLs are there
01:26
<sicking>
though less leak prone
01:26
<TabAtkins>
Well... Do blobs have serializable URLs?
01:27
<sicking>
yes, if you use URL.createObjectURL
01:27
<TabAtkins>
Okay.
01:27
<sicking>
but it's leak prone
01:27
<TabAtkins>
It's not a problem to take a Blob directly.
01:28
<TabAtkins>
Hm, is there anything weird I need to know about Blobs? Or does http://dev.w3.org/csswg/css-font-loading/#font-face-constructor step 4 handle Blobs sufficiently?
01:28
<TabAtkins>
(Being somewhat generic about "the data in it".)
01:29
<sicking>
i think that's pretty much good enough
01:29
<TabAtkins>
kk
01:29
<TabAtkins>
I'll just add Blob to the BinaryData typedef, then.
01:29
<TabAtkins>
(We don't implement the BinaryData side of the constructor quite yet.)
01:29
<annevk-cloud>
At some point blobs will have a way to read their data, not in the blob spec yet
01:30
<sicking>
TabAtkins: i'm still not sure I see the value in the current use of a Set though
01:30
<annevk-cloud>
You need that to better deal with failure or the blob being closed and such
01:30
<sicking>
TabAtkins: Adding a property with an Array seems better
01:30
<TabAtkins>
Shrug. Array has more stuff in it than I needed - all I need is something that'll hold some objects.
01:31
<TabAtkins>
(I'm seeing Set as being simpler than an Array.)
01:31
<sicking>
TabAtkins: you could make the Array be frozen to avoid worrying about mutations
01:31
<TabAtkins>
Nah, we want to allow mutations.
01:31
<sicking>
TabAtkins: and add a .add(FontFace) function on the loader
01:31
<sicking>
TabAtkins: including removals?
01:31
<TabAtkins>
Why not?
01:31
<sicking>
more code in implementations
01:31
<TabAtkins>
(Note that you can't remove CSS-connected ones, only manually-added ones.)
01:32
<TabAtkins>
Why not just say that .delete() and .clear() don't do anything?
01:33
<TabAtkins>
I gotta head home - we can pick this up tomorrow.
01:33
<sicking>
TabAtkins: how would we implement .delete() not doing anything?
01:33
<sicking>
since we'll likely reuse the actual JS Set implementation
01:33
<TabAtkins>
Exactly that way.
01:34
<TabAtkins>
You can override the methods.
01:34
<sicking>
i'm not entirely sure how we would implement subclassing Set, so i'm not sure
01:35
<sicking>
but having a .delete() function that didn't delete seems pretty poor
01:38
<TabAtkins>
I mean, it would probably throw instead.
01:38
<TabAtkins>
(Subclassing Set/Map is pretty piss-poor right now, I think.)
01:39
<sicking>
agreed. Array too
01:39
<TabAtkins>
(I think the only way to reliably do it is to put Set/Map on your proto chain, for detection purposes, but then implement reimplement all the methods yourself and forward to a contained Set/Map holding the real data.)
01:39
<sicking>
i'm kind'a worried that subclassing in JS is entirely broken
01:39
<sicking>
apparently one of the design patterns is to allow base classes to instantiate subclasses
01:39
<TabAtkins>
Subclassing works fine in user-land. :/
01:40
<sicking>
yeah, i think in user-land they use different rules
01:40
<sicking>
than what tc39 is trying to implement
01:40
<sicking>
at least that's my perception
01:46
<TabAtkins>
heycam: All I really want WebIDL to do is let me define a handful of core methods for my thing, have it act like a Map/Set, and then I never have to worry about it again.
01:47
<TabAtkins>
In particular, "not worry about it" means that if new Map/Set methods get added, it can be handled directly in WebIDL, not in every single spec that uses a Map/Set-like interface.
01:47
<sicking>
TabAtkins: I don't think we should make WebIDL go beyond what ES6 provides
01:47
<TabAtkins>
Also, for friendliness, basic typechecking should work (instanceof), and userland methods added to Map/Set.prototype should work.
01:48
<TabAtkins>
sicking: It's possible that this should be better handled in ES6. I proposed this a year or so ago, didn't get anywhere with it.
01:48
<heycam>
TabAtkins, those latter points paint us into this awkward corner of subclassing Map where it's not really designed to be subclassed
01:48
<sicking>
TabAtkins: i hear you :(
01:48
<TabAtkins>
(Specifically, I suggested defining a MapCore or whatever class that had just get/set/has/delete, and similar for Set.)
01:49
<TabAtkins>
And Map is defined to store its data in an internal MapCore, and other methods are defined on top of that.
01:49
<TabAtkins>
Maybe MapCore#clear too, just to let that one be efficient. Oh, and [iterator], obviously.
01:50
<TabAtkins>
So 5 or 6 core methods, and everything else forever defined on top of just those.
01:51
<TabAtkins>
Then WebIDL could specify that when you subclass you can swap out the core for something else that implements the same methods.
01:51
<TabAtkins>
And we can expose that to userland via a [core] symbol or something.
01:51
<heycam>
that sounds more much reasonable than the current [MapClass] setup
01:52
<heycam>
plug a map behaviour into a Map object
01:52
<TabAtkins>
Tell that to AWB.
01:55
<heycam>
the alternative is to do something like we want to do with Arrays, where at defined times the browser can update/replace an IDL attribute's Array object, and uses Object.watch on it
01:55
<heycam>
you'd need to forgo exceptions being thrown with bad values inserted into the Map though
01:55
<heycam>
and you'd need a Map.watch mechanism
01:56
<TabAtkins>
A watch mechanism that lets me filter out the bad things before they get used is sufficient.
01:56
<heycam>
TabAtkins, yeah you can always in prose skip over items of bad types
01:57
<TabAtkins>
Since you'd only be able to insert bad things by doing silly monkeypatching, like "Map.prototype.set.call(mapSubclass, badVal)"
01:57
<heycam>
TabAtkins, doesn't need to be integrated with the watching mechanism
01:57
<sicking>
yeah, synchronously calling into a validate-value hook would help hugely with DOM APIs
01:57
<sicking>
for all container types
01:57
<heycam>
sicking, I think that argues for the map core kind of pattern
01:57
<heycam>
I wonder if you could retrofit something like that onto Arrays as well
03:18
SamB
wonders if he is the only one who gets oddly-aligned checkboxes on http://naesten.mooo.com:8080/checkbox-off-kilter.html ...
03:18
<TabAtkins>
SamB: Off kilter for me too, in Chrome stable channel.
03:20
SamB
wonders if it's been like this forever and he only just noticed
03:27
<Goplat>
it should be off in any browser due to the table's cellspacing and cellpadding
04:34
<SamB>
Goplat: does only the one in the table look bad to you?
04:35
<Goplat>
They both look fine on their own, they're just not aligned with each other
04:36
<SamB>
oh, that's really two examples that happen to be in one file
04:36
<SamB>
my problem is that the text seems to be a few pixels below where it ought to be
09:23
<Ms2ger>
foolip is on a roll
09:39
<Ms2ger>
Does anything define the initial networkState?