[Prototype-core] Hi Dears,

2008-08-21 Thread [EMAIL PROTECTED]

I want to chat with you on google talk,.

I love you,


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Hi Dears,

2008-08-21 Thread [EMAIL PROTECTED]

I want to chat with you on google talk,.

I love you,


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread T.J. Crowder

Hey folks,

Weighing in briefly (being hammered at work and at home, and not in
that fun way).  Great stuff so far!  Thoughts/opinions/questions:

1. IMHO, $$() should _always_ return a list/array/whatever, even if
there's only one element; it should never return the NodeWrapper
itself.  Two reasons:  A) Having a function that returns a list in
some situations and a single element in another situations just means
that every use of it has to check what it got back, leading to
unnecessarily-verbose code and confusion on the part of users.  If
people are doing things like $$(#thingy), tell them to use $(),
that's what it's for. :-)  If there's a really really good reason
they're using $$() (for instance, they don't know what the selector
is, it's supplied from elsewhere), well, then they should always be
expecting to get back a list. B) That's what it does now.

  I don't think there would be confusion with things like $$
  (..).getValue() here.

  Keep in mind users do use the equiv of  $$('#myId') and that in those
  cases you are expecting 1 result
  so the desired behavior of a readAttribute, or getValue or anything
  getting a property
  is to return from the only matched item.

 True.
 We could reduce ambiguity by having some kind of a generic rule - e.g.
 all accessor methods always act on the first item. This should be
 fine, as long as there are no (or not many) exceptions.

2. FWIW, it seems to me that calling an accessor on a list should
return a list of the accessor results for each list element.  Always.
Similarly, calling a setter on the list [e.g., $$
('.blarg').update('yada')] should call the setter on all list
elements.

 1) NodeWrapper always exposes a public `source` property, which is a
 reference to a wrapped element:

3. Still don't like source.  That word is just way too overloaded,
and again, it's as much a target (e.g., of an update() call) as a
source.  raw is the best general term I've thought of, but I'm not
married to it.  Whatever we use should be *short* (so not
wrappedThingamajig) and as clear as feasible.  Maybe we should give
up on the generic term (I *know* it was my idea, but...) and just use
something meaningful for each wrapper, e.g. NodeWrapper.node,
ListWrapper.list, etc.  Keep 'em short, document 'em, and if people
forget what the property for the wrapped thingy inside a
NodeListWrapper is, too bad, at least the terms are short and clear.

4. get() and set() methods:  Great to have them, but I think it's
important that we not expect/require that people _use_ them.  We're
not, right?  I don't want to make a function call to access tagName,
I'll want to use wrapper.source.tagName (or wrapper.raw.tagName)
without the wrapper getting confused somehow.

5. How will the list wrapper handle indexing into the list?  E.g.:

var items;
var n;
items = $$('div.item');
for (n = 0; n  items.length; ++n)
{
items[n].update('This is item ' + n);
}

I'm not aware of a standard, widely-supported JavaScript feature that
lets us define the subscript operator, so I'm guessing the above is
out.  Again I hate to introduce a function call for simple access
[e.g., list.item(n), a'la Microsoft collections], so would I go to the
underlying raw/source?

6. Question on $$():  I think the idea so far is that it returns a
NodeListWrapper.  I'm guessing that that's a list of NodeWrappers
around the results of the query, right?  So I could reliably rewrite
my code above like this (I'll use 'source' rather than 'raw' here):

var items;
var list;
var n;
items = $$('div.item');
list = items.source;
for (n = 0; n  list.length; ++n)
{
list[n].update('This is item ' + n);
}

...because although I'm accessing the raw list, it contains wrapped
nodes.  Is that the idea?
--
T.J. Crowder
tj / crowder software / com


On Aug 21, 6:37 am, kangax [EMAIL PROTECTED] wrote:
 On Aug 21, 12:15 am, Ken Snyder [EMAIL PROTECTED] wrote:



  ... I forked prototype, and started working on NodeWrapper/NodeListWrapper
   -http://github.com/kangax/prototype/tree/master/src/element.js
   Accompanying tests are there as well (although the test suite is far
   from being complete).

   --
   kangax

  Exciting to see in code! What about adding caching instances and maybe even
  using a double-duty constructor instead of Class.create?  See what I mean
  below.
  - Ken Snyder
  Prototype.Element = function(element) {
    if (this instanceof Prototype.Element) {
      // constructor
      element.__prototypeWrapper = this;
      this.raw = element;
    } else {
      // getInstance function
      // allow element to be string, dom node, or Prototype.Element instance
      element = (typeof element === 'string' ?
  document.getElementById(element) : element);
      if (element instanceof Prototype.Element) {
        return element;
      }
      if (element  element.__prototypeWrapper) {
        return element.__prototypeWrapper;
      } else {
        return new 

[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread kangax

On Aug 21, 7:13 am, T.J. Crowder [EMAIL PROTECTED] wrote:
 Hey folks,

 Weighing in briefly (being hammered at work and at home, and not in
 that fun way).  Great stuff so far!  Thoughts/opinions/questions:

 1. IMHO, $$() should _always_ return a list/array/whatever, even if
 there's only one element; it should never return the NodeWrapper
 itself.  Two reasons:  A) Having a function that returns a list in
 some situations and a single element in another situations just means
 that every use of it has to check what it got back, leading to
 unnecessarily-verbose code and confusion on the part of users.  If
 people are doing things like $$(#thingy), tell them to use $(),
 that's what it's for. :-)  If there's a really really good reason
 they're using $$() (for instance, they don't know what the selector
 is, it's supplied from elsewhere), well, then they should always be
 expecting to get back a list. B) That's what it does now.

   I don't think there would be confusion with things like $$
   (..).getValue() here.

   Keep in mind users do use the equiv of  $$('#myId') and that in those
   cases you are expecting 1 result
   so the desired behavior of a readAttribute, or getValue or anything
   getting a property
   is to return from the only matched item.

  True.
  We could reduce ambiguity by having some kind of a generic rule - e.g.
  all accessor methods always act on the first item. This should be
  fine, as long as there are no (or not many) exceptions.

 2. FWIW, it seems to me that calling an accessor on a list should
 return a list of the accessor results for each list element.  Always.
 Similarly, calling a setter on the list [e.g., $$
 ('.blarg').update('yada')] should call the setter on all list
 elements.

This is tricky : )
On one hand, having accessor act on all elements seems most intuitive
and consistent with the current API. On the other hand, I can clearly
see a case when getting first value is much more convenient.
Considering that NodeList items can not be accessed via brackets,
wouldn't we end up with a somewhat verbose syntax?

$$('#sidebar #expandAll')[0].observe('click', function(){});

becomes:

$W('#sidebar #expandAll').source[0].observe('click', function(){});

Perhaps, if we give NodeList a `first` method, it will make things a
little less cryptic:

$W('#sidebar #expandAll').first().observe('click', function(){});


  1) NodeWrapper always exposes a public `source` property, which is a
  reference to a wrapped element:

 3. Still don't like source.  That word is just way too overloaded,
 and again, it's as much a target (e.g., of an update() call) as a
 source.  raw is the best general term I've thought of, but I'm not
 married to it.  Whatever we use should be *short* (so not
 wrappedThingamajig) and as clear as feasible.  Maybe we should give

I really like `source` but let's keep the naming aside for now : )

 up on the generic term (I *know* it was my idea, but...) and just use
 something meaningful for each wrapper, e.g. NodeWrapper.node,
 ListWrapper.list, etc.  Keep 'em short, document 'em, and if people
 forget what the property for the wrapped thingy inside a
 NodeListWrapper is, too bad, at least the terms are short and clear.

 4. get() and set() methods:  Great to have them, but I think it's
 important that we not expect/require that people _use_ them.  We're
 not, right?  I don't want to make a function call to access tagName,
 I'll want to use wrapper.source.tagName (or wrapper.raw.tagName)
 without the wrapper getting confused somehow.

Sure. We should recommend using them wisely and whenever it makes
sense.


 5. How will the list wrapper handle indexing into the list?  E.g.:

     var items;
     var n;
     items = $$('div.item');
     for (n = 0; n  items.length; ++n)
     {
         items[n].update('This is item ' + n);
     }

 I'm not aware of a standard, widely-supported JavaScript feature that
 lets us define the subscript operator, so I'm guessing the above is
 out.  Again I hate to introduce a function call for simple access
 [e.g., list.item(n), a'la Microsoft collections], so would I go to the
 underlying raw/source?

each always passes index as a second argument to iterator function:

$$('div.item').each(function(node, n) {
  node.update('This is item ' + n);
});


 6. Question on $$():  I think the idea so far is that it returns a
 NodeListWrapper.  I'm guessing that that's a list of NodeWrappers
 around the results of the query, right?  So I could reliably rewrite
 my code above like this (I'll use 'source' rather than 'raw' here):

     var items;
     var list;
     var n;
     items = $$('div.item');
     list = items.source;
     for (n = 0; n  list.length; ++n)
     {
         list[n].update('This is item ' + n);
     }

 ...because although I'm accessing the raw list, it contains wrapped
 nodes.  Is that the idea?

Yep, `source` of NodeList is an array of `Node`s.

--
kangax
--~--~-~--~~~---~--~~
You 

[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread John-David Dalton


@T. J. Crowder take some time to look at the jQuery source, it might
help with the wrapper discussion.
I was not suggesting that $$() return a list in some cases and a
single item in others. I was saying that
getter/setter methods would execute on the first matched item.

In jQuery (jQuery syntax):
$('#footer') - returns a jQuery instance (in our case it would be a
NodeListWrapper);

If you example the object it looks like:
  NodeListWrapper[0] - div#footer (the html element)
  NodeListWrapper.length - 1
  NodeListWrapper.observe - method
  NodeListWrapper.toggle - method
  NodeListWrapper.each - method
  NodeListWrapper._each - method
  NodeListWrapper.show  - method
  NodeListWrapper.getValue - method
  NodeListWrapper.update - method

the jQuery object and thus our NodeListWrapper will mimic an array,
it has a length, and index properties.

When you call a getter method then it executes on the first matched
item
NodeListWrapper.getHeight - execute on the first matched element and
not iterate over the list
NodeListWrapper.getStyle   - execute on ...
NodeListWrapper.getDimensions() - ...
so $$W('#id').getHeight() - is the same as - $$W('#id')
[0].getHeight();

$$W('#id')[0] is an element in jQuery but if we wrap ours in  a
NodeWrapper too then
$$W('#id')[0] would be the NodeWrapper
$$W('#id')[0] instanceof NodeWrapper would be true.
$$W('#id')[0].raw() would be the element,

now we can talk about if thats too many wrappers or what not,
but I think the approach of $$(selector)method is a good one.

Now we could do this:
NodeWrapper.raw() - gives you the element;
NodeWrapper.raw(element) - sets the element;
and the internal var _raw is private;

so that by the rules above if Prototype were modified $$W - $$, $W -
$
$('id').raw() - the element
$$('#id').raw() - the element (its a getter/setter so it executes on
the first matched)

$$('.panels').hide();
$$('.panels:first').hide();

$('myPanel).raw().tagName
$('myPanel).get('tagName');

There would be no internal raw item for the NodeListWrapper because
like the jQuery object
its items are part of its indexed properties.

- JDD






--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread kangax

On Aug 21, 9:21 am, T.J. Crowder [EMAIL PROTECTED] wrote:
 Hiya,





   2. FWIW, it seems to me that calling an accessor on a list should
   return a list of the accessor results for each list element.  Always.
 ...

  This is tricky : )
  On one hand, having accessor act on all elements seems most intuitive
  and consistent with the current API. On the other hand, I can clearly
  see a case when getting first value is much more convenient.
  Considering that NodeList items can not be accessed via brackets,
  wouldn't we end up with a somewhat verbose syntax?

  $$('#sidebar #expandAll')[0].observe('click', function(){});

  becomes:

  $W('#sidebar #expandAll').source[0].observe('click', function(){});

 Maybe I'm not understanding the example; I'm not a CSS guru by any
 means.  To me that looks like you're selecting an element with the ID
 'expandAll' if and only if it exists within an element with the ID

Correct.

 'sidebar'.  If so, that seems like quite an edge case to me (wouldn't
 you know whether it was inside the sidebar?), but again, I think I
 probably just don't get it.

This happens anytime one needs to reference an element without id:

$$('[name='+prop+']')[0]; // get element by name
$$('tbody tr:first-child')[0]; // get first row of a table
$$('img[src^=data:image]')[0]; // get image with specified src
attribute

etc.


  Perhaps, if we give NodeList a `first` method, it will make things a
  little less cryptic:

 That sounds good.  But separately, if we think it's common to need to
 select a single element on the basis of a CSS selector, I'd suggest an
 explicit means of doing that (e.g., a separate function -- $$First()
 comes to mind) that returns a NodeWrapper (or undefined, of course)
 and is optimized for that operation -- specifically, it stops as soon
 as it's found one.  More readable, perhaps slightly faster.

Another global function? ; )




   3. Still don't like source.  That word is just way too overloaded,
 ...

  I really like `source` but let's keep the naming aside for now : )

 No problem.  But you know I'll come back to it. :-)

I know : )




   4. get() and set() methods:  Great to have them, but I think it's
   important that we not expect/require that people _use_ them.
 ...
  Sure. We should recommend using them wisely and whenever it makes
  sense.

 Good good, just checking.



   5. How will the list wrapper handle indexing into the list?  E.g.:

       var items;
       var n;
       items = $$('div.item');
       for (n = 0; n  items.length; ++n)
       {
           items[n].update('This is item ' + n);
       }
 ...

  each always passes index as a second argument to iterator function:

 I don't use each() unless I have a really good reason for the added
 overhead or I know I'm dealing with so few elements that the added
 overhead (dramatic, in IE's case) doesn't matter.  I don't want people
 to think I'm dissing each() and I don't want to start an each()
 conversation.  But it seems like people get so caught up in the
 coolness of this stuff they they forget that function calls have a
 cost, inline closures have an even higher cost.  each() is really cool
 and I love it, love the idea of it, love the expressiveness of it.
 And implementations are making progress.  But for now my default mode
 will continue to be boring old-fashioned for/next loops (backward if
 it doesn't matter and time is *really* of the essence) barring a
 strong reason to do something else.

JS1.7 introduces iterators but as of now they are of little use (in a
web environment) : /
If `each` is out of the question, then yes, your previous example
should be fine.




   6. Question on $$():  I think the idea so far is that it returns a
   NodeListWrapper.  I'm guessing that that's a list of NodeWrappers
   around the results of the query, right?
 ...
  Yep, `source` of NodeList is an array of `Node`s.

 Nodes?  Or NodeWrappers?

NodeWrappers.

--
kangax
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread T.J. Crowder

@JDD:

Thanks.  I understood your suggsetion about the accessors, I thought
I'd also (separately) seen a suggestion that $$() return a single
wrapped element when it only finds one, but I'm not immediately
finding what it was that made me thing that.  Sounds like we're all on
the same page wrt always returning a list.  Apologies for muddying the
waters there.

I disagree on the list applying accessors to only the first element.
From an API perspective I just don't see that it makes sense.  I'd
much rather see a first() method or property, or better yet (as I
suggested to kangax) an explicit means of saying give me the first
(and only the first) element that matches this CSS spec).  If I see
the code list.highlight(), I'm going to expect the highlight method
to be applied to the list, not to the first entry on the list.

 Now we could do this:
 NodeWrapper.raw() - gives you the element;
 NodeWrapper.raw(element) - sets the element;
 and the internal var _raw is private;

We'll be using the raw underlying item a LOT, the last thing we want
to do is make accessing it a function call.

 There would be no internal raw item for the NodeListWrapper because
 like the jQuery object
 its items are part of its indexed properties.

If it's not literally a wrapper, if it's a replacement, that's great
and it's certainly the simplest solution.  But we keep calling it a
wrapper, which is the only reason for the question about indexed
access.
--
T.J. Crowder
tj / crowder software /

On Aug 21, 3:44 pm, John-David Dalton [EMAIL PROTECTED]
wrote:
 @T. J. Crowder take some time to look at the jQuery source, it might
 help with the wrapper discussion.
 I was not suggesting that $$() return a list in some cases and a
 single item in others. I was saying that
 getter/setter methods would execute on the first matched item.

 In jQuery (jQuery syntax):
 $('#footer') - returns a jQuery instance (in our case it would be a
 NodeListWrapper);

 If you example the object it looks like:
   NodeListWrapper[0] - div#footer (the html element)
   NodeListWrapper.length - 1
   NodeListWrapper.observe - method
   NodeListWrapper.toggle - method
   NodeListWrapper.each - method
   NodeListWrapper._each - method
   NodeListWrapper.show  - method
   NodeListWrapper.getValue - method
   NodeListWrapper.update - method

 the jQuery object and thus our NodeListWrapper will mimic an array,
 it has a length, and index properties.

 When you call a getter method then it executes on the first matched
 item
 NodeListWrapper.getHeight - execute on the first matched element and
 not iterate over the list
 NodeListWrapper.getStyle   - execute on ...
 NodeListWrapper.getDimensions() - ...
 so $$W('#id').getHeight() - is the same as - $$W('#id')
 [0].getHeight();

 $$W('#id')[0] is an element in jQuery but if we wrap ours in  a
 NodeWrapper too then
 $$W('#id')[0] would be the NodeWrapper
 $$W('#id')[0] instanceof NodeWrapper would be true.
 $$W('#id')[0].raw() would be the element,

 now we can talk about if thats too many wrappers or what not,
 but I think the approach of $$(selector)method is a good one.

 Now we could do this:
 NodeWrapper.raw() - gives you the element;
 NodeWrapper.raw(element) - sets the element;
 and the internal var _raw is private;

 so that by the rules above if Prototype were modified $$W - $$, $W -
 $
 $('id').raw() - the element
 $$('#id').raw() - the element (its a getter/setter so it executes on
 the first matched)

 $$('.panels').hide();
 $$('.panels:first').hide();

 $('myPanel).raw().tagName
 $('myPanel).get('tagName');

 There would be no internal raw item for the NodeListWrapper because
 like the jQuery object
 its items are part of its indexed properties.

 - JDD
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread Ryan Gahl
I like the wrapper tack (same way Ext does it). .raw doesn't sound intuitive
to me though. Why not just use .dom for the underlying element (also like
Ext)? Or .el? .raw just doesn't make for a beautiful API, IMHO :)

And no, don't make it a function call.


On Thu, Aug 21, 2008 at 10:41 AM, T.J. Crowder [EMAIL PROTECTED]wrote:


 @JDD:

 Thanks.  I understood your suggsetion about the accessors, I thought
 I'd also (separately) seen a suggestion that $$() return a single
 wrapped element when it only finds one, but I'm not immediately
 finding what it was that made me thing that.  Sounds like we're all on
 the same page wrt always returning a list.  Apologies for muddying the
 waters there.

 I disagree on the list applying accessors to only the first element.
 From an API perspective I just don't see that it makes sense.  I'd
 much rather see a first() method or property, or better yet (as I
 suggested to kangax) an explicit means of saying give me the first
 (and only the first) element that matches this CSS spec).  If I see
 the code list.highlight(), I'm going to expect the highlight method
 to be applied to the list, not to the first entry on the list.

  Now we could do this:
  NodeWrapper.raw() - gives you the element;
  NodeWrapper.raw(element) - sets the element;
  and the internal var _raw is private;

 We'll be using the raw underlying item a LOT, the last thing we want
 to do is make accessing it a function call.

  There would be no internal raw item for the NodeListWrapper because
  like the jQuery object
  its items are part of its indexed properties.

 If it's not literally a wrapper, if it's a replacement, that's great
 and it's certainly the simplest solution.  But we keep calling it a
 wrapper, which is the only reason for the question about indexed
 access.
 --
 T.J. Crowder
 tj / crowder software /

 On Aug 21, 3:44 pm, John-David Dalton [EMAIL PROTECTED]
 wrote:
  @T. J. Crowder take some time to look at the jQuery source, it might
  help with the wrapper discussion.
  I was not suggesting that $$() return a list in some cases and a
  single item in others. I was saying that
  getter/setter methods would execute on the first matched item.
 
  In jQuery (jQuery syntax):
  $('#footer') - returns a jQuery instance (in our case it would be a
  NodeListWrapper);
 
  If you example the object it looks like:
NodeListWrapper[0] - div#footer (the html element)
NodeListWrapper.length - 1
NodeListWrapper.observe - method
NodeListWrapper.toggle - method
NodeListWrapper.each - method
NodeListWrapper._each - method
NodeListWrapper.show  - method
NodeListWrapper.getValue - method
NodeListWrapper.update - method
 
  the jQuery object and thus our NodeListWrapper will mimic an array,
  it has a length, and index properties.
 
  When you call a getter method then it executes on the first matched
  item
  NodeListWrapper.getHeight - execute on the first matched element and
  not iterate over the list
  NodeListWrapper.getStyle   - execute on ...
  NodeListWrapper.getDimensions() - ...
  so $$W('#id').getHeight() - is the same as - $$W('#id')
  [0].getHeight();
 
  $$W('#id')[0] is an element in jQuery but if we wrap ours in  a
  NodeWrapper too then
  $$W('#id')[0] would be the NodeWrapper
  $$W('#id')[0] instanceof NodeWrapper would be true.
  $$W('#id')[0].raw() would be the element,
 
  now we can talk about if thats too many wrappers or what not,
  but I think the approach of $$(selector)method is a good one.
 
  Now we could do this:
  NodeWrapper.raw() - gives you the element;
  NodeWrapper.raw(element) - sets the element;
  and the internal var _raw is private;
 
  so that by the rules above if Prototype were modified $$W - $$, $W -
  $
  $('id').raw() - the element
  $$('#id').raw() - the element (its a getter/setter so it executes on
  the first matched)
 
  $$('.panels').hide();
  $$('.panels:first').hide();
 
  $('myPanel).raw().tagName
  $('myPanel).get('tagName');
 
  There would be no internal raw item for the NodeListWrapper because
  like the jQuery object
  its items are part of its indexed properties.
 
  - JDD
 



-- 
Ryan Gahl
Manager, Senior Software Engineer
Nth Penguin, LLC
http://www.nthpenguin.com
--
WebWidgetry.com / MashupStudio.com
Future Home of the World's First Complete Web Platform
--
Inquire: 1-920-574-2218
Blog: http://www.someElement.com
LinkedIn Profile: http://www.linkedin.com/in/ryangahl

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread darrin



 I disagree on the list applying accessors to only the first element.
 From an API perspective I just don't see that it makes sense.  I'd
 much rather see a first() method or property, or better yet (as I
 suggested to kangax) an explicit means of saying give me the first
 (and only the first) element that matches this CSS spec).  If I see
 the code list.highlight(), I'm going to expect the highlight method
 to be applied to the list, not to the first entry on the list.


I agree with that disagreement. Although it shortens up the syntax, to
me it's counter intuitive for a list to operate on the first element
for item related functions.

Darrin
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread T.J. Crowder

 This happens anytime one needs to reference an element without id:

 $$('[name='+prop+']')[0]; // get element by name
 $$('tbody tr:first-child')[0]; // get first row of a table
 $$('img[src^=data:image]')[0]; // get image with specified src
 attribute

Sure, that makes much more sense to me than '#sidebar #expandAll'.

  ...But separately, if we think it's common to need to
  select a single element on the basis of a CSS selector, I'd suggest an
  explicit means of doing that (e.g., a separate function -- $$First()
  comes to mind)...

 Another global function? ; )

Nah, we're namepsacing it, remember? ;-)  Seriously, though, if it's
common to need to select a single element not by ID and act on it,
let's make that an explicit and efficient thing, rather than bending
the API of the node list thingy to suit the case of only *really*
wanting the first element.  Doesn't matter (much) whether it's another
top-level function (although please, not literally with the name $
$First() -- blech) or an extension to something else (although I'd
leave $() -- which is otherwise very tempting -- lean and mean),
whatever.  But using $$() to go get a single element seems wasteful to
me, it'll continue its recursive descent even after it has what you
want, and then it goes and puts a list around it, all to be thrown
away because you're just going to use the first element anyway.

FWIW.

-- T.J. :-)

On Aug 21, 3:45 pm, kangax [EMAIL PROTECTED] wrote:
 On Aug 21, 9:21 am, T.J. Crowder [EMAIL PROTECTED] wrote:



  Hiya,

2. FWIW, it seems to me that calling an accessor on a list should
return a list of the accessor results for each list element.  Always.
  ...

   This is tricky : )
   On one hand, having accessor act on all elements seems most intuitive
   and consistent with the current API. On the other hand, I can clearly
   see a case when getting first value is much more convenient.
   Considering that NodeList items can not be accessed via brackets,
   wouldn't we end up with a somewhat verbose syntax?

   $$('#sidebar #expandAll')[0].observe('click', function(){});

   becomes:

   $W('#sidebar #expandAll').source[0].observe('click', function(){});

  Maybe I'm not understanding the example; I'm not a CSS guru by any
  means.  To me that looks like you're selecting an element with the ID
  'expandAll' if and only if it exists within an element with the ID

 Correct.

  'sidebar'.  If so, that seems like quite an edge case to me (wouldn't
  you know whether it was inside the sidebar?), but again, I think I
  probably just don't get it.

 This happens anytime one needs to reference an element without id:

 $$('[name='+prop+']')[0]; // get element by name
 $$('tbody tr:first-child')[0]; // get first row of a table
 $$('img[src^=data:image]')[0]; // get image with specified src
 attribute

 etc.



   Perhaps, if we give NodeList a `first` method, it will make things a
   little less cryptic:

  That sounds good.  But separately, if we think it's common to need to
  select a single element on the basis of a CSS selector, I'd suggest an
  explicit means of doing that (e.g., a separate function -- $$First()
  comes to mind) that returns a NodeWrapper (or undefined, of course)
  and is optimized for that operation -- specifically, it stops as soon
  as it's found one.  More readable, perhaps slightly faster.

 Another global function? ; )



3. Still don't like source.  That word is just way too overloaded,
  ...

   I really like `source` but let's keep the naming aside for now : )

  No problem.  But you know I'll come back to it. :-)

 I know : )





4. get() and set() methods:  Great to have them, but I think it's
important that we not expect/require that people _use_ them.
  ...
   Sure. We should recommend using them wisely and whenever it makes
   sense.

  Good good, just checking.

5. How will the list wrapper handle indexing into the list?  E.g.:

    var items;
    var n;
    items = $$('div.item');
    for (n = 0; n  items.length; ++n)
    {
        items[n].update('This is item ' + n);
    }
  ...

   each always passes index as a second argument to iterator function:

  I don't use each() unless I have a really good reason for the added
  overhead or I know I'm dealing with so few elements that the added
  overhead (dramatic, in IE's case) doesn't matter.  I don't want people
  to think I'm dissing each() and I don't want to start an each()
  conversation.  But it seems like people get so caught up in the
  coolness of this stuff they they forget that function calls have a
  cost, inline closures have an even higher cost.  each() is really cool
  and I love it, love the idea of it, love the expressiveness of it.
  And implementations are making progress.  But for now my default mode
  will continue to be boring old-fashioned for/next loops (backward if
  it doesn't matter and time is *really* of the essence) barring a
  strong reason to do something 

[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread kangax

On Aug 21, 10:44 am, John-David Dalton [EMAIL PROTECTED]
wrote:
 @T. J. Crowder take some time to look at the jQuery source, it might
 help with the wrapper discussion.
 I was not suggesting that $$() return a list in some cases and a
 single item in others. I was saying that
 getter/setter methods would execute on the first matched item.

 In jQuery (jQuery syntax):
 $('#footer') - returns a jQuery instance (in our case it would be a
 NodeListWrapper);

 If you example the object it looks like:
   NodeListWrapper[0] - div#footer (the html element)
   NodeListWrapper.length - 1
   NodeListWrapper.observe - method
   NodeListWrapper.toggle - method
   NodeListWrapper.each - method
   NodeListWrapper._each - method
   NodeListWrapper.show  - method
   NodeListWrapper.getValue - method
   NodeListWrapper.update - method

 the jQuery object and thus our NodeListWrapper will mimic an array,
 it has a length, and index properties.


Are we going to make `ListWrapper` pretend it's an array?
I agree that it's convenient to be able to access single elements of a
list with brackets, but wouldn't exposing all these properties break
the integrity/abstraction of a `ListWrapper`?

jQuery fills its instance with such properties and seems to adjust
`length` accordingly, but it's far from being an array:

var j = $('div');
j.length; // 14
j[14] = 'foo';
j.length; // 14 (not 15) - no magic length behavior obviously
j.push; // undefined
j.pop; // undefined
j.concat; // undefined

I think the only array-like method they have is `slice`.

--
kangax
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread John-David Dalton


// if source is a method
$$(css).source()  - equiv
$$(css)[0].source()  - equiv
$$(css).first().source() - equiv
you could always cache it
var source = $$(css).source();

// an array of sources
$$(css).invoke('source'); // OR
$$(css).each($$.source); //notice static $$.source method
$$(css)._each($$.source); // faster than all of them :P

if source is a property
//no soup for $$().method
$$(css)[0].source
$$(css).first().source
$$(css).pluck('source');

//get height of first matched item (equivs)
$$(css).first().getHeight(),
$$(css)[0].getHeight(), and
$$(css).getHeight() are equivs.

// array of heights (equivs)
$$(css).invoke('getHeight');
$$(css).each($$.getHeight);
$$(css)._each($$.getHeight);

//setters
$$(css).update(...); //sets all matched items
$$(css).setStyle(...) //sets all matched items
$$(css).addClassName(...) // does it to all matched items
$$(css).show().observer('click', ...); // shows all matches and
attached an onclick observer to all of them.

// get element by id
$(id).hide();
$(id).source() or $(id).source (whichever we decide)
$(id).source()._prototypeWrapperID //the id that the cache looks at
$(id).source()._prototypeWrapperID - [2]
// its an array with a number in it
because it wont transfer when you clone the node, this is how
its done in the current event system when element._prototypeEventID is
set.

We mod Class.create to allow the initialize method to return a value
so then:
Prototype.NodeWrapper = Class.create({
  initialize: function(...) {
// ...
if (Prototype.isWrapper(element)) { // some check for wrapper
  return element;
}

// ... resolve element from ID or whatnot

var cacheID = (element._prototypeWrapperID || [null])[0];
if (cacheID) {
  return Prototype.NodeWrapper.cache[cacheID];
}
   // set source, however that is decided on.
   this._source = element;
}, // ...
})

The reason we name it source instead of element or dom
is so we can always know what the source of a wrapper is without
having to guess if its an
Element wrapper to check for element if its an event wrapper to
check for .event.
we would know its always .source.

- JDD
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---



[Prototype-core] Re: Element wrapper draft notes

2008-08-21 Thread Ken Snyder

kangax wrote:
 ...
 Ken,

 I wanted to keep $W consistent with the rest of the library - be a
 simple shortcut for creating a new instance of NodeWrapper. Just like `
 $H` returns `new Hash` and $R returns `new ObjectRange`, $W should
 probably return `new NodeWrapper`. $W is also responsible for
 transforming string parameter into an actual element (via
 `document.getElementById`):

 ...
 this.$W = function(element) {
   if (typeof element == 'string') {
 element = document.getElementById(element);
   }
   return new Prototype.Node(element);
 };
 ...

 Using such proxy helper ($W) also ensures NodeWrapper is always
 called as a constructor. There are less chances that a user will
 mistakenly call `NodeWrapper` as a function and pollute the global
 scope. It, therefore, allows us to get rid of this instanceof
 Prototype.Node check:

 new Prototype.Node('foo'); // returns a wrapper
 Prototype.Node('foo'); // boom! returns undefined and creates a global
 `source`/`raw` property
   
That makes sense.  I was just thinking where it might be confusing that:

$W('foo') instanceof Prototype.Node; // true

but seeing it written out like that does make sense.
 Good point about passing a wrapper into a wrapper : ) Would it make
 sense to return a wrapper itself or a clone of it? Would there ever
 be a need for a cloned wrapper?
   
The only case I can think of is when there is an item in memory with the 
same id as one on the page. I don't know how we would handle that case.  
Maybe the caching system could handle that somehow.
 As far as caching, I'm afraid that storing reference to a wrapper on a
 node itself could lead to circular references (which as we know leak
 in IE's JScript). Having a separate cache-table and map elements to
 wrappers by an element's id (or a custom property of an element) seems
 more appropriate.
   
What about this caching idea: http://gist.github.com/6609

 I also think that #update, #insert, #replace, etc. should allow to
 accept a wrapper (besides an element or a string):

 $W('foo').insert($W('bar'));

 This should be as easy as giving wrapper `toElement`/`toHTML` methods
 (since `update`/`insert` delegate to those when available)
   
Definitely.
 --
 kangax
Ken Snyder

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Prototype: Core group.
To post to this group, send email to prototype-core@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/prototype-core?hl=en
-~--~~~~--~~--~--~---