- From: Lachlan Hunt <lachlan.hunt@lachy.id.au>
- Date: Sun, 10 Apr 2011 13:30:33 +0200
- To: Boris Zbarsky <bzbarsky@MIT.EDU>
- CC: public-webapps <public-webapps@w3.org>, Cameron McCormack <cam@mcc.id.au>
On 2011-04-09 19:14, Boris Zbarsky wrote:
> On 4/9/11 6:27 AM, Lachlan Hunt wrote:
>> There were cases in JQuery where the script wanted to iteratively run a
>> selector on all nodes in a collection, and return elements that are
>> descendants of those elements. This allows :scope to be used in those
>> cases by passing the collection as the refNodes. There was previous
>> discussion of this somewhere in the public-webapps archive.
>
> Hmm... ok.
As a simple example of that, this works in JQuery:
<p><span></span>
<p><span></span>
<p><span></span>
<script>
alert($("p").find(">span").length)
</script>
> But is jquery's collection a JS Array?
The object returned by the $() function isn't an array. It's a custom
object that mimics the functionality of an array. This means that as
currently defined, refElements could not accept a JQuery object as the
parameter like so:
var p = $("p.foo")
Var a = $("a");
a[0].matchesSelector(":scope>a", p)
This would instead require scripts to do this:
a[0].matchesSelector(":scope>a", p.toArray())
JQuery effectively defines .toArray() as a function that returns:
Array.prototype.slice.call( this, 0 );
Would it be useful, and is it possible to define the refElements
parameter to accept any object that contains a .length and indexed
properties, just like a JQuery object? i.e. Can we make this work?
var x = {}
x[0] = el1;
x[1] = el2;
x[2] = el3;
x.length = 3;
a.matchesSelector(":scope>a", x);
>> I also have to include one for HTMLCollection, which doesn't inherit
>> from NodeList.
>
> Yeah, that's broken... I wonder whether we can just fix that in Web DOM
> Core or something....
Yes, I'd like to fix it somehow. I'm not yet sure how.
>> WebIDL says sequences are passed by value and arrays are passed by
>> reference. So I suspect using an array is better here so that it doesn't
>> have to create a copy.
>
> The by reference thing only happens for array host objects, which a JS
> Array is not. So the copy would effectively happen in either case, I
> believe, for JS Array.
OK. Then I'm not sure what the practical difference between the
Element[] or sequence<Element> would be then, nor which one to use.
>> Yes, I would like feedback about the best way to define this,
>> particularly for Arrays. In particular, how to address the following
>> cases.
>>
>> var ref = [];
>> ref[0] = el1;
>> ref[1000000] = el2;
>>
>> That will contain almost a million empty cells. Will iterating through
>> that cause any unwanted performance issues?
>
> I believe my current Gecko implementation (using our existing variant
> facilities, since that's all we have to deal with overloads for the
> moment) will allocate a C array with 1000001 entries, then ignore it
> because not everything in the array is an Element.
>
> A DOM binding implementation using WebIDL arrays or sequences would
> allocate a C++ array with 1000001 entries, all of which except for the
> first and last are null. Then the actual implementation of the selectors
> API will walk this array and add only the first and last entry to the
> set of scope elements. I think. I'm pretty sure this is true for Array;
> the behavior for sequence is less clear to me. And maybe this can all be
> optimized in implementations, somehow... Ccing Cameron for his input.
>
>> Should we require arrays to contain contiguous Elements and only
>> iterate up to the first empty or non-Element cell, ignoring
>> anything beyond that?
>
> If using webidl array/sequence types, that would help with the
> iteration, but not the large allocation.
OK, does that mean it's not really worth defining like that?
>> ref[1] = "string";
>>
>> Should passing this now throw an exception, or should it just accept
>> that ref[0] was an element and use that?
>
> Webidl array/sequence would throw in this case, I think.
Yes, I just checked and I think you may be right. The WebIDL algorithm
to convert an ECMAScript array to an IDL value of type T[] iterates the
array and says:
While i < n:
Let x be the result of calling [[Get]] on V with property name
ToString(i).
Set Ei to be the result of converting x to an IDL value of type T.
Set i to i + 1.
I think the second step in the loop should throw a TypeError if the
object can't be converted to the correct type (Element, in this case).
But WebIDL doesn't seems very clear about this, so I may be wrong.
--
Lachlan Hunt - Opera Software
http://lachy.id.au/
http://www.opera.com/
Received on Sunday, 10 April 2011 11:31:08 UTC