Skip to content

Instantly share code, notes, and snippets.

@jackfuchs
Last active July 19, 2024 17:38
Show Gist options
  • Save jackfuchs/556448 to your computer and use it in GitHub Desktop.
Save jackfuchs/556448 to your computer and use it in GitHub Desktop.
Extends the jQuery.support object to CSS Properties
/**
* jQuery.support.cssProperty
* To verify that a CSS property is supported
* (or any of its browser-specific implementations)
*
* @param p css property name
* @param rp optional, if set to true, the css property name will be returned
* instead of a boolean support indicator
* @return {mixed}
*
* @author: Axel Jack Fuchs (Cologne, Germany)
* @date: 08-29-2010 18:43
* @url https://gist.github.com/jackfuchs/556448
*
* Example: $.support.cssProperty('boxShadow');
* Returns: true
*
* Example: $.support.cssProperty('boxShadow', true);
* Returns: 'MozBoxShadow' (On Firefox4 beta4)
* Returns: 'WebkitBoxShadow' (On Safari 5)
*/
$.support.cssProperty = (function() {
function cssProperty(p, rp) {
var b = document.body || document.documentElement,
s = b.style;
// No css support detected
if (typeof s == 'undefined') { return false; }
// Tests for standard prop
if (typeof s[p] == 'string') { return rp ? p : true; }
// Tests for vendor specific prop
var v = ['Moz', 'Webkit', 'Khtml', 'O', 'ms', 'Icab'],
p = p.charAt(0).toUpperCase() + p.substr(1),
vl = v.length;
for (var i=0; i<vl; i++) {
if (typeof s[v[i] + p] == 'string') { return rp ? (v[i] + p) : true; }
}
return false;
}
return cssProperty;
})();
@XavierBouhours
Copy link

/*
I do something equal to your work :
this build a $.support.css object with all properties
Xavier Bouhours
*/

(function($)
{
// Extend the jQuery.support with css3 normalized names.

// prevention
$.support = $.support ? $.support : {} ;

// store
$.support.css=  {};

// caller
$.supportCss =  function(key)
                {

                    // Method:
                    // $.support.getCss() => return $.support.css ;
                    // $.support.getCss().keyName Or $.support.getCss("keyName") => return $.support.css.keyName ;

                    // if propertie top exist, the $.support.css is yet built
                    if( $.support.css.top )
                    {
                        // if key exist we return the -navigator-key, else we return false.
                        if( key ) return $.support.css[key] ? $.support.css[key] : false ;
                        // if we have no key, just return the global object
                        return $.support.css ;
                    }

                    // build store
                    // Note: this function need the body tag to parse styles. So, we wait body is ready, before building the css properties.
                    var body ;
                    while( body=document.getElementsByTagName('body')[0] )
                    {

                        var

                        // Compile a single regex for memory leak
                        regex       =   new RegExp() ,
                        reg         =   function(a,b)
                                        {
                                            regex.compile(a,b) ;
                                            // We can't return directly the regex.compile in Safari.
                                            return regex ;
                                        },

                        cache       =   {},

                        // body     =   document.getElementsByTagName('body')[0] ,

                        camelcase   =   function(str)
                                        {
                                            return str
                                                    .toString().toLowerCase()
                                                    .replace( reg("^-"), "" )
                                                    //.replace( reg("^(khtml|moz|ms|o|webkit)-","i"),"" )
                                                    .replace( reg("(-)(\\w)?","g"), function(a,b,c){ return c ? c.toUpperCase() : '' ; })
                                                    .replace( reg("^moz"), "Moz" ) ;
                                                    //.replace( 'Webkit|', 'webkit' )
                                                    //.replace( 'Khtml', 'khtml' ) ; // not tested
                                        },

                        standard    =   function(s)
                                        {   // 'Moz', 'Webkit', 'Khtml', 'O', 'Ms'
                                            return s.replace( reg("^(khtml|Moz|ms|o|webkit)(\\w)"), function(a,b,c){ return c ? c.toLowerCase() : '' ; }) ;
                                        },

                        view        =   document.defaultView,

                        k,

                        cs,

                        v,

                        // http://github.com/zachstronaut/jquery-css-transform/blob/master/jquery-css-transform.js
                        addNormalized = function(prop)
                                        {
                                            var proxied = $.fn.css;
                                            $.fn.css = function (arg)
                                            {
                                                // Find the correct browser specific property and setup the mapping using
                                                // $.props which is used internally by jQuery.attr() when setting CSS
                                                // properties via either the css(name, value) or css(properties) method.
                                                // The problem with doing this once outside of css() method is that you
                                                // need a DOM node to find the right CSS property, and there is some risk
                                                // that somebody would call the css() method before body has loaded or any
                                                // DOM-is-ready events have fired.
                                                if
                                                (
                                                    typeof $.props[ prop ] == 'undefined'
                                                    &&
                                                    (
                                                        arg == prop
                                                        ||
                                                        (
                                                            typeof arg == 'object'
                                                            && typeof arg[prop] != 'undefined'
                                                        )
                                                    )
                                                )
                                                {
                                                    $.props[prop] = $.support.css[prop] ; //getTransformProperty(this.get(0));
                                                }

                                                // We force the property mapping here because jQuery.attr() does
                                                // property mapping with jQuery.props when setting a CSS property,
                                                // but curCSS() does *not* do property mapping when *getting* a
                                                // CSS property. (It probably should since it manually does it
                                                // for 'float' now anyway... but that'd require more testing.)
                                                if (arg == prop)
                                                {
                                                    arg = $.props[prop];
                                                }

                                                return proxied.apply(this, arguments);
                                            };
                                        } ;
                    // console.log( body.tagName );

                    // Opera // ie not tested
                    if ( body.currentStyle )
                    {
                        cs = body.currentStyle ;
                        for( k in cs ) if( typeof k === 'string' ) cache[ standard(k) ] = k ;
                    }

                    // Moz, Webkit
                    else if( view && view.getComputedStyle )
                    {
                        cs = view.getComputedStyle(body, "" ) || [] ;
                        for( k in cs )
                        {
                            if( reg("\\d").test(k) )
                                // console.log( cs[k]+ ': '+ standard( cs[k] ) +' -> '+ camelcase(cs[k]) ) ;
                                cache[ standard( camelcase(cs[k]) ) ] = camelcase(cs[k]) ;
                        }
                    } ;

                    // var ar = ['Transform','Transition','BoxShadow','BorderRadius','Column'] ; for( k in ar ) $.support[ 'css' + ar[k] ] = false ;

                    for( k in cache )
                    {

                        // Add generics names to jquery support
                        if( v = k.match( reg("transform|transition|boxShadow|borderRadius|column","i") ) )
                            $.support['css'+v[0].replace( reg("^.?"), function(a){ return a.charAt(0).toUpperCase()+a.substr(1); } )] = true ;

                        // jQuery prevention
                        // This add the normalized names to jQuery.css and jQuery.animate objects.
                        // It prevent for undefined keys
                        if( reg("^(khtml|moz|ms|o|webkit)[a-z-]*(background|box|border|color|col|margin|outline|padding|transform)","i").test( cache[k] ) )
                            addNormalized(k) ;

                        // Add to the main object
                        // $.support.css[k] = cache[k] ;

                    }
                    // for( k in ar ) console.log( ar[k] +': '+ $.support[ 'css' + ar[k] ] ) ;


                    // Add to the main object
                    $.support.css = cache ;

                    // Clear
                    regex = null ;
                    camelcase = standard = k = cs = v = addNormalized = reg = cache = null ;


                    // prevention
                    // $.support.css    =   _Css;
                    // $.support.getCss = _getCss ;

                    // incomplete transition
                    // https://developer.mozilla.org/en/CSS/CSS_transitions : "transitions aren't supported on CSS transforms."
                    // console.log( parseFloat($.browser.version) );
                    if( $.browser.mozilla && parseFloat($.browser.version) >= 3.9 && parseFloat($.browser.version) <= 4 ) $.support.cssTransition = 'incomplete' ;

                    // Ok
                    return $.support.css ;

                    }
                } ;
    // Init
    $.supportCss() ;        

})(jQuery);

@paulirish
Copy link

Ms -> ms

@gustavopaes
Copy link

Good work. I added a return false; too.

@hrieke
Copy link

hrieke commented Jul 19, 2024

License?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment