Re: [WebIDL] T[] migration

2016-01-07 Thread Boris Zbarsky

On 12/18/15 3:53 AM, Simon Pieters wrote:

Note that it requires liveness. Does that work for a frozen array?


No.  You'd have to create a new array object at the point when you want 
to update the set of values in the array.



Maybe this particular API should be a method instead that returns a
sequence?


Will that cause anyone to implement it?  Because if no one is planning 
to ever implement it, it should probably be removed, not twiddled.


-Boris




Re: CfC: Is Web Workers Ready for CR? deadline Dec 14

2015-11-30 Thread Boris Zbarsky

On 11/30/15 8:31 AM, Xiaoqian Wu wrote:

The latest [TEST RESULTS] of Web Workers indicate that Dedicated Workers have 
been widely implemented by the major browser vendors.


Compatibly?  Last I checked, for example, Blink doesn't support 
Dedicated Workers inside workers, only inside Window.  I agree that 
there is some subset of dedicated worker support that is widely 
implemented; I'm just not sure what that subset is.


-Boris



Re: Callback when an event handler has been added to a custom element

2015-11-06 Thread Boris Zbarsky

On 11/6/15 3:44 PM, Olli Pettay wrote:

You need to override addEventListener on EventTarget, and also relevant
onfoo EventHandler setters on Window and Document and *Element prototypes


Are we trying to just do this best-effort, or reliably?  Because this:

 var ifr = document.createElement("iframe");
 document.body.appendChild(ifr);
 ifr.contentWindow.EventTarget.prototype.addEventListener.call(myNode, 
whatever);


is obviously hard to handle without serious effort...

-Boris



Re: The key custom elements question: custom constructors?

2015-07-17 Thread Boris Zbarsky

On 7/17/15 12:05 PM, Anne van Kesteren wrote:

True, but either way this doesn't seem like a problem. You can create
a DocumentFragment, insert a new img, and then let it be GC'd,
today.


Sure.  In practice it won't get GC'd until the load completes, which is 
sucky, but that's life.


-Boris




Re: The key custom elements question: custom constructors?

2015-07-17 Thread Boris Zbarsky

On 7/17/15 10:38 AM, Anne van Kesteren wrote:

If I look at update the image data step 6 it seems it might be
fetched at a later point?


Yes, but in practice the fetch will go ahead, no?  There's nothing to 
prevent it from happening, so it's going to happen once you reach a 
stable state...


-Boris



Re: alternate view on constructors for custom elements

2015-07-17 Thread Boris Zbarsky

On 7/17/15 2:03 PM, Travis Leithead wrote:

Something magical happens here. The use of super() is supposed to call
the constructor of the HTMLElement class—but that’s not a normal JS
class. It doesn’t have a defined constructor() method


Sure, but neither does Array.  What super() actually does is get the 
prototype of the current constructor and call it.  So in your case:


class CustomElement extends HTMLElement {
   constructor() {
  super();
   }
}

it would call the HTMLElement constructor.

Now there's a slight problem here, which is that HTMLElement is not 
defined to have a constructor in the spec right now.  We need to fix 
that, clearly, for this subclassing of elements with constructors stuff 
to make sense.



Also, as
has been pointed out, running the CustomElement constructor code
_/before/_ instantiating the actual element (at parse-time for example)


I'm not sure what before means here.  In the hypothetical world in 
which we call the CustomElement constructor from the parser, the parser 
would do that, and get back an object.  That would be the actual element.



·Javascript classes are mutable—what if CustomElement’s proto chain is
mutated later?


Then you get something that may not be an HTMLElement when you construct 
via it.  Obviously consumers who care (like the parser, perhaps; though 
it may only care about getting Element) would need to check and handle 
that problem.



1.Native [internal] element is created with appropriate tag name,
attributes, etc.

2.JS constructor is called and provided the instance (as ‘this’)


The only problem with that is what Anne pointed out: there are some 
proposed ES spec additions that would require that the initial JS object 
allocation take the subclassing bits into account to determine which 
immutable state it's preallocated with.  Note that I'm not convinced 
that means we need to call JS from the parser; just that's the problem 
Anne is trying to solve.


Need to chew a bit on your XFooStartup proposal before I can comment on 
it intelligently.


-Boris



Re: [WebIDL] T[] migration

2015-07-16 Thread Boris Zbarsky

On 7/16/15 12:02 PM, cha...@yandex-team.ru wrote:

But would just abandoning T[] break anything elsewhere?


It's hard to break something that never worked.  No browser ever 
implemented anything for T[] to my knowledge.


-Boris



Re: [WebIDL] T[] migration

2015-07-16 Thread Boris Zbarsky

On 7/16/15 11:45 AM, Travis Leithead wrote:

Now that WebIDL has added FrozenArray and dropped T[], it’s time to
switch over! On the other hand, there are a number of specs that have
already gone to Rec that used the old syntax.


Note that since the old syntax was never supported by any UA in any 
meaningful way I'm aware of, those are basically problems in those specs 
that should technically have prevented them from going to REC (due to 
lack of two interoperable implementations).


Looking at the uses of IDL arrays in the relevant specs (links would 
have helped!):



Recommendations:
·HTML5


Assuming we're talking about 
http://www.w3.org/TR/2014/REC-html5-20141028/single-page.html, I don't 
see any uses of IDL arrays in this specification.  Am I missing something?



·Web Messaging


I'm not sure which specification this is referring to...


Other references:

·CSS OM


Presumably this is Document.styleSheetSets?  In practice, I believe no 
one except Gecko implements this and I therefore don't expect it to make 
it to REC... Updating this draft to use FrozenArray would be possible, 
of course.



·Web Sockets


I assume we're talking about 
http://www.w3.org/TR/2012/CR-websockets-20120920/.  This is just buggy 
and needs to be fixed as should 
https://html.spec.whatwg.org/multipage/comms.html#the-websocket-interface; 
it's using an IDL array as an argument, which is pretty much never 
what's desired even back in the world where IDL arrays existed. 
Certainly it's not desired here.  What Gecko ships is a sequence 
argument instead.  I just checked, and so does Blink.  So does WebKit. 
What do Trident and Edge do?


Note that this is tracked by 
https://www.w3.org/Bugs/Public/show_bug.cgi?id=28102 at least.



·WebRTC


Are we talking about http://www.w3.org/TR/2015/WD-webrtc-20150210/?  I 
don't see usage of IDL arrays here.



Legacy/Deprecated references:

·TypedArrays (replaced by ES2015)


This has no bearing on reality; we should just mark it so somehow and 
move on.  IDL arrays are hardly the only problem in this document...



·Web Intents


This could use some mix of FrozenArray and sequence.  But does anyone 
care about this document?


-Boris



Re: Async Image - ImageData conversion

2015-06-26 Thread Boris Zbarsky

On 6/26/15 4:07 AM, Ashley Gullen wrote:

I don't think we should extend HTMLImageElement because it is not
available in workers. Adding the conversion methods to ImageBitmap
allows workers to perform conversions using Blob (compressed image data)
in the place of HTMLImageElement.


Maybe I wasn't clear.  I was suggesting that we have the methods on both 
HTMLImageElement and ImageBitmap (and possibly on any other things we 
feel should have the methods directly).



I like the suggestion that ImageBitmap be the hub of image conversion,


I agree that it sounds appealing, but it means ImageBitmap now has to 
serve two masters: it has to be something that you can paint from 
quickly (premultiplied, probably lives on the GPU) _and_ it needs to be 
something you can transferToImageData efficiently (better to not live on 
the GPU for this).


Maybe that's OK; it's just a bit of a warning flag from my point of view 
when a single object is meant to do multiple quite different things; it 
makes it harder to have it be good at all of them...


-Boris



Re: Async Image - ImageData conversion

2015-06-25 Thread Boris Zbarsky

On 6/24/15 1:28 PM, Ashley Gullen wrote:

I'm new to specs and WebIDL, my intent was to say those are new methods
on ImageBitmap. Is partial interface ImageBitmap the correct way to
say that?


Yes, it is.


The wording of undue latency in the ImageBitmap spec does not appear
to rule out ImageBitmap storing its encoded image data, and lazily
decoding it.


Decoding can easily take hundreds of milliseconds.  It definitely 
constitutes undue latency from our point of view.



- require ImageBitmap to decompress its contents, and make it available
through a read-only Uint8ClampedArray like ImageData has.


This has the premultiplied vs non-premultiplied problem Justin points out.


- provide a way to neuter the ImageBitmap when converting it to
ImageData, transferring its contents and avoiding any copy, which is
useful if the ImageBitmap is a temporary object only being created for
the purposes of getting the ImageData. I guess this would be similar to
transferrable objects with workers.


This would be a viable option.

Another option is to add toBlob/toImageData directly to HTMLImageElement 
and the other things we want it on, in addition to having them on 
ImageBitmap.  Then you wouldn't need to go through an ImageBitmap at all.



Note for devices with discrete GPUs, it's possible that ImageBitmap
stores the decompressed image data in a GPU texture but does not have it
in system RAM.


Indeed.  This is another situation where going directly from an 
HTMLImageElement to an ImageData or Blob would make some sense, because 
it would allow the UA to avoid the GPU upload and readback, right?


The drawback of adding toBlob/toImageData to the various things 
ImageData can be constructed from is that it's a bit more spec 
complexity, but I don't see that as a showstopper, necessarily.


-Boris



Re: Async Image - ImageData conversion

2015-06-24 Thread Boris Zbarsky

On 6/19/15 5:43 AM, Ashley Gullen wrote:

I've not done this before, so I've no idea if this is the right/useful
approach, but I drafted a spec for it here:

https://www.scirra.com/labs/specs/imagedata-blob-extensions.html

Let me know if you have any feedback on this.


Ashley,

I assume the relevant link is now 
https://www.scirra.com/labs/specs/imagebitmap-conversion-extensions.html, 
right?


I'm trying to understand where the methods are being added.  The IDL 
says partial interface ImageBitmapConversion but there is no current 
ImageBitmapConversion interface I'm aware of.  Is this supposed to be 
partial interface ImageBitmap?


-Boris



Re: Writing spec algorithms in ES6?

2015-06-11 Thread Boris Zbarsky

On 6/11/15 4:32 PM, Dimitri Glazkov wrote:

I noticed that the CSS Color Module Level 4 actually does this, and it
seems pretty nice:
http://dev.w3.org/csswg/css-color/#dom-rgbcolor-rgbcolorcolor


I should note that the ES code there produces semantics that don't match 
the IDL in this spec (or is complete nonsense, depending on how 
literally you choose to read it).


So there are basically at least two problems here:

1)  You have to clearly delineate when you're working with JS values and 
when you're working with IDL values, to the extent that these are not 
the same thing.


2)  You have to clearly delineate which bits of JS run in the page 
global and which bits run in some other clean global and which bits run 
in the page global but have access to some clean intrinsics somehow.


I would actually prefer some sort of pseudocode that is _not_ 
JS-looking, just so people don't accidentally screw this up.


-Boris



Re: Custom Elements: insert/remove callbacks

2015-05-09 Thread Boris Zbarsky

On 5/9/15 12:40 PM, Anne van Kesteren wrote:

So that seems clearly wrong (in the specification)... Are descendants
notified in tree order?


In Gecko, yes.

Note that running script during these insert/remove notifications is not 
OK, so anything that needs to run script has to do it later (for 
various definitions of later).


-Boris



Re: Custom Elements: insert/remove callbacks

2015-05-08 Thread Boris Zbarsky

On 5/8/15 1:42 AM, Elliott Sprehn wrote:

That actually seems pretty similar to what we have, ours is in the form of:

Node#insertedInto(Node insertionPoint)
Node#removedFrom(Node insertionPoint)


To be clear, ours is also in the form of two methods 
(BindToTree/UnbindFromTree) that take various arguments.  I just 
described the conceptual information that one can typically get based on 
what all those arguments are.  It also happens that in Gecko the 
Bind/Unbind functions aren't pure notification; they are also 
responsible for doing things like setting the parent pointer as needed.


But yes, the upshot is that the two cases are pretty similar.  Gecko 
doesn't have on hand the exact node that the insertion/removal happened 
at, but adding that would not be a big deal.


-Boris



Re: Custom Elements: insert/remove callbacks

2015-05-07 Thread Boris Zbarsky

On 5/7/15 3:43 AM, Anne van Kesteren wrote:

On Wed, May 6, 2015 at 11:01 PM, Justin Fagnani
justinfagn...@google.com wrote:

How are you supposed to tell if one of your ancestors was removed?


Is that a hook builtin elements have today?


In Gecko, yes.  The set of hooks Gecko builtin elements have today is, 
effectively:


1)  This element used to not have a parent and now does.
2)  This element has an ancestor that used to not have a parent and now
does.
3)  This element used to have a a parent and now does not.
4)  This element has an ancestor that used to have a parent and
now does not.

-Boris



Re: Why is querySelector much slower?

2015-04-29 Thread Boris Zbarsky

On 4/29/15 12:23 AM, Glen Huang wrote:

because of the proxy machinery involved on the JS engine side


Do you mean the cost introduced by passing a C++ object into ecmascript world?


No, it's the cost introduced by needing custom property behavior for 
integer-named properties on lists (and in particular the need to have 
them appear and disappear, not be redefinable, and so forth).  The 
upshot in the SpiderMonkey implementation is that the list object is a 
proxy in the ES6 sense, which makes the [0] access take a slower path 
through the JS engine than I'd like.


-Boris



Re: Why is querySelector much slower?

2015-04-28 Thread Boris Zbarsky

On 4/28/15 2:44 AM, Glen Huang wrote:

But If I do getElementsByClass()[0], and LiveNodeList is immediately
garbage collectable


Then it will only be collected the next time GC happens.  Which might 
not be for a while.


-Boris



Re: Why is querySelector much slower?

2015-04-28 Thread Boris Zbarsky

On 4/28/15 1:58 AM, Glen Huang wrote:

Just a quick follow up question to quench my curiosity: if I do list[1] and no one has 
ever asked the list for any element, Gecko will find the first two matching elements, and store 
them in the list, if I then immediately do list[0], the first element is returned 
without walking the DOM (assuming there are at least two matching elements)?


Yes, exactly.


querySelector(foo) and getElementsByTagName(foo)[0] can return different 
nodes


Still a bit confused regarding this. If the premise is the selector only 
contains characters allowed in a tag name


Then in that case I _think_ those are now equivalent, though I'd have to 
check it carefully.  They didn't use to be back when 
getElementsByTagName was defined as matching on qualified name, not 
localname...


-Boris



Re: Why is querySelector much slower?

2015-04-28 Thread Boris Zbarsky

On 4/28/15 2:13 AM, Glen Huang wrote:

On second thought, if the list returned by getElementsByClass() is lazy
populated as Boris says, it shouldn't be a problem. The list is only
updated when you access that list again.


Mutations have to check whether the list is marked dirty already or not.

This is not too bad if you only have a few lists around, but if you have 
several thousand it can start to hurt.


-Boris



Re: Why is querySelector much slower?

2015-04-28 Thread Boris Zbarsky

On 4/28/15 2:59 AM, Glen Huang wrote:

Looking at the microbenchmark again, for Gecko, getElementById is around 300x 
faster than querySelector('#id'), and even getElementsByClassName is faster 
than it.


This is why one should not write microbenchmarks.  ;)  Or at least if 
one does, examine the results very carefully.


The numbers you see for the getElementById benchmark there are on the 
order of 2e9 operations per second, yes?  And modern desktop/laptop CPUs 
are clocked somewhere in the 2-4 GHz range.  So what you're seeing is 
that the benchmark claims the operation is performed in 1-2 clock 
cycles.  This should seem unlikely if you think the operation involves a 
hashtable lookup!


What's happening there is that Gecko happens to know at JIT compile time 
in this microbenchmark:


1)  The bareword lookup is going to end up at the global, because there 
is nothing on the scope chain that would shadow the document name.
2)  The global has an own property named document whose getter is 
side-effect-free.
3)  The return value of the document property has only been observed 
to be a Document.
4)  Looking up getElementById on the return value of the document 
property has consistently found it on Document.prototype.

5)  Document.prototype.getElementById is known to be side-effect-free.
6)  The return value of getElementById is not used (assigned to a 
function-local variable that is then not used).


The upshot of all that is that with a few guards both the 
getElementById call get and the  document get can be dead-code 
eliminated here.  And even if you stored the value somewhere persistent 
they could both still be loop-hoisted in this case.  So what this 
getElementById benchmark measures is how fast a loop counter can be 
decremented from some starting value to 0.  It happens that this can be 
done in about 1-2 clock cycles per loop iteration.


OK, so what about querySelector(#id) vs getElementsByClassName?

In the former case, loop-hoisting and dead code elimination are 
disallowed because querySelector can throw.  That means that you can't 
eliminate it, and you can't move it past other things that might have 
observable side effects (like the counter increment).  Arguably this is 
a misfeature in the design of querySelector.


In the latter case, loop-hoisting or dead code elimination can't happen 
because Gecko doesn't know enough about what [0] will do so assumes the 
worst: that it can have side-effects that can affect what the document 
getter returns as well as what the getElementsByClassName() call returns.


So there are no shortcuts here; you have to actually do the calls. What 
do those calls do?


querySelector does a hashtable lookup for the selector to find a parsed 
selector.  Then it sets up some state that's needed for selector 
matching.  Then it detects that the selector's right-hand-most bit has a 
simple ID selector and does a fast path that involves looking up that id 
in the hashtable and then comparing the selector to the elements that 
are returned until one of them matches.


getElementsByClassName has to do a hashtable lookup on the class name, 
then return the result.  Then it has to do the [0] (which is actually 
surprisingly expensive, by the way, because of the proxy machinery 
involved on the JS engine side).


So we _could_ make querySelector faster here by adding another special 
case for selectors that are _just_ an id as opposed to the existing 
optimization (which works for #foo  #bar and similar as well).  And 
of course the new special case would only work the way you want for 
document.querySelector, not element.querySelector; the latter needs to 
check for your result being a descendant of the element anyway.  It's a 
tradeoff between complexity of implementation (which has its own 
maintenance _and_ performance costs) and real-life use cases.


Lastly, I'd like to put numbers to this.  On this particular testcase, 
the querySelector(#list) call takes about 100ns on my hardware: about 
300 CPU cycles.  We could add that other set of special-casing and get 
it down to 70ns (I just checked by implementing it, so this is not a 
random guess).  At that point you've got two hashtable lookups (which we 
could try to make faster, perhaps), the logic to detect that the 
optimization can be done at all (which is not that trivial; our selector 
representation requires a bunch of checks to ensure that it's just an id 
selector), and whatever work is involved in the binding layer.  In this 
case, those all seem to have about the same cost; about 17-18ns (50 CPU 
cycles) each.


So is your use case one where the difference between querySelector 
costing 100ns and it costing 70ns actually makes a difference?



It doesn't look like it benefits much from an eagerly populated hash table?


It benefits a good bit for non-toy documents where avoiding walking the 
entire DOM is the important part of the optimization.  Again, 
microbenchmarks mostly serve to highlight the 

Re: Why is querySelector much slower?

2015-04-27 Thread Boris Zbarsky

On 4/27/15 11:27 PM, Glen Huang wrote:

When you say var node = list[0]; walks the DOM until the first item is found, 
do you mean it only happens under the condition that some previous code has changed the 
DOM structure?


Or that no one has ever asked the list for its [0] element before, yes.


If not, the returned list object will be marked as up-to-day, and accessing the 
first element is very cheap?


In Gecko, yes.


I ask because in the first paragraph you said the returned list and returned 
first element is probably precomputed.


In the case of the microbenchmark where you just ask for it repeatedly 
without changing the DOM, yes.



After UA has parsed html, it caches a hash table of elements with class names 
(also all element with ids, all elements with tag names, etc in different hash 
tables), keyed under the class names.


At least in Gecko, that's not how it works.

There _is_ a hashtable mapping ids to element lists used for 
getElementById that is populated eagerly.


There is also hashtable mapping the pair (class string, root) to an 
element list that's used by getElementsByClassName and is populated 
lazily.  Likewise, a hashtable mapping the pair (tagname, root) to an 
element list that's used by getElementsByClassName; this one is also 
populated lazily.


 When getElementsByClassName() is called, and the DOM hasn't been 
modified, it simply creates a list of elements with that class name from 
the hash table.


No, it just gets the list pointer from the hashtable (if any) and 
returns it.  That is, getElementsByClasName(foo) === 
getElementsByClassName(foo) tests true.  If there is no list pointer 
in the hashtable, an empty list is created, stored in the hashtable, and 
returned.



When the first element is accessed from that list, and the DOM still isn't 
modified, the element is returned directly.


If the list has computed it before.  If not, it walks the DOM until it 
finds its first element, then adds that one element to the list and 
returns it.



The hash table is kept in sync with the DOM when it's modified.


The id hashtable is.  The class/tagname hashtables aren't kept in sync 
per se, since they're lazily populated anyway, but the lists stored in 
them may need to be marked dirty.



And if the DOM is changed after the list is returned but before it's accessed


Or before the list is returned.  The order really doesn't matter here; 
what matters is whether the DOM is changed after the previous access, if 
any.



Why can't querySelector benefit from these hash tables?


It could, somewhat.  querySelector with an id selector does in fact 
benefit from the id hashtable.  For the specific case of querySelector 
with a class selector, we _could_ internally try to optimize a bit, 
especially for the class case (the tag name case is a bit harder 
because, for example, querySelector(foo) and 
getElementsByTagName(foo)[0] can return different nodes depending on 
the value of the string foo and whether it contains any ':' characters 
and whatnot).



I currently feel the urge to optimize it myself by overriding it with a custom function which will parse the 
passed selector, and if it's a simple selector like div, .class, #id, 
call the corresponding getElement*() function instead.


Then you'll end up with incorrect behavior in some cases, which you may 
of course not care about.



Why can't UAs perform this for us?


To some extent they could.  In practice this hasn't come up as a 
bottleneck in anything we've profiled so far, so people have avoided 
adding what seems like unnecessary complexity, but if there's a 
real-life example (not a microbenchmark) where this is being a problem 
that would certainly help a lot with getting this sort of thing on the 
radar.



If my mental model is correct


It's not quite.


The only price it  pays is parsing the selector.


Not even that, possibly; at least Gecko has a cache of parsed selectors.


Is it because authors don't use querySelector often enough that UAs aren't 
interested in optimizing it?


Or more precisely don't use it in ways that make it the performance 
bottleneck.


-Boris



Re: Exposing structured clone as an API?

2015-04-23 Thread Boris Zbarsky

On 4/23/15 9:31 PM, Kyle Huey wrote:

Today it's not demanding, it's not even possible.  e.g. how do you
duplicate a FileList object?


Ah, there we go.  I figured there was something that would fail the 
ways of cloning them all test in the platform today... ;)


We should make it possible to manually clone FileList of course, but the 
larger point is that this is likely to continue being a problem.


-Boris




Re: Exposing structured clone as an API?

2015-04-23 Thread Boris Zbarsky

On 4/23/15 6:34 PM, Elliott Sprehn wrote:

Have you benchmarked this? I think you're better off just writing your
own clone library.


That requires having a list of all objects browsers consider clonable 
and having ways of cloning them all, right?  Maintaining such a library 
is likely to be a somewhat demanding undertaking as new clonable objects 
are added...


-Boris



Re: Privileged context features and JavaScript

2015-04-17 Thread Boris Zbarsky

On 4/17/15 2:44 AM, Mike West wrote:

Consider Geolocation, for instance: users can disable the API entirely
in Chrome (and, I assume, other browsers). Should we remove the API in
these cases as well?


There's no user-facing UI to disable geolocation in Firefox, but there 
is a preference that can be changed in about:config and there are some 
instructions for how to change that preference in about:rights on some 
Firefox platforms (e.g. Firefox on Android).


If that preference is toggled, we in fact remove the API entirely, so 
that 'geolocation' in navigator tests false.


-Boris



Re: Privileged context features and JavaScript

2015-04-17 Thread Boris Zbarsky

On 4/17/15 2:52 AM, Boris Zbarsky wrote:

If that preference is toggled, we in fact remove the API entirely, so
that 'geolocation' in navigator tests false.


Oh, I meant to mention: this is more web-compatible than having the API 
entrypoints throw, because it can be object-detected.  Of course we 
could have made the API entrypoints just always reject the request 
instead, I guess; removing the API altogether was somewhat simpler to do.


-Boris




Re: Privileged context features and JavaScript

2015-04-17 Thread Boris Zbarsky

On 4/17/15 3:38 AM, Elliott Sprehn wrote:

It's preferable not to do that for us because you can then create a
static heap snapshot at compile time and memcpy to start JS contexts faster.


For this specific case, where there are only two possibilities 
(privileged or not) it seems like you can just have two different 
snapshots and pick the right one.  I agree this uses more memory; there 
are all sorts of tradeoffs here.


But yes, this is an argument against having any sort of dynamic 
behavior.  In the case of Gecko, we have to have _something_ somewhat 
dynamic anyway, since we expose APIs to extensions that we don't expose 
to web pages... which I'm sure you do too.


-Boris



Re: Privileged context features and JavaScript

2015-04-17 Thread Boris Zbarsky

On 4/17/15 2:44 AM, Mike West wrote:

Either way, expressing the constraint via IDL seems totally reasonable.


OK, so let's say we do the API is still present but fails somehow 
thing.  How would one express that constraint via IDL?  What would the 
normative language be?  It seems like the best you can do in this 
situation is an IDL annotation that has no actual behavior implications 
of its own but serves as a warning to the spec reader to carefully read 
the prose for what the behavior implications are, right?


I say this because I'm seeing people want to apply this to a variety of 
different APIs which should do a variety of different things in the 
disabled state, as far as I can tell.


Am I missing something and there's something more that such an 
annotation could do?


-Boris




Re: Privileged context features and JavaScript

2015-04-17 Thread Boris Zbarsky

On 4/17/15 7:58 AM, Ashley Gullen wrote:

I think the existence of the API functions should indicate the browser
has the capability, and then the API returns an error if it's not
allowed to be used in the current context. I think this would improve
the quality of messages seen by users, since for example removing the
Geolocation API entirely could result in a web page message like sorry,
your browser does not support Geolocation, try updating your browser -
which is incorrect, it really should say something like geolocation
permission denied.


If the page has a codepath for the denied condition, yes.

This is somewhat more likely for geolocation (which involves explicit 
user permission, and the site author may at least consider not being 
granted) than for something like webcrypto (where the site author is 
likely to just not check for rejection at all).


But even for geolocation, you'd end up with a we page message like 
sorry, you didn't grant permission to use Geolocation, reload the page 
and grant it which is _also_ incorrect: the correct remediation step is 
to use HTTPS to load the page.  And I bet if the page didn't already 
redirect to an SSL version of itself this step is not available to the 
user anyway...


I would love it if there were a way here to message to the user that the 
page is the thing that's broken (trying to use a privileged feature in a 
non-privileged context), but clearly doing that via messaging the _page_ 
controls is not viable.  The browser _could_ put up an infobar, I 
suppose, in the case that the API is left in place but triggers 
automatic failure if called...


-Boris



Re: Privileged context features and JavaScript

2015-04-17 Thread Boris Zbarsky

On 4/17/15 11:13 AM, Anne van Kesteren wrote:

A bunch of the new non-legacy APIs (that is geolocation doesn't count)
have some kind of promise thing you need to get past before things
start working. For those APIs we could have something with normative
language. I don't see how we could make something work for all
possible APIs (unless we do the hiding thing).


OK, so the annotation could be defined as something like adding the 
following to the operation (and maybe attribute getter?) steps in WebIDL:


   If the API returns a Promise type, return a Promise rejected with
   a TypeError (??).  Otherwise, the operation steps MUST fail in some
   way.

Or some such.

-Boris



Re: [Imports] Considering imperative HTML imports?

2015-04-16 Thread Boris Zbarsky

On 4/16/15 12:37 AM, Travis Leithead wrote:

Was an imperative form of HTML imports already considered? E.g., the
following springs to mind:

   PromiseDocument importDocument(DOMString url);


How is this different from a promise-ified version of XHR, exactly? 
(Not that there's anything wrong with that; just trying to understand 
the proposal.)


-Boris



Re: WebIDL Plans

2015-04-14 Thread Boris Zbarsky

On 4/14/15 8:22 AM, Yves Lafon wrote:

I remember ArrayClass removed from NodeList for the reason of lack of 
implementations, and even plans for implementation


It was removed because as things stand it's not web-compatible.  Once 
@@isConcatSpreadable exists in implementations, we could and should 
reinstate ArrayClass on NodeList, I expect, while making it 
concat-spreadable at the same time.  Certainly I plan to do so in Gecko.


Thank you for the summary of stuff we're considering unstable for now. 
Comments inline.



Currently maplike/setlike/ RegExp [Unscopeable] [PrimaryGlobal] [ImplicitThis], 
most probably iterable.


OK.  So I'm fine with maplike/setlike being considered unstable at the 
moment, because they are.


I have no strong opinion on RegExp, since I suspect in practice no one 
uses it anywhere so far.


[Unscopeable] is not implemented in UAs yet, but doing that blocks 
implementing some DOM APIs, fwiw.


[PrimaryGlobal] is needed for [Exposed] stuff to make any sense.  I see 
no reason not to keep it; it's supported in Gecko fwiw.


[ImplicitThis] is, I agree, unstable in terms of IDL syntax.  The 
functionality is obviously needed for basic web compat; I think we 
should just make it a priority to get this part sorted out and stabilized.



But of course this is also subject to the number of bugs attached to them, 
issues with test etc...


Sure.


So many things will still be considered “at risk”.


That's fine.


I didn’t see any trace of [ImplicitThis] either, so that will make it hard to 
test (the Window interface given in the example is no longer using it).


It's trivial to test its effects.  If this script puts up an alert:

  script
alert(Hello);
  /script

then something like [ImplicitThis] is being done somewhere, whether the 
specs call for it or not.  What that something is should probably be 
specced, of course.  ;)



Ah indeed no, and now I wonder why I added it in my list… (so as no specs seems 
to use them, I don’t think there are implementations around).


I'm not aware of any implementations, correct.

-Boris





Re: [websockets] Test results available

2015-04-02 Thread Boris Zbarsky

On 4/2/15 8:15 AM, Simon Pieters wrote:

http://www.w3c-test.org/websockets/keeping-connection-open/001.html --
the test is wrong.  Passing undefined means the argument is not
present per Web IDL, so this should not throw.


I assume you mean some other test since that test doesn't use undefined.


Er, yes.  I meant http://www.w3c-test.org/websockets/Close-undefined.htm 
I think, which has since been fixed looks like?.



I agree. The spec says to return from the constructor and establish the
connection in parallel, so it is not guaranteed which cookies to
include. Fix: https://github.com/w3c/web-platform-tests/pull/1701


Thanks!

-Boris



Re: [W3C TCP and UDP Socket API]: Status and home for this specification

2015-04-01 Thread Boris Zbarsky

On 4/1/15 12:50 PM, Domenic Denicola wrote:

Do you think it's acceptable for browser to experiment with e.g. auto-granting 
permission if the requested remoteAddress is equal to the IP address of the 
origin executing the API?


This particular example sets of alarm bells for me because of virtual 
hosting.  As in, this seems like precisely the sort of thing that one 
browser might experiment with, another consider an XSS security bug, and 
then we have content that depends on a particular browser, no?


-Boris



Re: [websockets] Test results available

2015-03-26 Thread Boris Zbarsky

On 3/26/15 10:51 AM, Arthur Barstow wrote:

If anyone is willing to help with the failure analysis, that would be
very much appreciated.


Taking a brief look at some of the failures in Firefox, in addition to 
the ones Olli already posted about:


http://www.w3c-test.org/websockets/keeping-connection-open/001.html -- 
the test is wrong.  Passing undefined means the argument is not present 
per Web IDL, so this should not throw.


http://www.w3c-test.org/websockets/cookies/001.html seems racy to me: it 
kicks off an async test and then immediately removes the cookie, so it's 
not obvious to me why it expects that cookie to be present in the 
websocket connection; the cookie may well be removed before the 
connection is set up.


http://www.w3c-test.org/websockets/interfaces/WebSocket/readyState/003.html 
looks wrong to me: the value it should get is in fact undefined, since 
the property got deleted from the prototype.


-Boris



Re: [websockets] Test results available

2015-03-26 Thread Boris Zbarsky

On 3/26/15 10:51 AM, Arthur Barstow wrote:

* All results http://w3c.github.io/test-results/websockets/all.html

* 2 passes http://w3c.github.io/test-results/websockets/less-than-2.html

Overall these results are pretty good: 97% of the 495 tests have two or
more passes.


Arthur,

It looks like the tests that are failed with an Error as opposed to a 
Fail are not being counted in the 2 passes list?  For example, 
http://www.w3c-test.org/websockets/Create-Secure-valid-url-array-protocols.htm 
is not in that list even though everyone fails it.


Is that an accident, or a purposeful decision?

-Boris



Re: [websockets] Test results available

2015-03-26 Thread Boris Zbarsky

On 3/26/15 1:02 PM, Boris Zbarsky wrote:

It looks like the tests that are failed with an Error as opposed to a
Fail are not being counted in the 2 passes list?


And the for 
http://www.w3c-test.org/websockets/keeping-connection-open/001.html 
which is all-Timeout.


-Boris



Re: Custom elements: synchronous constructors and cloning

2015-02-23 Thread Boris Zbarsky

On 2/23/15 4:27 AM, Anne van Kesteren wrote:


1) If we run the constructor synchronously, even during cloning. If
the constructor did something unexpected, is that actually
problematic? It is not immediately clear to me what invariants we
might want to preserve. Possibly it's just that the code would get
more complicated when not self-hosted? Similar to mutation events? If
someone has a list of reasons in mind that would be appreciated. This
type of question keeps popping up.


So these are the things that come to mind offhand for me, which may or 
may not be problems:


1)  If cloning can have sync side-effects, then we need to either accept 
that cloneNode can go into an infinite loop or ... I'm not sure what. 
And yes, non-self-hosted implementation gets more complicated.


2)  There are various non-obvious cloning operations UAs can perform 
right now because cloning is side-effect free.  For example, when you 
print Gecko clones the document and then does the printing stuff async 
on the cloned document instead of blocking the UI thread while the 
(fairly long-running) print operation completes.  If cloning became 
observable, we'd need to figure out what to do here internally (e.g. 
introduce a new sort of cloning that doesn't run the constructors?).


3)  As you note, we'd need to figure out what to do with current clone 
consumers.  This includes not just range stuff but things built on top 
of said range stuff or on top of cloning directly.  Things like editing 
functionality, for example.  Not that we have a real spec for that 
anyway


-Boris



Re: Thread-Safe DOM // was Re: do not deprecate synchronous XMLHttpRequest

2015-02-11 Thread Boris Zbarsky

On 2/11/15 3:04 PM, Brendan Eich wrote:

If you want multi-threaded DOM access, then again based on all that I
know about the three open source browser engines in the field, I do not
see any implementor taking the huge bug-risk and opportunity-cost and
(mainly) performance-regression hit of adding barriers and other
synchronization devices all over their DOM code. Only the Servo project,
which is all about safety with maximal hardware parallelism, might get
to the promised land you seek (even that's not clear yet).


A good start is defining terms.  What do we mean by multi-threaded DOM 
access?


If we mean concurrent access to the same DOM objects from both a window 
and a worker, or multiple workers, then I think that's a no-go in Servo 
as well, and not worth trying to design for: it would introduce a lot of 
spec and implementation complexity that I don't think is warranted by 
the use cases I've seen.


If we mean the much more modest have a DOM implementation available in 
workers then that might be viable.  Even _that_ is pretty hard to do in 
Gecko, at least, because there is various global state (caches of 
various sorts) that the DOM uses that would need to either move into TLS 
or become threadsafe in some form or something...  Again, various specs 
(mostly DOM and HTML) would need to be gone over very carefully to make 
sure they're not making assumptions about the availability of such 
global shared state.



We should add lighter-weight workers and immutable data structures


I should note that even some things that could be immutable might 
involved a shared cache in current implementations (e.g. to speed up 
sequential indexed access into a child list implemented as a linked 
list)...  Obviously that sort of thing can be changed, but your bigger 
point that there is a lot of risk to doing that in existing 
implementations remains.


-Boris



Re: Thread-Safe DOM // was Re: do not deprecate synchronous XMLHttpRequest

2015-02-11 Thread Boris Zbarsky

On 2/11/15 9:45 PM, Marc Fawzi wrote:

this backward compatibility stuff is making me think that the web is
built upon the axiom that we will never start over and we must keep
piling up new features and principles on top of the old ones


Pretty much, yep.


this has worked so far, miraculously and not without overhead, but I can
only assume that it's at the cost of growing complexity in the browser
codebase.


To some extent, yes.

Browsers have obviously been doing refactoring and simplification as 
they go, but I think it's pretty clear that a minimal viable browser 
today is a lot more complicated than one 10 years ago.



I'm sure you have to manage a ton of code that has to do with
old features and old ideas...


Sometimes.  Sometimes it can just be expressed easily in terms of the 
newer stuff.  And sometimes we do manage to remove things -- I'm seeing 
it happen right now with plugins, which definitely fall in the bucket of 
a ton of annoying-to-maintain code.



how long can this be sustained? forever?


If we're lucky, yes.


what is the point in time where
the business of retaining backward compatibility becomes a huge nightmare?


About 10-15 years ago, really.  We've just gotten pretty good at facing 
the nightmare.  ;)


-Boris



Re: do not deprecate synchronous XMLHttpRequest

2015-02-10 Thread Boris Zbarsky

On 2/10/15 12:28 PM, Marc Fawzi wrote:

Launch an async xhr and monitor its readyState in a while loop and don't exit 
the loop till it has finished.


Per spec (and in implementations last I checked), the readyState isn't 
allowed to change during the loop.  So all that will happen is you will 
get a slow script dialog or equivalent.


-Boris




Re: oldNode.replaceWith(...collection) edge case

2015-01-21 Thread Boris Zbarsky

On 1/21/15 3:52 AM, Simon Pieters wrote:

This jsperf might be interesting:

http://jsperf.com/appendchild-vs-documentfragment-vs-innerhtml/81


Or misleading.

Again, in real life what matters most here is what else is on the page, 
which the jsperf doesn't capture.  The other thing that really matters 
is how many elements are being inserted, exactly, of course... which the 
jsperf also doesn't capture.


Typically, jsperf is the wrong tool for answering questions like this, 
unless you're 100% sure your microbenchmark captures all the essential 
features of the macro-situation...


-Boris



Re: oldNode.replaceWith(...collection) edge case

2015-01-20 Thread Boris Zbarsky

On 1/20/15 6:45 PM, Glen Huang wrote:

I vaguely remember document fragment is introduced just to reduce
reflows. Looks like this best practice is obsolete now?


You don't have to use a document fragment to reduce reflows, as long as 
you don't query layout information between your DOM notifications.


There are some other things (e.g. maintaining DOM state of various 
sorts) a browser may be able to optimize a bit better with a document 
fragment.  Or not.



So to recap, when you have the need to pass the context node as an
argument along with other nodes, just use before() and after() to insert
these other nodes? And even insert them one by one is fine?


I strongly suggest measuring to get an answer to this question.  The 
performance characteristics will depend on the browser, on the exact set 
of DOM features used on the page, and on the exact stylesheets used on 
the page.


That said, I would expect the difference between inserting a document 
fragment and inserting the nodes one at a time to be fairly small in all 
modern browsers in most situations.  Note all the weasel-wording.  ;)


-Boris



Re: Minimum viable custom elements

2015-01-14 Thread Boris Zbarsky

On 1/14/15 9:45 AM, Anne van Kesteren wrote:

* No subclassing of normal elements for now.


You mean subclassing anything more specific than HTMLElement/SVGElement, 
yes?  Presumably we still want subclassing of HTMLElement and maybe 
SVGElement?



* Parsing of declarative syntax invokes the registered constructor
synchronously.


I would like to understand what this means, exactly.  For example, what 
is the proposed behavior of document.write() in the declarative constructor?


This part of the proposal really worries me in terms of implementation 
complexity, for what it's worth.


-Boris



Re: Custom element design with ES6 classes and Element constructors

2015-01-14 Thread Boris Zbarsky

On 1/14/15 8:28 AM, Anne van Kesteren wrote:

On Wed, Jan 14, 2015 at 2:00 PM, Boris Zbarsky bzbar...@mit.edu wrote:

Wanting things like custom buttons is _very_ common.  What is your proposal
for addressing this use case?


I have no good answer. appearance:button seems to work okayish


I think we're having a miscommunication here.

appearance:button can give you something that looks like a button.  But 
it doesn't _act_ like one.


What I'm asking is what people who want an actual button but with some 
additional APIs on it are supposed to do.  This is the basic idea of 
subclassing built-ins: get something that acts like the built-in as far 
as the browser is concerned but has some additional functionality on it.


-Boris



Re: Custom element design with ES6 classes and Element constructors

2015-01-14 Thread Boris Zbarsky

On 1/14/15 11:52 AM, Dimitri Glazkov wrote:

Would like to point out that we're not talking about a general case
here. The actual proto munging in custom elements spec is minimized to a
pretty small set.


Pretty small set of which?  Possible mutations, elements, something else.


Given that most engines use lazily created wrappers


I don't think we should be designing around this.  I believe that this 
is a carryover from the way the engines were initially implemented in a 
C++-first manner.  As a a particular example, Servo doesn't even have a 
concept of wrappers; it just has a single memory area that is both the 
JS and Rust representation of the object involved.



the actual setting
of the prototype won't even need to happen unless the developer first
accessed the element, thus creating a wrapper.


What that really means is that the performance cliff is randomly 
unpredictable, right?  That may or may not be better than always being slow.



Also, the current design doesn't change the prototype chain arbitrarily:


This is the most important point.  It's possible engines could optimize 
such proto chain insertions better than they do now.  Some feedback from 
engine implementors on how feasible that is would be good to have.



the effect is limited to inserting a sub-chain into the existing chain.


Is it, though?

I don't see that this is always true, though I would be fine with the 
cases in which it's not true falling off performance cliffs: those would 
only happen when proto chains get munged after element registration.


If we ignore those cases, it's possible JS engines could optimize this 
better than they do now.  JS engine implementor feedback would be pretty 
useful on this matter.


-Boris




Re: Custom element design with ES6 classes and Element constructors

2015-01-14 Thread Boris Zbarsky

On 1/14/15 7:51 AM, Anne van Kesteren wrote:

I would rather we gave up on subclassing normal elements


Wanting things like custom buttons is _very_ common.  What is your 
proposal for addressing this use case?


-Boris



Re: Custom element design with ES6 classes and Element constructors

2015-01-13 Thread Boris Zbarsky

On 1/13/15 12:06 PM, Gabor Krizsanits wrote:

I think this part of the spec was largely written before ES6 class stuff
stabilized, fwiw.  Which is not hard, since it's still not stabilized.  ;)


Isn't there a chance to consider our use-case in ES6 spec. then?


I suspect not in time for ES6.  The not stabilized bit here is 
supposed to be rectified on a timeframe of hours-to-days.



(+ internally I'm sure most engines does transformations in some cases
already, like for array optimisations...)


The feedback from the V8/Blink folks was that they are in fact unable to 
do such a transformation for DOM objects.  That's one of the things that 
led to the re-coupling of allocation and initialization in ES6.


A more limited class transformation that doesn't involve changing the 
set of internal slots might be easier to do.  But if you have to change 
internal slots, things get complicated.


-Boris




Re: Defining a constructor for Element and friends

2015-01-13 Thread Boris Zbarsky

On 1/13/15 12:05 PM, Domenic Denicola wrote:

From: Boris Zbarsky [mailto:bzbar...@mit.edu]

   var x = new Element(a, http://www.w3.org/1999/xhtml;)


The idea is that your above example throws, preserving the invariant.


That sounds annoying

Presumably this means that document.createElement(NS) looks up the 
registry constructor and calls it, instead of calling the Element 
constructor and having _that_ delegate to the registry.


But it also means that user-space code that has to create an HTML 
element generically now has to go through document.createElement instead 
of being able to do |new HTMLElement(a)|, right?


I agree that this does allow us to preserve the invariant in question, 
but I question whether it's worth it.



I was assuming non-exotic [[HasInstance]]


Ah, yeah, with Web IDL that's not a good assumption


but I agree it's ambiguous given that. I meant prototype chain. Probably I also 
implicitly meant internal slots.


Those aren't the same thing at all, right?  The prototype chain has 
absolutely nothing to do with internal slots, unless we're assuming some 
sort of vanilla untouched tate of the world.



The one piece of terminology that I think we have so far that I understand is what it 
means for an object to implement an interface.
At least Web IDL has a normative requirement on such a thing being defined 
(e.g. see http://heycam.github.io/webidl/#es-operations step 4 of the 
behavior), presumably in terms of some sort of branding.


Heh, I don't really understand what that means; I indeed noticed that Web IDL 
uses it without defining it.


Right now the concept of what it means for a platform object to 
implement an interface is sort of up to the implementation.  The Web 
IDL spec assumes that for each platform object there is a set of 
interfaces it implements, subject to some constraints described in 
http://heycam.github.io/webidl/#es-platform-objects, but even basic 
restrictions like if A inherits from B and the platform object 
implements A then it must implement B don't seem to be explicitly 
stated We should really fix that.



I too would guess that it's branding-related.


That's certainly how implementations treat it in practice.


Note that in any sensible scheme I can think of, subclass instances (for a 
subclass that calls super() in the constructor) also get the brands of their 
superclass.


Yes, absolutely.


So it makes sense to me to talk about things implementing Element but not any interface 
that has Element as an inherited interface.  That would correspond to is an Element 
but not any specific subclass of Element.  Could use a shorter way of saying it, 
for sure.


Don't think this attempt at pinning down terminology works for user-defined 
subclasses of Element. E.g. as far as I can tell, `new (class X extends Element 
{})()` has only the Element brand but no other brand (since X didn't install 
any brands itself). But I would say that it's an own-instance of X instead of 
an own-instance of Element.


OK.  That makes sense; I'm not trying to redefine the concept of 
own-instance.  I'm just trying to figure out what the right concepts 
are to define.


The concept of implements an interface has to do with branding and 
guaranteed existence of internal slots and whatnot.  The concept of has 
Element as its primary interface also promises something about the 
initial value of __proto__.


The concept of own-instance, if we define it as you did above (was 
created by) would also guarantee certain things about branding and 
internal slots.  It would also make some guarantees about the prototype, 
assuming no one sets __proto__ after that...


Really, this idea of primary interface and your idea of own-instance 
seem fairly similar, right?  Except that primary interface can only 
refer to Web IDL interfaces, not user-defined subclasses... or something.


-Boris



Re: Defining a constructor for Element and friends

2015-01-13 Thread Boris Zbarsky

On 1/13/15 1:18 PM, Ryosuke Niwa wrote:

I agree. It's unusual for a constructor of a super class to automatically 
instantiate an arbitrary subclass based on its arguments. And we usually solve 
that convenience problem by introducing a factory class/function.


While true, I do think there's a problem here.  Consider this:

  var element = new HTMLElement(somename);

OK, so the web author is not being very forward-compatible in that 
they're not using a tag name with a - in it.  But then they put it in 
the DOM and it acts just like a span, and they're happy with that.


Then we want to add a somename tag in the spec, and suddenly this JS 
throws.  This is a different order of breakage than what you get from 
just having new semantics for the somename tag.


In some cases, this is a problem no matter what; e.g. if somename is 
actually img or canvas then the layout is totally different too, not 
just the semantics.  But there are other cases where the layout is not 
that different from a vanilla inline though maybe we don't really 
plan to add any more of those?


In any case, it's a bit of a niggling worry for me because it can 
increase the chance that adding things to HTML breaks websites.


-Boris




Re: Custom element design with ES6 classes and Element constructors

2015-01-13 Thread Boris Zbarsky

On 1/13/15 12:50 PM, Domenic Denicola wrote:

Agreed. That needs to be done with img is=my-img, IMO. (Assuming the 
upgrading design doesn't get switched to DOM mutation, of course.)

Although! Briefly yesterday Arv mentioned that for Blink's DOM implementation there's no real 
difference in internal slots between img and span: both just have a 
single internal slot pointing to the C++ backing object.


Just a few notes:

1)  This is not universal across implementations.  For example, Gecko 
will handle some property accesses by storing the values in additional 
internal slots on IDL objects.  We're not doing that on any elements 
right now, but would likely start doing that for HTMLMediaElement's 
TimeRanges attributes, for example, if those ever switch away from the 
return a new object on every get behavior.


2)  Updating the value in the internal slot means changing the C++ 
object identity, which means finding all the C++ places that have 
pointers to it (like the DOM tree) and ... something.  Not updating the 
value in the internal slot means you now have an img pointing to the 
wrong C++ class or something.


In any case, we seem agreed that for now this case needs to stick to the 
is= syntax.



The argument for different constructors is that: **assuming we want a design 
such that parsing-then-upgrading an element is the same as calling its 
constructor**, then we need the constructor to be split into two pieces: 
allocation, which happens on parse and is not overridden by author-defined 
subclasses, and initialization, which happens at upgrade time and is what 
authors define.


Right, that makes sense.


However, when authors design constructors with `class C1 extends HTMLElement { 
constructor(...) { ... } }`, their constructor will do both allocation and 
initialization. We can't separately call the initialization part of it at 
upgrade time without also allocating a new object.


Hmm.

So this is a situation where having the [[Call]] of the constructor do 
something magic (like ignoring the super() call in the script) might 
be nice, but I agree it would be really weird.



Thus, given a parse-then-upgrade scenario, we can essentially never call C1's 
constructor.


Yes, agreed.


We *could* call some other method of C1 at upgrade time. Say, createdCallback.


Right.


We could even generate a constructor, call it C2, that does HTMLElement 
allocation + calls createdCallback. That's what the current spec does.


OK. Or we could leave that up to the class implementor.  That is, they 
could do:


  class C1 extends HTMLElement {
constructor(...args) { super(...args); this.createdCallback(); }
  };

if they want a nontrivial createdCallback.  It does mean more 
boilerplate, though.


I guess that's basically Arv's proposal, yes?

I'm less worried about the extra leeway in this setup per se and more 
worried about whether the extra leeway would be a footgun in practice...


Thank you for explaining; I see the issues more clearly now.

-Boris



Re: Custom element design with ES6 classes and Element constructors

2015-01-13 Thread Boris Zbarsky

On 1/13/15 12:10 PM, Domenic Denicola wrote:

Hmm.  So given the current direction whereby ES6 constructors may not even be 
[[Call]]-able at all, I'm not sure we have any great options here.  :(  
Basically, ES6 is moving toward coupling allocation and initialization but the 
upgrade scenario can't really be expressed by coupled alloc+init if it 
preserves object identity, right?


Yes, that is my feeling exactly. The old @@create design was perfect for our 
purposes, since its two-stage allocation-then-initialization could be staged 
appropriately


Just to be clear, this still didn't allow you to upgrade a my-img to 
be a subclass of img, because that required a change in allocation, right?



Well, I was skipping several steps and making a few assumptions. Roughly, my 
thought process was that you want *some* constructor that corresponds to 
parser/document.createElement behavior. And, since as discussed it definitely 
can't be your own constructor


This is the part I'm not quite following.  Why can't it be your own 
constructor?  Sorry for losing the thread of the argument here


-Boris



Re: Defining a constructor for Element and friends

2015-01-13 Thread Boris Zbarsky

On 1/13/15 1:33 PM, Ryosuke Niwa wrote:

Shouldn't we throw in this case because the concert type of somename is 
HTMLUnknownElement?


Oh, hmm.

Yes, I guess so.  That's very non-obvious to an author.

Even less obvious because for some tag names using the HTMLElement 
constructor is in fact correct.


The end result here is really something that ends up all self-consistent 
and preserving our invariants and the obvious reaction to it will be 
WAT?.  Not least because the actual interface used by various HTML 
elements is pretty random.


Want a basefont?  HTMLElement.  Want a bgsound?  HTMLUnknownElement. 
 Want a rb?  HTMLUnknownElement.  Want a big?  HTMLElement...



I think if we threw an exception on every attempt to create an element with a name 
without - (as they're HTMLUnknownElement anyway)


I'm not sure I follow.  How do you propose an s be constructed via 
constructor, say?  What about address?


-Boris



Re: Adopting a Custom Element into Another Document

2015-01-13 Thread Boris Zbarsky

On 1/13/15 2:43 PM, Domenic Denicola wrote:

Why is the tree data structure embodied by the DOM any different?


The issue is not the tree structure but rather 1) what it means to have 
a certain document as your ownerDocument and 2) Whether there are 
footguns here that make it too easy for authors to accidentally entrain 
globals forever.


But yes, this has all been discussed at great length...

-Boris



Re: [Selection] Should selection.getRangeAt return a clone or a reference?

2015-01-12 Thread Boris Zbarsky

On 1/12/15 1:56 PM, Olivier Forget wrote:

Unfortunately
multiple range selections are not a nice to have. All real editors
(MS Word, Google Docs, etc..) support selecting multiple ranges


Precisely.  This is why Gecko ended up supporting it: it was needed for 
the editor that was part of the Mozilla suite back in the day


Of course I've made this point before; it just got ignored.  :(

-Boris



Re: Custom element design with ES6 classes and Element constructors

2015-01-12 Thread Boris Zbarsky

On 1/12/15 12:20 PM, Tab Atkins Jr. wrote:

Proto munging isn't even that big of a deal.


That really depends.

For example, dynamically changing __proto__ on something somewhat 
permanently deoptimizes that object in at least some JS engines. 
Whether that's a big deal depends on what you do with your objects.


-Boris




Re: Defining a constructor for Element and friends

2015-01-12 Thread Boris Zbarsky

On 1/11/15 2:33 PM, Domenic Denicola wrote:

Terminology: In what follows I use 'own-instances of X' to mean objects where 
obj.constructor === X,


That doesn't make much sense to me as a useful test, since it's pretty 
simple to produce, say, an HTMLParagraphElement instance on the web that 
has whatever .constructor value you desire, right?  Unless the intent is 
to talk about this in some setup where no one has messed with any of the 
objects or something.


I guess the intent here is that we want obj to have been constructed via 
X in some sense?  Modulo whatever the story is for the things that have 
NamedConstructors.



as distance from 'instances of X' which means objects for which obj instanceof 
X.


OK.

Anyway, modulo exactly what this definition should be, let's talk about 
the proposed the constructor of an element determines its set of 
internal slots invariant.  I'm OK with that if we include constructor 
arguments.  Otherwise, I don't see how it can make sense.  In 
particular, say someone does:


  var x = new Element(a, http://www.w3.org/1999/xhtml;)

or whatever argument order we do.  Per invariant 1 in your document, 
this should get the internal slots of an HTMLAnchorElement, right?  Per 
invariant 2, x.constructor == Element, and in particular x.__proto__ == 
Element.prototype.  So suddenly we have an HTMLAnchorElement as an 
own-instance of Element, which I think violates your invariant 3.


Moving on to invariant 4, is that instances in terms on instanceof 
(which can be almost tautologically true, given what Web IDL says about 
[[HasInstance]] on interface objects), or in terms of what the proto 
chain looks like, or something else?  In particular, the x defined 
above doesn't have HTMLElement.prototype on its proto chain, but is 
instanceof HTMLElement...



I'd like to understand what you mean by interface is Element here, exactly.


I'm just quoting Anne :). My interpretation is that the (object representing 
the) element is an own-instance of Element.


This _really_ requires pinning down what exactly own-instance means. 
Let's get our terminology in order.  ;)


The one piece of terminology that I think we have so far that I 
understand is what it means for an object to implement an interface. 
At least Web IDL has a normative requirement on such a thing being 
defined (e.g. see http://heycam.github.io/webidl/#es-operations step 4 
of the behavior), presumably in terms of some sort of branding.


So it makes sense to me to talk about things implementing Element but 
not any interface that has Element as an inherited interface.  That 
would correspond to is an Element but not any specific subclass of 
Element.  Could use a shorter way of saying it, for sure.


-Boris



Re: Custom element design with ES6 classes and Element constructors

2015-01-12 Thread Boris Zbarsky

On 1/11/15 3:13 PM, Domenic Denicola wrote:

So, at least as a thought experiment: what if we got rid of all the local name checks 
in implementations and the spec. I think then `my-q` could work, as long as 
it was done *after* `document.registerElement` calls.


Yes.


However, I don't understand how to make it work for upgraded elements at all, i.e., in the case 
where `my-q` is parsed, and then later `document.registerElement(my-q, 
MyQ)` happens. You'd have to somehow graft the internal slots onto all MyQ instances after the 
fact


Yep.  It's no fun.


Is there any way around this you could imagine?


Not without making the set of internal slots mutable.

Note that in some implementations (e.g. a self-hosted implementation 
using WeakMaps for internal slots) this might not be so difficult.  But 
in general it does constrain implementation strategies quite significantly.



I know how seriously you were considering my suggestion to rewrite them all ;)


I've pretty seriously considered it on and off


The story is still pretty unsatisfactory, however. Consider the case where your document consists of 
`my-el/my-el`, and then later you do `class MyEl extends HTMLElement {}; 
document.registerElement(my-el, MyEl)`. (Note how I don't save the return value of 
document.registerElement.) When the parser encountered `my-el`, it called `new 
HTMLUnknownElement(...)`, allocating a HTMLUnknownElement. The current design says to `__proto__`-munge the 
element after the fact, i.e. `document.body.firstChild.__proto__ = MyEl.prototype`. But it never calls the 
`MyEl` constructor!


Yeah, I'm not a fan of this part either.


- It means that the code `class MyEl extends HTMLElement {}` is largely a lie.


I think this part of the spec was largely written before ES6 class stuff 
stabilized, fwiw.  Which is not hard, since it's still not stabilized.  ;)



- It means that what you get when doing `new MyEl()` is different from what you got when 
parsing-then-upgrading `my-el/my-el`.


This seems pretty undesirable.


(The same problems apply with q is=qq, by the way. It needs to be upgraded 
from HTMLQuoteElement to QQ, but we can only `__proto__`-munge, not call the constructor.)


Hmm.  So given the current direction whereby ES6 constructors may not 
even be [[Call]]-able at all, I'm not sure we have any great options 
here.  :(  Basically, ES6 is moving toward coupling allocation and 
initialization but the upgrade scenario can't really be expressed by 
coupled alloc+init if it preserves object identity, right?



I was hopeful that ES6 would give us a way out of this, but after thinking things 
through, I don't see any improvement at all. In particular it seems you're always going 
to have to have `var C2 = document.registerElement(my-el, C1)` giving `C2 !== 
C1`.


This part is not immediately obvious to me.  Why does that have to be true?

-Boris



Re: Custom element design with ES6 classes and Element constructors

2015-01-12 Thread Boris Zbarsky

On 1/12/15 7:24 PM, Domenic Denicola wrote:

One crazy idea for solving B is to make every DOM element (or at least, every one 
generated via parsing a hyphenated or is= element) into a proxy whose target 
can switch from e.g. `new HTMLUnknownElement()` to `new MyEl()` after upgrading. Like 
WindowProxy, basically. I haven't explored this in much detail because proxies are scary.


Hey, we have implementation experience for this in Gecko, since that's 
_exactly_ what we do when you adopt an element into a different global: 
we replace the guts of the old object with a proxy to the new thing.  ;)


Some thoughts:

1)  This does NOT affect C++ references in Gecko, not least because the 
C++ object identity doesn't change in this case.  Updating those would 
be a PITA.  But you want to change the C++ object identity for this 
particular use case, so you could get into weird situations where if 
something that's not JS is holding a ref to your element it can now be 
pointing to the wrong element.  Unless things get changed so all C++ 
holds references to elements via their JS reflections, which is probably 
a nonstarter.


2)  There is a performance penalty for having a proxy, obviously.  For 
adoption this is not too horrible, since in practice that's not that 
common, but presumably upgrades would actually be somewhat common.


3)  You need a way for the brand checks Web IDL methods do to deal with 
these proxies.  Gecko already has a way for that to work, on a slower 
path, since we have these membrane proxies, but other UAs would need to 
grow something like that.


-Boris



Re: Defining a constructor for Element and friends

2015-01-09 Thread Boris Zbarsky

On 1/9/15 8:01 PM, Domenic Denicola wrote:

I was writing up my ideas in an email but it kind of snowballed into something 
bigger so now it's a repo: https://github.com/domenic/element-constructors


Domenic, thanks for putting this together.

Caveat: I won't get a chance to read through this carefully until 
Monday.  Responses below are based on just what's in the mail.


That said, I do have one question already: what does the term 
own-instances mean in that document?



whether it is acceptable to have an element whose name is a, namespace is the 
HTML namespace, and interface is Element


I'd like to understand what you mean by interface is Element here, 
exactly.



One ugly point of my design is that the constructor signature is `new 
Element(localName, document, namespace, prefix)`, i.e. I require the document 
to be passed in. I am not sure this is necessary


It's necessary, but I think the document should be allowed, but not 
required.  As in, the signature should be:


  new Element(localName, namespace, prefix, document).

(though maybe prefix should come after document; hard to say).  If the 
document is undefined, then we get a document as follows: Element is a 
function, so has an associated Realm.  This Realm's [[globalThis]] is a 
Window.  This Window has a .document; use that.


The only reason we need the ability to specify a document at all is that 
there are documents around that are not inside a browsing context (XHR 
responseXML, for example) and we need to be able to create elements that 
have those documents as an ownerDocument.  But those document's don't 
have their own global/Realm and hence don't have separate instances of 
the Element constructor.


I commented on the github issue in a bit less detail.


what is the use case for producing something that extends HTMLImageElement (and 
presumably has its internal slots?) but doesn't have img as the tag name and 
hence will not have anything ever look at those internal slots?


Elsehwere on this thread or some related one IIRC he pointed out code that looks at the local name, finds 
img, and casts to the C++ backing representation of HTMLImageElement. So from what I am 
gathering in his view the parts of the platform that treat img elements specially currently work 
by checking explicitly that something has local name img (and HTML namespace).


Yes.  And that's true of not just implementations but also 
specifications.  The entire HTML specification is written in terms of 
local name tests, for example.



 From a naïve authoring point of view that seems suboptimal. I'd rather be able to do 
`class MyImg extends HTMLImageElement { constructor(document) { super(document); } }` and 
have MyImg instances treated specially by the platform in all the ways img 
currently is.


I don't quite see the issue here.  Presumably the HTMLImageElement 
constructor passes img as the localName to the HTMLElement 
constructor, so your MyImg would get img as the localName, right?


Can you explain what the concern is here?

Now I do think there's an authoring problem where if you want to do a 
fancyimage that's treated like img by the platform you have a 
problem.  But that doesn't seem to be what you're talking about... or 
are you?



Or, for an easier example, I'd like to be able to do `class MyQ extends HTMLQuoteElement 
{ constructor(document) { super(document); } }` and have `(new MyQ()).cite` actually 
work, instead of throw a cite getter incompatible with MyQ error because I 
didn't get the HTMLQuoteElement internal slots.


This should totally work, of course.  Why wouldn't it, exactly?  Given 
the subclassing proposal on the table in ES6 right now, it would work 
splendidly, since the HTMLQuoteElement constructor is what would perform 
the object allocation and it would pass along q as the localName. 
(Though actually, HTMLQuoteElement is excitingly complicated, because 
both q and blockquote would use that constructor, so it would need 
to either require one of those two strings be passed in, or default to 
q unless blockquote is passed in or something.)



The logical extension of this, then, is that if after that `document.registerElement` call I do 
`document.body.innerHTML = my-q cite=fooblah/my-q`


Ah, here we go.  This is the part where the trouble starts, indeed.

This is why custom elements currently uses q is=my-q for creating 
custom element subclasses of things that are more specific than 
HTMLElement.  Yes, it's ugly.  But the alternative is at least major 
rewrite of the HTML spec and at least large parts of Gecko/WebKit/Blink. 
 :( I can't speak to whether Trident is doing a bunch of localName 
checks internally.



However this idea that we'd like custom elements which inherit from existing 
elements to have their internal slots ties in to the whole upgrading mess


Right, which you get for free with the q is=my-q setup, since you 
just get the slots for q and then the upgrade just has to worry about 
your proto 

Re: Custom element lifecycle callbacks

2015-01-09 Thread Boris Zbarsky

On 1/9/15 9:33 AM, Anne van Kesteren wrote:

On Fri, Jan 9, 2015 at 3:09 PM, Boris Zbarsky bzbar...@mit.edu wrote:

In any case, the fact that we're even _having_ this discussion and that it
needs careful reading of the HTML spec is my point.


It does seem however we could define this in a way that is safe.


If by this you mean cloning of file inputs, then obviously yes.  I 
never implied otherwise, as far as I can tell.


If by this you mean a change from the current behavior to delayed 
cloning steps, without auditing all the cloning steps to make sure we 
don't end up in weird inconsistent states, then I don't think so.  You 
really do have to carefully audit all the cloning steps in the spec, as 
well as any future cloning steps.


-Boris




Re: Custom element lifecycle callbacks

2015-01-09 Thread Boris Zbarsky

On 1/9/15 8:46 AM, Anne van Kesteren wrote:

As far as I can tell from the specification, when the value IDL
attribute is in the filename mode, any values that might be stored in
internal slots are ignored.


Hmm...  That was not obvious to me, but OK.  I guess it uses the list 
of selected files instead?  And then the claim is that the only 
sanitization that's needed is step 2 of When an input element's type 
attribute changes state, to lose the old value, which was being stored 
all this time, when changing out of the file upload state?


That's pretty bizarre, since it requires storing information that will 
never get used, but ok.



As far as I can tell from the specification you cannot influence the
value returned by input type=file.value in any way.


UAs do not seem to be interoperable here.  In particular, in some UAs 
cloning a file input copies the list of selected files, and in some it 
does not, with the spec seeming to side with the latter.  It's a bit 
weird that cloning would normally copy the value, but not for file inputs.


In any case, the fact that we're even _having_ this discussion and that 
it needs careful reading of the HTML spec is my point.


-Boris



Re: Custom element lifecycle callbacks

2015-01-09 Thread Boris Zbarsky

On 1/9/15 7:14 AM, Anne van Kesteren wrote:

Both parent and input need to be cloned in this case. While parent's
callback runs it changes the type of input, at which point input's
callback runs. So, yes.


OK.  So just to be clear, the type will be set before the input's 
cloning callback runs, yes?



It's a bit unclear to me why When an input element's type attribute
changes state does not sanitize this value


When the type changes it sanitizes the value of the input.  Though I see 
nothing in the spec to indicate this; I filed 
https://www.w3.org/Bugs/Public/show_bug.cgi?id=27791


But in this case the value is not set yet when the type changes.  Then 
the cloning callback runs and sets the value on the now-file-type input, no?


In particular, the current spec for input says:

  The cloning steps for input elements must propagate the value, dirty
  value flag, checkedness, and dirty checkedness flag from the node
  being cloned to the copy.

This is not conditional on the input type in any way, unlike .value 
sets.  So if we allow the type to change before the cloning steps run, 
the cloning steps need to be adjusted to deal with this situation.


And in particular, all cloning steps need to be carefully audited to 
deal with issues like this.



or how cloning it makes it a security concern.


Because if the cloning steps in HTML are left as-is but run after script 
can change the type, then you can create a file input with an arbitrary 
value filled in.  Which is a security concern.


-Boris




Re: Custom element lifecycle callbacks

2015-01-09 Thread Boris Zbarsky

On 1/9/15 4:28 AM, Anne van Kesteren wrote:

On Thu, Jan 8, 2015 at 5:54 PM, Boris Zbarsky bzbar...@mit.edu wrote:

   var input = document.createElement(input);
   input.value = file:///etc/passwd;
   var newInput = input.cloneNode();
   newInput.type = file;


Note that in the above example cloning callbacks would happen after
the cloneNode() call but still before type is being set. So that might
be okay?


Ok, what about this testcase:

  var parent = document.createElement(x-my-element);
  var input = document.createElement(input);
  parent.appendChild(input);
  input.value = file:///etc/passwd;
  parent.cloneNode(true);

and then in the cloning callback for x-my-element, assuming newNode is 
the clone:


  newNode.firstChild.type = file;

That seems to me like it would do the type set before the cloning 
callback for the input runs, right?


-Boris



Re: Custom element lifecycle callbacks

2015-01-08 Thread Boris Zbarsky

On 1/8/15 10:56 AM, Anne van Kesteren wrote:

2) For normal elements we act directly when they are cloned or
adopted. How much interest is there in delaying what happens for
normal elements to align them with custom elements?


Which things are we talking about delaying?

I'm pretty sure the prototype change that happens in Gecko on adopt 
right now is part of our security model and can't easily be delayed. 
The other main thing that happens sync on clone is state propagation 
(e.g. copying of values for inputs, right)?  There are some security 
considerations there too that would need to be considered for every bit 
of state that's propagated; consider:


  var input = document.createElement(input);
  input.value = file:///etc/passwd;
  var newInput = input.cloneNode();
  newInput.type = file;

I would like to see an actual list of the things we're considering 
delaying so we can think about the implications of doing that.


-Boris



Re: Defining a constructor for Element and friends

2015-01-07 Thread Boris Zbarsky

On 1/7/15 6:17 AM, Anne van Kesteren wrote:

The main tricky thing here I think is whether it is acceptable to have
an element whose name is a, namespace is the HTML namespace, and
interface is Element.


That depends on what you mean by interface is Element.

If you mean that it has all the internal slots HTMLAnchorElement has but 
its prototype is Element.prototype, I think that may be fine.  Libraries 
might get confused if you pass them elements like this, but that just 
comes down to don't create elements like this as a guideline, right?


If you mean not having the internal slots HTMLAnchorElement has, then 
that would involve a good bit of both specification and implementation 
work.  Specifically:


1)  Pretty much the entire HTML spec is written in terms of tag names, 
and the operations it performs often assume some sort of state being 
stored on elements with those tag names.  Conceptually this is being 
stored in internal slots (though of course in actual implementations 
slots can mean hashtable entries in some hashtable or whatnot). 
Significant spec work would need to happen to deal with situations where 
the element has some tagname but not the corresponding internal slots.


2)  In specifications, there are assumptions about particular tag names 
having particular internal slots.  For example, you often get code like 
this (not actual code in either one, but intended to get the flavor 
across) at least in WebKit and Gecko:


  void doWhatever(Element* element) {
if (element-isHTML()  element-tagName() == input) {
  HTMLInputElement* input = static_castHTMLInputElement*(element);
  // Do stuff with input here.
}
  }

If we can have HTML elements which have the input tag name but aren't 
represented by a subclass of the C++ HTMLInputElement in the above code, 
you get a security bug.  So codebases would have to be audited for all 
instances of this and similar patterns.  I just did a quick check in 
Gecko, and we're looking at at least 500 callsites just in C++.  There 
are probably more in privileged JavaScript that make assumptions about 
things based on tagname...


This is why the custom elements spec ended up with the is=... business 
for extending nontrivial HTML elements.  :(


So just to check, which of these two invariant-violations are we talking 
about here?



If we can break that invariant it seems rather easy to build the
hierarchy. The HTMLElement constructor would only take a local name
and always have a null prefix and HTML namespace.


I think that's fine in a world where we still create an 
HTMLAnchorElement under the hood if you do new HTMLElement('a') but 
just give it HTMLElement.prototype as the proto.



And HTMLAnchorElement would always be a. HTMLQuoteElement could accept
an enum and we could even add dedicated constructors for q and
blockquote (provided the web allows).


Yeah, this would make sense to me.

-Boris



Re: Defining a constructor for Element and friends

2015-01-07 Thread Boris Zbarsky

On 1/7/15 9:51 AM, Anne van Kesteren wrote:

That is what I meant. Otherwise in order to support new Element()
you'd have to support an ever growing set of more specific objects as
well and layering is out of the window.


Do you mean layering of implementations or specifications?  For 
specifications, here's one way this could work with reasonable layering. 
 DOM provides the following bits:


1)  A registry mapping (namespace, localname) pairs to abstract 
operations that allocate an object.


2)  Abstract operations that can be used by specifications built on top 
of DOM to register abstract operations in this registry.


3)  An abstract operation that takes a list of internal slot names and 
returns an object which has those internal slots, plus the internal 
slots all elements have, plus probably the ordinary object internal 
slots from ES6, depending on whether Web IDL assumes these are ordinary 
objects.  I thought ES6 had this sort of abstract operation already, but 
I don't see anything like it; in any case the only issue here is that 
this requires implementations of DOM and specifications built on top of 
it to agree internally on what internal slot means for elements, I agree.


Specifications that define elements on top of DOM provide the following 
bits:


4)  An abstract operation that creates an uninitialized version of their 
element, via calling the thing defined in #3.


5)  Registration of the abstract operation defined in #4 with the 
registry defined in #1, whether that happens at global-setup time or 
when the element definition is encountered or whatever.


An implementation that wants to just implement core DOM but not things 
built on on top of it can skip all of this machinery.  An implementation 
that wants to support DOM but not everything on top of it (e.g. support 
MathML but not HTML or something) just supports the bits it wants and 
the registry ends up not having stuff in it that it has in other 
implementations.  Seems ok to me.


Now some questions:

* Did I cover your concern about have to support an ever growing set of 
more specific objects?  If not, can you explain what the concern is?


* Without a mechanism like the above, how would one go about supporting 
document.createElement(NS) as it exists on the web.



However, that does indeed seem like a lot of work and it's not clear
whether that actually pays off in the end :-(


That's hard to say without knowing what the desired payoff is.

-Boris




Re: HTML imports in Firefox

2014-12-15 Thread Boris Zbarsky

On 12/15/14, 1:10 PM, Ashley Gullen wrote:

Why would modules affect the decision to ship HTML imports?


Because the interaction of the various import systems with each other 
needs to be specified, for one thing.


But more to the point, we're not shipping imports because we've gotten 
feedback from a number of people that imports are not solving the 
problems they actually need solved.  We'd prefer to not ship imports and 
then need to ship yet another HTML import system that solves those problems.



The webcomponents.org http://webcomponents.org polyfill for imports
has a couple of caveats, so it doesn't look like it's totally equivalent
and portable with browsers with native support, like Chrome which has
shipped it already.


Chrome has shipped a lot of things in this space already.  Feel free to 
mail me privately for my feelings on the matter.  chrome shipping 
something is not sufficient reason to ship something we're pretty sure 
is deficient, I'm afraid.


-Boris



Re: HTML imports in Firefox

2014-12-15 Thread Boris Zbarsky

On 12/15/14, 3:09 PM, Arthur Barstow wrote:

Does [Bugzilla] capture all of Mozilla's Imports concerns (or at least
the higher priority issues)?


Not yet.  We've just gotten things sorted out on our end.


If not, who should I contact to request
capturing your concerns?


I think Anne's email covers it.

-Boris



Re: Help with WebIDL v1?

2014-12-03 Thread Boris Zbarsky

On 12/3/14, 6:02 AM, Yves Lafon wrote:

Pretty much like refactoring XHR using Fetch or not. Most
implementations will most probably move to the latest version, but the
external interface will be the same.


External interface being the IDL syntax in this case, not the 
resulting web-exposed interface, right?



In the case of Sequence, the ES
binding says in the two versions IDL sequenceT values are represented
by ECMAScript Array values.


That's only really true for sequence return values in v2.  sequence 
arguments are represented by ES iterables.



The option 2 you outline seems best here, the syntax is considered as
stable (well, can be expanded, things can be declared obsolete, but
there won't be breaking changes), but implementations (as in the es
binding algorithms) may change to match the evolution of the underlying
language.


OK.  I can live with this as long as the people referencing v1 can live 
with it.



Or another example: in v1 having an indexed getter implies nothing
about being iterable, but in v2 it implies ES6 iterability.


This is an example of v1 plus one feature.


Not plus an IDL feature.  As in, this is not a case of v2 adds some IDL 
syntax compared to v1, but if you never use it in your spec you never 
have to worry about it.  This is a case of the same syntax has 
different resulting behavior in implementations depending on which 
version of IDL they implement, leading to possible lack of interop for 
different implementations of your spec depending on which IDL version 
they choose to use.


This is why in option 2 it's important to spell out what the actual 
requirements on implementations are that arise from the IDL reference.



Another option would be to define only the syntax and leave the bindings
to v2 only, but it wouldn't help much for testing.


Indeed.  Or, again, actual interop.

-Boris




Re: Help with WebIDL v1?

2014-12-01 Thread Boris Zbarsky

On 12/1/14, 1:49 PM, Travis Leithead wrote:

I believe so; this will give many specs a baseline WebIDL document to point to 
in their references at the very least. Many specs don't rely on the more 
advanced feature set being defined in WebIDL Second Edition.


Here's the problem.

As of today, v2 is not just v1 plus some more features.  They actually 
have some disagreements on how identical IDL syntactic constructs are 
handled.  For example, sequence behavior is different: in v1 a sequence 
has magic for platform array objects and the gets the length property 
and goes from 0 to length, while in v2 a sequence is an iterable and 
uses the ES6 iterator protocol.


Or another example: in v1 having an indexed getter implies nothing about 
being iterable, but in v2 it implies ES6 iterability.


More generally, v1 is pretty much defined in ES5 terms, while v2 is 
aiming for closer convergence with ES6.


What happens when a spec uses a sequence argument and references v1? 
Are UAs supposed to implement the v1 behavior or v2 behavior?



However, let's not hijack this thread; I'd love to hear what the next steps are 
for moving this v1 forward.


I think that actually depends on how we want to handle the problem I 
describe above.


Some obvious options are:

1)  Backport all behavior changes from v2 to v1 so they agree on the set 
of syntactic constructs supported by v1.  This makes v1 depend on ES6, 
which I understood to be a non-goal (or perhaps even anti-goal, given 
ES6 is not finalized yet?  But it's close).


2)  Treat v1 as a syntax spec (with v2 a superset of the syntax) and 
explicitly say somewhere in v1 that v2 can redefine the behavior.  Not 
sure how happy people referencing v1 will be with that.


Other options?

-Boris



Re: [xhr] Questions on the future of the XHR spec, W3C snapshot

2014-10-18 Thread Boris Zbarsky

On 10/17/14, 8:19 PM, Hallvord R. M. Steen wrote:

a) Ship a TR based on the spec just *before* the big Fetch refactoring.


If we want to publish something at all, I think this is the most 
reasonable option, frankly.  I have no strong opinions on whether this 
is done REC-track or as a Note, I think, but I think such a document 
would in fact be useful to have if it doesn't exist yet.



b) Ship a TR based on the newest WHATWG version, also snapshot and ship the 
Fetch spec to pretend there's something stable to refer to.


I think this requires more pretending thatn I'm comfortable with for 
Fetch.  ;)



c) Ship a TR based on the newest WHATWG version, reference WHATWG's Fetch spec 
throughout.


There doesn't seem to be much point to this from my point of view, since 
all the interesting bits are in Fetch.


-Boris



Re: PSA: publishing new WD of URL spec

2014-09-11 Thread Boris Zbarsky

On 9/11/14, 12:52 PM, Mark Baker wrote:

On Thu, Sep 11, 2014 at 12:13 PM, Anne van Kesteren ann...@annevk.nl wrote:

In which case the WHATWG version wouldn't be canonical anymore anyway.


It would be for implementers.


Only those implementers that can afford to staff a team to keep up
with a moving target. That's not all potential implementers.


Mark, the options are to have a team do that or to have a team to 
reverse-engineer the other implementations.  Assuming you want to be 
interoperable with said implementations, of course.


Tracking a well-written spec is _usually_ simpler than 
reverse-engineering other implementations...


-Boris




Re: publishing new WD of URL spec

2014-09-10 Thread Boris Zbarsky

On 9/10/14, 6:14 PM, Glenn Adams wrote:

and they do not follow a consensus process.


Glenn, with all due respect, neither do many W3C specifications.  Case 
in point is http://www.w3.org/TR/navigation-timing/ which managed to get 
to REC while ignoring feedback that pointed out that not a single 
implementation actually matched the specification (including the ones 
produced by the employers of the editors).  And this wasn't because the 
implementations were buggy, but because the specification was incomplete.


Of course now that it's a REC getting it fixed is a major production; 
given that it didn't happen back when it should have I have no hope of 
it happening now.


This is hardly an isolated incident with W3C specifications.  In fact, 
and very unfortunately, it's the most common thing I see happening.


-Boris



Re: Proposal for a Permissions API

2014-09-02 Thread Boris Zbarsky

On 9/2/14, 9:51 AM, Mounir Lamouri wrote:

   required PermissionName name;


Glad to see required being put to good use.  ;)


interface PermissionManager {


IDL nit: This needs Exposed=(Window,Worker)


[NoInterfaceObject, Exposed=Window,Worker]


And parens.

-Boris



Re: First Draft of W3C version of URL Spec

2014-08-27 Thread Boris Zbarsky

On 8/27/14, 4:50 PM, Daniel Appelquist wrote:

with a few minimal editorial changes.


What are the changes, specifically?

-Boris



Re: =[xhr]

2014-08-01 Thread Boris Zbarsky

On 8/1/14, 9:39 AM, nmork_consult...@cusa.canon.com wrote:

All tabs, menus, etc. must be frozen.


Sync XHR doesn't do that.

-Boris



[imports] credentials flag bits need to be updated to current fetch terminology

2014-07-15 Thread Boris Zbarsky
In http://w3c.github.io/webcomponents/spec/imports/#fetching-import the 
spec says:


  Fetch a resource from LOCATION with request's origin set to the
  origin of the master document, the mode to CORS and the omit
  credentials mode to CORS.

There is no omit credentials mode in the current Fetch draft, and the 
mode that _is_ there, credentials mode, doesn't have CORS as a 
value.  Presumably this is asking for same-origin?


-Boris



Re: Fallout of non-encapsulated shadow trees

2014-07-02 Thread Boris Zbarsky

On 7/2/14, 11:07 AM, Adam Barth wrote:

I've studied the XBL implementation of marquee in Gecko, and it does
leak some implementation details.


Absolutely.  The point of the XBL implementation was to provide the 
functionality (back before there was a spec for it, note) at minimal 
cost and core complexity.  It's not even close to what hixie has specced 
for marquee right now.



As a simple example,
alert(document.createElement('marquee')) in Firefox says [object
HTMLDivElement] because the XBL implementation uses a div.


It's because XBL doesn't have a way to affect the sort of JS object 
that's created for the element and we explicitly map the marquee tag 
name to creating an HTMLDivElement C++ object because we didn't really 
have any better sort of C++ object for it to create.


Web components can help solve parts of this what sort of JS object to 
create?, I agree.


-Boris



Re: Fallout of non-encapsulated shadow trees

2014-07-01 Thread Boris Zbarsky

On 7/1/14, 9:16 PM, Ryosuke Niwa wrote:

I would love to hear from Mozillians if they have gotten enough developer 
feedbacks


Our implementation is currently at a stage that can best be described as 
not usable yet, which is most of the feedback we've gotten thus far.  ;)


-Boris



Re: Fallout of non-encapsulated shadow trees

2014-07-01 Thread Boris Zbarsky

On 7/1/14, 9:13 PM, Brendan Eich wrote:

Are you sure? Because Gecko has used XBL (1) to implement, e.g., input
type=file, or so my aging memory says.


We use XBL to implement marquee.

We do not use XBL to implement input type=file, though there was 
once a project to do that sort of thing.


-Boris



Re: Fallout of non-encapsulated shadow trees

2014-07-01 Thread Boris Zbarsky

On 7/1/14, 11:20 PM, Brendan Eich wrote:

XBL can expose anonymous content via special API:

https://developer.mozilla.org/en-US/docs/XBL/XBL_1.0_Reference/DOM_Interfaces#getAnonymousNodes

https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/Tutorial/XBL_Example
https://developer.mozilla.org/en-US/docs/XBL/XBL_1.0_Reference/Anonymous_Content

I'm rusty on this stuff; bz should correct anything amiss here.


A few things:

1)  The XBL implementation has not been static over time.  At one point, 
XBL ran in the same global (Realm, whatever you want to call it) as the 
document it was bound to.  This caused obvious encapsulation issues.  We 
attempted to change it to run in a separate global, but ran into compat 
problems with Firefox UI and extensions that depended on the old 
behavior.  At the moment, XBL runs in the same global as the document 
when the document is part of the browser UI, but runs in a separate 
global when the document is untrusted.  This means we can use XBL to 
implement things like marquee or the controls of video elements 
without worrying about the XBL scripts being affected by whatever the 
web page is doing to its global.


2)  The document.getAnonymousNodes API does exist, but is only exposed 
to trusted globals and the XBL globals associated to untrusted web 
pages.  In other words, you can only use getAnonymousNodes() if you are 
same-global with the XBL code already.



   Gecko does*not*  today  leak any
internal details of input type=file, in the way that type 2 web
components would leak; that would be a major security breach.


Right you are -- native anonymous content is special this way. But ES6
proxies are used (albeit by C++ APIs):


In fact, we place the JS reflections for the innards of the file input 
in the same global as XBL bound to the page, if I recall correctly. 
Though there is no exposed API to get at it, of course.



So I question whether membranes *and* structured clones are required.
SES uses membranes without cloning (wrapping, not cloning). This all
seems doable in-JS with enough care and testing, including
capability-leak detection. Proxies are awesome!


Membranes are definitely doable, but there's a lot of details to get right.

-Boris



Re: Fallout of non-encapsulated shadow trees

2014-07-01 Thread Boris Zbarsky

On 7/2/14, 12:15 AM, Brendan Eich wrote:

Boris Zbarsky wrote:

On 7/1/14, 9:13 PM, Brendan Eich wrote:

Are you sure? Because Gecko has used XBL (1) to implement, e.g., input
type=file, or so my aging memory says.


We use XBL to implement marquee.


Also video playback controls, per your next message.


That's correct, but that's a slightly different situation because the 
XBL in that case is bound to an element that is internal anonymous 
content (in the same way that the button inside an input type=file 
is internal anonymous content) that the web page shouldn't have any 
access to anyway.  The marquee case is interesting because the element 
the XBL is attached to is in fact visible to the web page.


-Boris



Re: Should / Can an EventHandler throw a stack overflow exception?

2014-06-30 Thread Boris Zbarsky

On 6/30/14, 4:40 AM, Anne van Kesteren wrote:

Are stack overflow exceptions even a thing per standards?


No.

However, they come up pretty regularly in practice.  In fact, some sites 
depend on them for proper functioning.  :(


-Boris



Re: WebIDL Spec Status

2014-06-24 Thread Boris Zbarsky

On 6/24/14, 6:56 AM, Charles McCathie Nevile wrote:

While nobody is offering an editor who can get the work
done, this argument is in any case academic (unless the editor's
availability is predicated on the outcome, in which case it would be mere
political machinations).


I strongly disagree with that characterization.

The fact is, for browser vendors a stable v1 Web IDL snapshot as we have 
right now is not very useful, since that's not what they need to 
implement in practice: there are too many APIs currently being specified 
that cannot be expressed in that snapshot.  So it's really hard to 
justify devoting resources to such a snapshot.


On the other hand, making Web IDL reflect ongoing specification reality 
is something that's really useful to browser vendors, so it might be 
easier to convince them to spend time on that.  No political 
machinations involved.


A more recent snapshot might be more useful, but is still likely to end 
up not being an actual implementation target because there are still too 
many changes happening in terms of ES integration and the like.


I don't have a good solution to this problem, unfortunately.  :(

On the other hand, the only audience I see for a snapshot are 
specification writers who don't want/need the newer things we're adding 
to Web IDL.  Are there other audiences?  Are there actually such 
specification writers?  The recent set of changes to Web IDL have all 
been driven by specification needs.


-Boris



Re: WebIDL Spec Status

2014-06-24 Thread Boris Zbarsky

On 6/24/14, 1:05 PM, Glenn Adams wrote:

Such device certification regimes cannot work unless the referenced
specifications are locked down and clearly implementable.


I see.

So this is not about actual spec implementations or spec authors but 
effectively about a QA cycle that compares the implementations to the 
specs, and which needs to know which spec to compare the implementations to.


In an ideal alignment of incentives, the organizations that need this 
sort of snapshot would step up to produce it, but I'm not sure how 
likely that is to happen in practice...


-Boris



Re: WebIDL Spec Status

2014-06-24 Thread Boris Zbarsky

On 6/24/14, 1:46 PM, Glenn Adams wrote:

The primary goal of the W3C is to produce Technical Reports that reach a
stable level of maturity.


The Technical Reports are not an end in themselves.  They're a means to 
an end.  This is why we don't produce Technical Reports that just say 
do whatever if we can avoid it, because that would fail to fulfill our 
_actual_ goals (which might differ for different W3C members of course; 
for some of them maybe do whatever is good enough for their purposes).


You're correct that sometimes the production of the Technical Report is 
viewed as an end in itself in an attempt to bridge the different 
member's actual goals.  Sometimes this works ok, and sometimes the 
result is a TR that is useless to some subset of members.


I happen to be affiliated with a member for whom most TRs (possibly all 
of them) as practiced by the W3C tend to be somewhat useless compared to 
the process of putting together the TR, so I have certain biases in that 
regard.



If a WG fails to move a technical report to REC then it has failed its
chartered purpose (as far as that report is concerned).


Yes, agreed, as the W3C process is set up right now.  It's a bug, not a 
feature.  ;)



In my capacity in this WG, I represent a Full Member who pays for
membership in order to see technical work reach completion.


Is this Member willing to devote resources to getting there?

Again, I'm not saying we shouldn't have a REC of Web IDL.  I'm saying 
that currently there's a perverse incentives problem: the only people 
who have stepped up to edit the spec are the ones who are affiliated 
with a Member which can'e make much use of a Web IDL REC in its current 
state all that much.  Which means that they end up, consciously or not, 
not prioritizing reaching REC on Web IDL v1, say, particularly highly.



In the current situation, I think the best course would be for the chair
and team members of this group to attempt to work with the editor to
define a reasonable schedule for moving it forward to REC, and, if
necessary call for volunteer co-editors if the current editor is unable
to invest sufficient time to see through that process.


Yep, we agree.

-Boris



Re: HTML imports: new XSS hole?

2014-06-03 Thread Boris Zbarsky

On 6/3/14, 12:48 PM, Hajime Morrita wrote:

HTML Imports are a bit more strict. They see CORS header and decline if
there is none for cross origin imports.
Also, requests for imports don't send any credentials to other origins.


These two measures prevent attacks on other origins via imports.

It does nothing about attacks by the imported script on the page the 
import is happening into.


-Boris



Re: HTML imports: new XSS hole?

2014-06-02 Thread Boris Zbarsky

On 6/2/14, 8:54 AM, James M Snell wrote:

So long as they're handled with the same policy and restrictions as the
script tag, it shouldn't be any worse.


It's worse for sites that have some sort of filtering on user-provided 
content but don't catch this case right now, no?


-Boris



Re: HTML imports: new XSS hole?

2014-06-02 Thread Boris Zbarsky

On 6/2/14, 9:22 AM, James M Snell wrote:

Yes, that's true. Content filters are likely to miss the links
themselves. Hopefully, the imported documents themselves get filtered


By what, exactly?  I mean, CSP will apply to them, but not website 
content filters...



One assumption we can possibly make is that
any implementation that knows how to follow import links ought to know
that they need to be filtered.


Sure, but that assumes the filtering we're talking about is being done 
by the UA to start with.


-Boris



Re: HTML imports: new XSS hole?

2014-06-02 Thread Boris Zbarsky

On 6/2/14, 9:54 AM, James M Snell wrote:

Im not saying it's perfect. Not by any stretch. I'm saying it shouldn't
be worse.


I don't understand why you think it's not worse.


and content filters will need to evolve.


And until they do, we may have vulnerable pages, right?  How is that not 
worse?


Say an OS added some new functionality that meant software running on 
that OS would be insecure unless it got patched.  Would you consider 
that acceptable?  This is a pretty similar situation.


The only thing that might make this OK is if good whitelist-based 
filters are overwhelmingly used in practice.



Perhaps an additional
strongly worded warning in the spec would be helpful.


By what mechanism would someone who created a web page a year ago see 
this warning and go update their page?


-Boris



Re: HTML imports: new XSS hole?

2014-06-02 Thread Boris Zbarsky

On 6/2/14, 4:21 PM, Giorgio Maone wrote:

I do hope any filter already blocked out link elements, as CSS has
been a XSS vector for a long time


link elements without stylesheet in rel don't load CSS, though.

Hence the worries about blacklist vs whitelist...

-Boris



Re: HTML imports: new XSS hole?

2014-06-02 Thread Boris Zbarsky

On 6/2/14, 11:17 PM, Eduardo' Vela Nava wrote:

Now, I'm not sure how many have tried to implement an HTML sanitizers.


I've reviewed Gecko's implementation of one, if that counts...


  1. You have to write a parser OR You have to use a third-party parser.


Wasn't an issue for us obviously.


  2. You have to get a serializer.


Likewise.


  3. You need a sane whitelist.


This was a pain.


   3.1 And the whitelist, apparently, needs to be aware of not just
tag/attribute pairs, but also tag/attribute + rel=stylesheet geez!


And this.  We actually rip out all @rel values specifically on link 
elements, because we in fact do not want to allow rel=stylesheet (but 
we do want to allow we do allow @rel on other elements)


I agree with your general point, though, which is that writing a good 
sanitizer is pretty nontrivial.


-Boris



Re: Fetch API

2014-06-01 Thread Boris Zbarsky

On 6/1/14, 2:06 AM, Domenic Denicola wrote:

- Named constructors scare me (I can't figure out how to make them work in 
JavaScript without breaking at least one of the normal invariants). I think a 
static factory method would make more sense for RedirectResponse.


Or just a constructor overload, if the type of body for the existing 
constructor can be told apart from a string.  Which may not be the case, 
of course.



- HeaderMap should have a constructor that takes an iterable of [key, value] 
pairs, in the same way Map does.


So a sequencesequenceByteString basically, right?  Seems pretty 
plausible to me.



- I like HeaderMap a lot, but for construction purposes, I wonder if a 
shorthand for the usual case could be provided. E.g. it would be nice to be 
able to do

fetch(http://example.com;, {
   headers: {
 X-Foo: Bar


We've had other cases arise where such an open-ended dictionary 
construct would be useful.  The only difference is that those other 
cases wanted string-valued keys while this might want ByteString-valued 
ones...


One concern here: is order an issue for headers?  I seem to vaguely 
recall that in practice order can matter with some HTTP servers.


-Boris

P.S.  Still reading through; will have feedback of my own in the next 
few days.




Re: Blob URL Origin

2014-05-16 Thread Boris Zbarsky

On 5/16/14, 10:11 AM, Anne van Kesteren wrote:

What exactly is wrong with the data URL model that we have today


The fact that some UAs don't want to implement it?


and how do we plan on fixing it?


We don't have a plan yet.


But I guess this is a scenario you explicitly want to outlaw,
even though you could do the equivalent by passing a Blob object
directly and that would always work.


Where by directly you mean postMessage, right?

-Boris




Re: Blob URL Origin

2014-05-16 Thread Boris Zbarsky

On 5/16/14, 10:39 AM, Anne van Kesteren wrote:

The fact that some UAs don't want to implement it?


Do we know why?


They think it's a security problem.

-Boris



Re: Blob URL Origin

2014-05-16 Thread Boris Zbarsky

On 5/16/14, 11:08 AM, Anne van Kesteren wrote:

Not tainting canvas? Same-origin iframe? Doesn't matter?


The same-origin iframe bit.  I think everyone is on board with not 
tainting canvas for data: things.


-Boris




Re: Blob URL Origin

2014-05-13 Thread Boris Zbarsky

On 5/13/14, 1:20 AM, Frederik Braun wrote:

On 12.05.2014 18:41, Jonas Sicking wrote:

(new URL(url)).origin should work, no?


It does not work for blob URIs in Firefox.


It can't work, given how URL.origin is currently defined...  It's 
possible that definition should change, though.


-Boris




Re: Custom Elements: 'data-' attributes

2014-05-13 Thread Boris Zbarsky

On 5/13/14, 7:31 AM, Dimitri Glazkov wrote:

Sole had the idea of providing hooks for attributes so a component can
say it handles them rather than the user agent. That makes a lot of
sense to me. That way you can grab any name, even existing ones.


3 this idea, would love to hear more. It's like dinner reservations
for attributes!


I slightly worry about the performance implications of this and the 
number of changes to UAs this will require: any place inside a UA that 
examines attribute values (only for global attributes?) would need to 
consult this reservation information, right?


-Boris



Re: Blob URL Origin

2014-05-12 Thread Boris Zbarsky

On 5/12/14, 5:28 AM, Anne van Kesteren wrote:

so blob:https://origin:42/uuid would be fine.


I'd really rather we didn't make web pages parse these strings to get 
the origin.  A static method on Blob that takes a valid blob: URI and 
returns its origin seems like it should be pretty easy for UAs to 
implement, though.


-Boris



Re: Blob URL Origin

2014-05-12 Thread Boris Zbarsky

On 5/12/14, 7:46 AM, Anne van Kesteren wrote:

I thought the idea was to associate the origin of
URL.createObjectURL() with the Blob object (which might be different
from the Blob object's origin).


Er, right, these URLs come from URL.createObjectURL.  So we'd want a 
URL.getObjectURLOrigin() or some such, not a static on Blob, if we want 
a way to expose the origin to script.


-Boris



  1   2   3   4   5   6   7   8   >