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
-~----------~----~----~----~------~----~------~--~---

Reply via email to