David - It'd be good to file a ticket on the issue and add in your patch and a link back to this discussion: http://dev.jquery.com/newticket
How well have you tested the change across browsers? Does changing .className to .getAttribute/setAttribute("class") have any other ramifications? It's definitely something that we can look in to for another release. --John On Sat, May 30, 2009 at 10:27 AM, David Baird <dhba...@gmail.com> wrote: > > Anyone have advice on how to proceed? > > The fundamental goal is to add support for selectors like this: > > $("#my-svg-element .my-class") // this currently won't work > > The reason this doesn't work right now is because jQuery's class name > selection relies on the .className member of the HTML DOM. The SVG > DOM also has .className, but it is of an incompatible type > ("SVGAnimatedString"). (This is explained in more detail in the > original post). > > I'm a newbie to jQuery development, so any pointers would be much > appreciated. > > Thanks in advance, > David > > On May 26, 11:01 pm, David Baird <dhba...@gmail.com> wrote: >> Overview of the problem: The HTML and SVG DOM extensions have >> differing interface definitions for "className". For the HTML DOM, >> className is a DOMString [1]. For SVG, className is defined as type >> SVGAnimatedString [2] (instead of good old DOMString) in SVGStylable >> [3]. (Furthermore, not all SVG elements inherit from SVGStylable - a >> fact which some Mozilla devs think is ridiculous, and I'd tend to >> agree, and they plan to add support for class everywhere in spite of >> the W3C recommendation [4]). To access the class value of an SVG >> element, you must call elem.className.baseVal (or elem.getAttribute >> ("class")). >> >> So, I'd like to tackle this problem as either a modification of jQuery >> or a plugin to jQuery. The following jQuery interfaces would need to >> be changed: >> >> - addClass/hasClass/removeClass/toggleClass >> >> - Selection: The Sizzle backend for allowing selection based on class >> would need to be changed a little >> >> Keith Wood has provided a jQuery plugin which solves part of this >> problem by creating a wrapper around addClass, et al. [5]. But his >> plugin doesn't address selection of SVG elements by class name (e.g. $ >> (".my-svg-class")). >> >> My question for the devs: is a modification to jQuery itself >> necessitated or can/should I factor this out into a separate plugin? >> It seems that I have to drill to the bottom layers of Sizzle, which >> makes me think a plugin is not ideal, and I would appreciate any >> suggestions. >> >> Here's a patch I came up with (alternatively, it should be available >> here for a month:http://pastebin.com/m24bdbbd9): >> >> --- jquery-1.3.2.js 2009-05-25 12:00:43.667854804 -0600 >> +++ jquery-1.3.2-modified-selectors.js 2009-05-26 22:52:33.748668152 >> -0600 >> @@ -707,27 +707,54 @@ >> }, >> >> className: { >> + >> + get: function( elem ) { >> + //var classNames = elem.className.baseVal || >> elem.className || >> elem.getAttribute("class"); >> + var classNames = elem.getAttribute("class"); >> + classNames = classNames ? classNames : ""; >> + return classNames >> + }, >> + >> + set: function( elem, value ) { >> + elem.setAttribute("class", value); >> + }, >> + >> + >> // internal only, use addClass("class") >> add: function( elem, classNames ) { >> jQuery.each((classNames || "").split(/\s+/), >> function(i, className) >> { >> - if ( elem.nodeType == 1 && >> !jQuery.className.has( elem.className, >> className ) ) >> - elem.className += (elem.className ? >> " " : "") + className; >> + var curClassName = >> jQuery.className.get(elem); >> + if ( elem.nodeType == 1 && >> !jQuery.className.has( curClassName, >> className ) ) >> + jQuery.className.set(elem, curClassName + >> (curClassName ? " " : >> "") + className); >> }); >> }, >> >> // internal only, use removeClass("class") >> remove: function( elem, classNames ) { >> if (elem.nodeType == 1) >> - elem.className = classNames !== undefined ? >> - >> jQuery.grep(elem.className.split(/\s+/), function(className){ >> + jQuery.className.set(elem, classNames !== >> undefined ? >> + >> jQuery.grep(jQuery.className.get(elem).split(/\s+/), function >> (className){ >> return >> !jQuery.className.has( classNames, className ); >> }).join(" ") : >> - ""; >> + "" >> + ); >> }, >> >> // internal only, use hasClass("class") >> has: function( elem, className ) { >> - return elem && jQuery.inArray( className, >> (elem.className || >> elem).toString().split(/\s+/) ) > -1; >> + var classNames = ""; >> + if (elem) >> + { >> + if (elem.getAttribute) >> + { >> + classNames = >> elem.jQuery.className.get(elem); >> + } >> + else >> + { >> + classNames = elem; >> // <-- ??? >> + } >> + } >> + return elem && jQuery.inArray( className, >> classNames.toString >> ().split(/\s+/) ) > -1; >> } >> }, >> >> @@ -1779,7 +1806,8 @@ >> >> for ( var i = 0, elem; (elem = curLoop[i]) != null; >> i++ ) { >> if ( elem ) { >> - if ( not ^ (elem.className && (" " + >> elem.className + " >> ").indexOf(match) >= 0) ) { >> + var className = >> jQuery.className.get(elem); >> + if ( not ^ (className && (" " + >> className + " ").indexOf(match)>= 0) ) { >> >> if ( !inplace ) >> result.push( elem ); >> } else if ( inplace ) { >> @@ -2005,7 +2033,8 @@ >> return (match === "*" && elem.nodeType === 1) || >> elem.nodeName === >> match; >> }, >> CLASS: function(elem, match){ >> - return (" " + (elem.className || >> elem.getAttribute("class")) + " >> ") >> + var className = jQuery.className.get(elem); >> + return (" " + (className) + " ") >> .indexOf( match ) > -1; >> }, >> ATTR: function(elem, match){ >> @@ -2207,7 +2236,7 @@ >> if ( div.querySelectorAll && div.querySelectorAll(".TEST").length >> === 0 ) { >> return; >> } >> - >> + >> Sizzle = function(query, context, extra, seed){ >> context = context || document; >> >> [1]http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-58190037 >> "Interface HTMLElement" >> [2]http://www.w3.org/TR/SVG/types.html#InterfaceSVGAnimatedString >> [3]http://www.w3.org/TR/SVG/types.html#InterfaceSVGStylable >> [4]https://developer.mozilla.org/en/SVG/Specification_Deviations >> [5]http://keith-wood.name/svg.html > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "jQuery Development" group. To post to this group, send email to jquery-dev@googlegroups.com To unsubscribe from this group, send email to jquery-dev+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/jquery-dev?hl=en -~----------~----~----~----~------~----~------~--~---