Skip to content

Commit

Permalink
Adding Modernizr.prefixedCSS() API
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit 508b8934dc86d9fa22f563081f6dae2b9b0dcca0
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Sun Mar 2 01:09:31 2014 +0000

    Updated comments in `prefixedCSS` to explain that it accepts either camelCase or kebab-case

commit 9ba6dfa96be800b1e668eac3978fb0c2494976d0
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Sun Mar 2 01:01:56 2014 +0000

    Removing duplicated/unused code and re-adding `cssToDOM()` (got lost in the rebase somewhere)

commit 0062bd8ade4f4ef08359040f0e4e01424c004f5b
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Sun Mar 2 00:39:29 2014 +0000

    Added tests for both camelCase and kebab-case inputs to Modernizr.prefixed and Modernizr.prefixedCSS

commit 87e7271a954095c17c10c9029832f443b1f60285
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Sat Mar 1 22:10:55 2014 +0000

    `Moderizr.prefixed()` and `Modernizr.prefixedCSS()` now accept properties in camelCase OR kebab-case

commit c1ccbc91c0e7837166d1677ab49c2ab2bffbef62
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Sat Mar 1 21:40:35 2014 +0000

    Changed `domToHyphenated` to `domToCSS` throughout the repo

commit 560a929ce9efc954fafd20eebbf46412c62221ed
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Sun Dec 1 21:26:36 2013 +0000

    Added tests for prefixedCSS()

commit dc0d27170afef838218562286c3b350ae39469b1
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Sun Dec 1 20:44:22 2013 +0000

    Added comment to prefixed() re. prefixedCSS()

commit 6e34fc143fea73200167c71588f89316b66475b4
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Sun Dec 1 20:42:37 2013 +0000

    Changed name of prefixedHyphenated to prefixedCSS

commit fb9f494f51e769bccf5455956c4239a7774e60be
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Tue Jul 16 18:28:59 2013 +0100

    Handled case of `prefixed()` returning false and added to `config-all.json`

commit 7748702dfe4a5158ab970a84cbc6ae4a9e7459fd
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Tue Jul 16 18:11:49 2013 +0100

    Added domToHyphenated dependency

commit 74b5b9a5e476c41ddd1dc9fbb1363c3b3783b6a7
Author: Stu Cox <stuart.cox@gmail.com>
Date:   Tue Jul 16 17:57:35 2013 +0100

    Added prefixedHyphenated function
  • Loading branch information
stucox committed Mar 2, 2014
1 parent 94fcd21 commit c4c60c1
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 47 deletions.
3 changes: 2 additions & 1 deletion lib/config-all.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"html5printshiv",
"load",
"testProp",
"fnBind"
"fnBind",
"prefixedCSS"
],
"feature-detects": [
"test/a/download",
Expand Down
10 changes: 10 additions & 0 deletions src/cssToDOM.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
define(function() {
// Helper function for converting kebab-case to camelCase,
// e.g. box-sizing -> boxSizing
function cssToDOM( name ) {
return name.replace(/([a-z])-([a-z])/g, function(str, m1, m2) {
return m1 + m2.toUpperCase();
}).replace(/^-/, '');
}
return cssToDOM;
});
7 changes: 4 additions & 3 deletions src/domToHyphenated.js → src/domToCSS.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
define(function() {
// Helper function for e.g. boxSizing -> box-sizing
function domToHyphenated( name ) {
// Helper function for converting camelCase to kebab-case,
// e.g. boxSizing -> box-sizing
function domToCSS( name ) {
return name.replace(/([A-Z])/g, function(str, m1) {
return '-' + m1.toLowerCase();
}).replace(/^ms-/, '-ms-');
}
return domToHyphenated;
return domToCSS;
});
6 changes: 3 additions & 3 deletions src/nativeTestProps.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
define(['injectElementWithStyles', 'domToHyphenated'], function ( injectElementWithStyles, domToHyphenated ) {
define(['injectElementWithStyles', 'domToCSS'], function ( injectElementWithStyles, domToCSS ) {
// Function to allow us to use native feature detection functionality if available.
// Accepts a list of property names and a single value
// Returns `undefined` if native detection not available
Expand All @@ -8,7 +8,7 @@ define(['injectElementWithStyles', 'domToHyphenated'], function ( injectElementW
if ('CSS' in window && 'supports' in window.CSS) {
// Try every prefixed variant of the property
while (i--) {
if (window.CSS.supports(domToHyphenated(props[i]), value)) {
if (window.CSS.supports(domToCSS(props[i]), value)) {
return true;
}
}
Expand All @@ -19,7 +19,7 @@ define(['injectElementWithStyles', 'domToHyphenated'], function ( injectElementW
// Build a condition string for every prefixed variant
var conditionText = [];
while (i--) {
conditionText.push('(' + domToHyphenated(props[i]) + ':' + value + ')');
conditionText.push('(' + domToCSS(props[i]) + ':' + value + ')');
}
conditionText = conditionText.join(' or ');
return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function( node ) {
Expand Down
12 changes: 7 additions & 5 deletions src/prefixed.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
define(['ModernizrProto', 'testPropsAll'], function( ModernizrProto, testPropsAll ) {
define(['ModernizrProto', 'testPropsAll', 'cssToDOM'], function( ModernizrProto, testPropsAll, cssToDOM ) {
// Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
// Modernizr.prefixed('boxSizing') // 'MozBoxSizing'

// Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
// Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
//
// str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
// Properties can be passed as DOM-style camelCase or CSS-style kebab-case.
// Return values will always be in camelCase; if you want kebab-case, use Modernizr.prefixedCSS().

// If you're trying to ascertain which transition end event to bind to, you might do something like...
//
Expand All @@ -17,6 +15,10 @@ define(['ModernizrProto', 'testPropsAll'], function( ModernizrProto, testPropsAl
// transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];

var prefixed = ModernizrProto.prefixed = function( prop, obj, elem ) {
// Convert kebab-case to camelCase
if (prop.indexOf('-') != -1) {
prop = cssToDOM(prop);
}
if (!obj) {
return testPropsAll(prop, 'pfx');
} else {
Expand Down
15 changes: 15 additions & 0 deletions src/prefixedCSS.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
define(['ModernizrProto', 'prefixed', 'domToCSS'], function( ModernizrProto, prefixed, domToCSS ) {
// Modernizr.prefixedCSS() is like Modernizr.prefixed(), but returns the result in
// hyphenated form, e.g.:
// Modernizr.prefixedCSS('transition') // '-moz-transition'

// It’s only suitable for style properties.

// Properties can be passed as DOM-style camelCase or CSS-style kebab-case.
// Return values will always be the hyphenated variant, or `false` if not supported
var prefixedCSS = ModernizrProto.prefixedCSS = function(prop) {
var prefixedProp = prefixed(prop);
return prefixedProp && domToCSS(prefixedProp);
};
return prefixedCSS;
});
102 changes: 67 additions & 35 deletions test/js/unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,42 +518,49 @@ test('Modernizr.testAllProps()',function(){
});


// Generic control function used for prefixed() and prefixedCSS() tests
// https://gist.github.com/523692
function gimmePrefix(prop, obj){
var prefixes = ['Moz','Khtml','Webkit','O','ms'],
domPrefixes = ['moz','khtml','webkit','o','ms'],
elem = document.createElement('div'),
upper = prop.charAt(0).toUpperCase() + prop.slice(1),
len;

if(!obj) {
if (prop in elem.style)
return prop;

for (len = prefixes.length; len--; ){
if ((prefixes[len] + upper) in elem.style)
return (prefixes[len] + upper);
}
} else {
if (prop in obj)
return prop;

for (len = domPrefixes.length; len--; ){
if ((domPrefixes[len] + upper) in obj)
return (domPrefixes[len] + upper);
}
}

return false;
}

// Feel bad using a copy-paste of this function to essentially test itself, but
// it should still help catch any future code changes which might break
// prefixedCSS
function domToCSS (name) {
return name.replace(/([A-Z])/g, function(str, m1) {
return '-' + m1.toLowerCase();
}).replace(/^ms-/, '-ms-');
}


test('Modernizr.prefixed() - css and DOM resolving', function(){
// https://gist.github.com/523692
var i,
len;
function gimmePrefix(prop, obj){
var prefixes = ['Moz','Khtml','Webkit','O','ms'],
domPrefixes = ['moz','khtml','webkit','o','ms'],
elem = document.createElement('div'),
upper = prop.charAt(0).toUpperCase() + prop.slice(1),
len;

if(!obj) {
if (prop in elem.style)
return prop;

for (len = prefixes.length; len--; ){
if ((prefixes[len] + upper) in elem.style)
return (prefixes[len] + upper);
}
} else {
if (prop in obj)
return prop;

for (len = domPrefixes.length; len--; ){
if ((domPrefixes[len] + upper) in obj)
return (domPrefixes[len] + upper);
}
}


return false;
}

var propArr = ['transition', 'backgroundSize', 'boxSizing', 'borderImage',
'borderRadius', 'boxShadow', 'columnCount'];
Expand All @@ -568,14 +575,17 @@ test('Modernizr.prefixed() - css and DOM resolving', function(){
equal(Modernizr.prefixed(prop), gimmePrefix(prop), 'results for ' + prop + ' match the homebaked prefix finder');
}

// Hyphenated versions of property names should return the same as camelCase
for (i = -1, len = propArr.length; ++i < len; ){
prop = domToCSS(propArr[i]);
equal(Modernizr.prefixed(prop), gimmePrefix(propArr[i]), 'results for ' + prop + ' match the homebaked prefix finder');
}

for (i = -1, len = domPropArr.length; ++i < len; ){
prop = domPropArr[i];
ok(!!~Modernizr.prefixed(prop.prop, prop.obj, false).toString().indexOf(gimmePrefix(prop.prop, prop.obj)), 'results for ' + prop.prop + ' match the homebaked prefix finder');
}




});


Expand Down Expand Up @@ -698,6 +708,28 @@ test('Modernizr.prefixed autobind', function(){
});





test('Modernizr.prefixedCSS', function () {
// Using different properties from Modernizr.prefixed, for the sake of
// variety
function testProp ( prop ) {
var prefixed = gimmePrefix(prop);
if (prefixed) {
equal(Modernizr.prefixedCSS(prop), domToCSS(prefixed), 'results for ' + prop + ' match the homebaked prefix finder');
}
else {
equal(Modernizr.prefixedCSS(prop), false, 'results for ' + prop + ' match the homebaked prefix finder');
}
}
testProp('animationProperty');
testProp('fontFeatureSettings');
testProp('flexWrap');
testProp('boxSizing');
testProp('textShadow');
testProp('resize');

testProp('animation-property');
testProp('font-feature-settings');
testProp('flex-wrap');
testProp('box-sizing');
testProp('text-shadow');
});

0 comments on commit c4c60c1

Please sign in to comment.