Ruby Forum Rails Spinoffs > $(element).select('[attr]') in IE selects attributes *and* methods?

Posted by Byron Young (Guest)
on 15.05.2008 00:46
(Received via mailing list)
Hi all,

I couldn't find anything about this on the list or the prototype docs
or google, so please excuse me if somebody has addressed this
somewhere.

I'm have some code like this:

    var toggleControllers = $A(form.select('*[show]'));

Which works great in FF - it selects all the items on the page with a
'show="something"' attribute.  But in IE it selects everything on the
page.  If i change the selector to *[anything-other-than-show], it
works properly.  I couldn't figure out why I was getting this behavior
until i dumped the contents of element.readAttribute('show') for each
result in toggleControllers.  This gives me:

    function() {
      return __method.apply(null, [this].concat($A(arguments)));
    };

So, it appears that the [attr] selector in IE also selects elements
with methods named 'attr'.  Or maybe I'm interpreting it wrong and
Prototype adds extended methods to elements as attributes, so maybe
XPath is doing the right thing?

Is there any way to avoid matching on methods like show() using the
[attr] selector?  Or do I need to just skip any where
Object.isFunction(el.readAttribute('attr')) is true?

Thanks,
Byron
Posted by kangax (Guest)
on 15.05.2008 02:45
(Received via mailing list)
That's quite a bummer, and we should probably "fix" it.
I wonder if regexp against outerHTML would do the trick.

- kangax
Posted by RobG (Guest)
on 15.05.2008 07:23
(Received via mailing list)
On May 15, 8:45 am, Byron Young <titus.byroni...@gmail.com> wrote:
> Which works great in FF - it selects all the items on the page with a
> 'show="something"' attribute.

It is not a good idea to use custom attributes on HTML elements, the
class attribute can provide similar functionality.


> So, it appears that the [attr] selector in IE also selects elements
> with methods named 'attr'.  Or maybe I'm interpreting it wrong and
> Prototype adds extended methods to elements as attributes,

Prototype.js adds methods to DOM elements in browsers like IE in every
function that accepts an element as an argument.


> so maybe
> XPath is doing the right thing?
>
> Is there any way to avoid matching on methods like show() using the
> [attr] selector?  Or do I need to just skip any where
> Object.isFunction(el.readAttribute('attr')) is true?

You also have the problem of masking DOM properties with HTML
attributes in those browsers where Prototype.js adds methods directly
to the DOM element (as it does for IE).

When using Prototype.js, do not use it's element method names as
attribute names on HTML elements, e.g.:

  <button onclick="$(this).hide()" hide="foo">Hide me?</button>

Does not hide the button in IE, since $(this).hide returns the string
"foo", not a reference to the hide method.  It is also possible that
some browsers will add HTML attributes as DOM properties where methods
have been added to the host HTML element prototype object and so may
be "shadowed" in browsers other than IE.

The issue you have discovered is used to argue against adding
properties to host objects, particluarly as a fundamental strategy of
a general purpose library.


--
Rob
Posted by Justin Perkins (Guest)
on 15.05.2008 08:03
(Received via mailing list)
On Thu, May 15, 2008 at 12:22 AM, RobG <rgqld@iinet.net.au> wrote:
> It is not a good idea to use custom attributes on HTML elements, the
> class attribute can provide similar functionality.

With all do respect, why? I have been using custom attributes for a
very long time and have never seen one single negative side effect.

-justin
Posted by RobG (Guest)
on 15.05.2008 13:38
(Received via mailing list)
On May 15, 4:02 pm, "Justin Perkins" <justinperk...@gmail.com> wrote:
> On Thu, May 15, 2008 at 12:22 AM, RobG <rg...@iinet.net.au> wrote:
> > It is not a good idea to use custom attributes on HTML elements, the
> > class attribute can provide similar functionality.
>
> With all do respect, why? I have been using custom attributes for a
> very long time and have never seen one single negative side effect.

User agents should ignore unrecognised attributes, but as the OP
discovered, their use can create problems in other ways.  In this
case, the addition of certain attribute names has interfered with
scripts, but they could just as easily cause problems by being
recognised by a particular browser as something other than what was
intended.  IE in particular has a heap of custom attributes.

The possibility of issues can be mitigated using a pseudo-namespace
(e.g. adding a prefix to all such attributes), however it can be
reduced to zero by using standard attributes such as class.


--
Rob
Posted by anthyon (Guest)
on 15.05.2008 14:43
(Received via mailing list)
well... i'm new to this group and correct me if i'm wrong, but...

by using the acronym HTML does that include XHTML?

if so than XHTML was designed to be eXtendable by third parties using
both own tags and attributes. And me myself use this advantage of
this, when eg. I have a small code that deals with specific attribute
pairs on different built-in tags, and implement some dynamism
independently of the page itself, using prototype.js' power. (Though i
have to admit, that I'm guilty of placing these attributes into the
xhtml namespace instead of my own one, but i'm already working on
it. :) )

If your terms of HTML does not include XHTML ( as i think the
situation is ), i haven't gone through the HTML5 specification, but in
the past though i could use my own attributes, i always had to be
aware of not using special ones ( and that's not so hard to achieve )

so all in all, i don't see a point why it should be avoided to use my
own attributes.

Anthyon

RobG írta:
Posted by Justin Perkins (Guest)
on 15.05.2008 16:56
(Received via mailing list)
On Thu, May 15, 2008 at 6:37 AM, RobG <rgqld@iinet.net.au> wrote:
> User agents should ignore unrecognised attributes, but as the OP
> discovered, their use can create problems in other ways.

Yes, that is a big risk. I meant to mention that in my last reply. If
you are aware of these risks when you are creating your custom
attributes, you are much more likely to create attribute names that
will likely never conflict with some browser custom attribute or
built-in method on a DOM element.

For the OP, 'attr' is clearly a bad choice, but all I would suggest is
prefix/suffix like 'foo_attr' as opposed to just not using them
altogether.

-justin
Posted by Byron Young (Guest)
on 15.05.2008 20:20
(Received via mailing list)
On May 15, 7:56 am, "Justin Perkins" <justinperk...@gmail.com> wrote:
> For the OP, 'attr' is clearly a bad choice, but all I would suggest is
> prefix/suffix like 'foo_attr' as opposed to just not using them
> altogether.

(accidentally replied directly to Justin.  here it is again:)

I was just using 'attr' as an example meaning 'any attribute'.  The
one I actually ran into trouble with was 'show', since Prototype
creates a show() method on every element, so everything was being
selected by the '*[show]' selector.  Using
Object.isFunction(el.readAttribute('show')) works to filter the
elements down to the ones I want, but it's a lame solution since I'm
effectively looping through every element on the form.

It's clear to me now that 'show' is a bad name for the attribute, for
the reasons pointed out by Rob and Justin.  But not using custom
attributes isn't a good solution for me, because I don't want to
include javascript on every element that should do something.  Instead
I'd rather be able to use css selector to get a list of the elements
that want to register themselves for certain events.  I'm using XHTML
strict mode, so it shouldn't be a problem for the browser.  It works
great in FF and IE, except for the caveats already discussed.

Thanks for your help Rob, Justin, Anthyon and Kangax

byron
Posted by Justin Perkins (Guest)
on 15.05.2008 20:53
(Received via mailing list)
On Thu, May 15, 2008 at 1:19 PM, Byron Young <titus.byronicus@gmail.com> 
wrote:
> I was just using 'attr' as an example meaning 'any attribute'.  The
> one I actually ran into trouble with was 'show',

Show is also a bad choice. Any short, single word is probably a bad 
choice.

I use custom attributes quite frequently, but they are always multiple
words separated by an underscore or dash, also, to access the
attribute value I *always* use
$('my-element').getAttribute('whatever-attribute') as opposed to just
$('my-element).whatever-attribute (which wouldn't work anyway).

-justin
Posted by Byron Young (Guest)
on 15.05.2008 22:58
(Received via mailing list)
On May 15, 11:52 am, "Justin Perkins" <justinperk...@gmail.com> wrote:
> $('my-element).whatever-attribute (which wouldn't work anyway).
I liked your suggestion of using a dash in the attribute name, so I
changed my attributes to 'show-container' and 'container-name', which
will avoid the problem of matching on an object method.

However, this caused the $(form).select('[show-container]') selector
to throw an error in FF.  Prototype didn't like me using a dash, and
instead of using the 'attrPresence' xpath selector it used 'attr',
because the 'attrPresence' pattern didn't include a dash but the
'attr' pattern did.

Here's a patch that fixes it for me (against the 1.6.0 release):

Index: prototype.js
===================================================================
--- prototype.js        (revision 11904)
+++ prototype.js        (working copy)
@@ -2962,7 +2962,7 @@
     id:           /^#([\w\-\*]+)(\b|$)/,
     className:    /^\.([\w\-\*]+)(\b|$)/,
     pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|
empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
-    attrPresence: /^\[([\w]+)\]/,
+    attrPresence: /^\[([\w-]+)\]/,
     attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])
([^\4]*?)\4|([^'"][^\]]*?)))?\]/
   },


byron
Posted by RobG (Guest)
on 16.05.2008 02:38
(Received via mailing list)
On May 15, 10:43 pm, anthyon <anth...@gmail.com> wrote:
> well... i'm new to this group and correct me if i'm wrong, but...
>
> by using the acronym HTML does that include XHTML?

For the purpose of this discussion, there is no difference between
HTML and XHTML.  In any case, the vast majority of XHMTL on the web is
served as HTML, even to those UAs that identify as being able to
handle XHTML, so the only relevant specification is HTML 4.01.

If you want a detailed discussion of HTML vs XHTML, search the
archives at comp.infosystems.www.authoring.html[1].  Don't jump in
with a general question as it has been asked many, many times before,
however feel free to ask about specific details if you've searched for
relevant threads and haven't found an answer.


> if so than XHTML was designed to be eXtendable by third parties using
> both own tags and attributes.

The purpose of XHTML 1.0 is to be HTML written to conform to XML
syntax (the specification is sub-titled "A Reformulation of HTML 4 in
XML 1.0").  The X does stand for "extensible", but is intended as a
reference XML, it does not infer that XHTML is extensible and HTML
isn't. There is nothing in the HTML 4 specification to prohibit custom
attributes, this is not an issue of conformance.


> And me myself use this advantage of
> this, when eg. I have a small code that deals with specific attribute
> pairs on different built-in tags, and implement some dynamism
> independently of the page itself, using prototype.js' power. (Though i
> have to admit, that I'm guilty of placing these attributes into the
> xhtml namespace instead of my own one, but i'm already working on
> it. :) )

"the XHTML namespace"?  One result of custom attributes is that your
document will not validate using a standard DTD, however that is of
little consequence provided it is valid otherwise.  You might consider
a custom DTD that includes your attributes, but I don't think any
browser in popular use (and probably no browser at all) will take any
notice of it.   A custom DTD may give you peace of mind, but in
practice it doesn't change anything.


> If your terms of HTML does not include XHTML ( as i think the
> situation is ), i haven't gone through the HTML5 specification,

HTML 5 is currently a working draft, it has not reached the status of
recommendation and likely wont for some time.  The section on element
attributes seems to be primarily concerned with clarifying the
relationship between element attributes and related DOM object
properties.  Whatever it says, it won't have any practical effect on
the web for quite some time (let's say 5 years) after it becomes a
recommendation.


> but in
> the past though i could use my own attributes, i always had to be
> aware of not using special ones ( and that's not so hard to achieve )

The issue is that you don't know all the special attributes of all the
UAs that may be parsing your pages.  Adding custom attributes to
elements is similar to the issue in scripting of adding properties to
the global object.


> so all in all, i don't see a point why it should be avoided to use my
> own attributes.

It is a matter of risk management.  There is a chance that your custom
attributes will cause conflict with proprietary browser custom
attributes.  The chance of conflict is relative to the number of
attributes introduced, the variety of user agents parsing your code
and the scripts that may be operating.

The risk can be mitigated using strategies such as prefixes (e.g. foo-
show="ByDefault"), but can be almost entirely avoided using standard
HTML attributes, e.g. class="foo-show&byDefault" or similar.

Ultimately it is your decision how you go about it, I have not doubt
that you will continue to use custom attributes.  Hopefully this
discussion provides enlightenment on issues and strategies to deal
with them.


1. Here are a couple of threads:
<URL:
http://groups.google.com.au/group/comp.infosystems.www.authoring.html/browse_frm/thread/f2f54a73906b8317/9b55d756557e1835?hl=en&lnk=gst&q=custom+attributes#9b55d756557e1835
>
<URL:
http://groups.google.com.au/group/comp.infosystems.www.authoring.html/browse_frm/thread/9a63384f3eceab4/ebc9bf5b71072106?hl=en&lnk=gst&q=custom+attributes#ebc9bf5b71072106
>


--
Rob