Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use CSS.supports() internally (fixes #818) #933

Merged
merged 7 commits into from
Aug 1, 2013
2 changes: 1 addition & 1 deletion feature-detects/css/animations.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('cssanimations', testAllProps('animationName'));
Modernizr.addTest('cssanimations', testAllProps('animationName', 'a', true));
});
11 changes: 3 additions & 8 deletions feature-detects/css/backgroundposition-xy.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@
}]
}
!*/
define(['Modernizr', 'testStyles'], function( Modernizr, testStyles ) {
Modernizr.addTest('bgpositionxy', function() {
return testStyles('#modernizr {background-position: 3px 5px;}', function( elem ) {
var cssStyleDeclaration = window.getComputedStyle ? getComputedStyle(elem, null) : elem.currentStyle;
var xSupport = (cssStyleDeclaration.backgroundPositionX == '3px') || (cssStyleDeclaration['background-position-x'] == '3px');
var ySupport = (cssStyleDeclaration.backgroundPositionY == '5px') || (cssStyleDeclaration['background-position-y'] == '5px');
return xSupport && ySupport;
});
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('bgpositionxy', function () {
return testAllProps('backgroundPositionX', '3px', true) && testAllProps('backgroundPositionY', '5px', true);
});
});
20 changes: 4 additions & 16 deletions feature-detects/css/backgroundrepeat.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,8 @@
}]
}
!*/
define(['Modernizr', 'testStyles'], function( Modernizr, testStyles ) {

function getBgRepeatValue( elem ) {
return (window.getComputedStyle ?
getComputedStyle(elem, null).getPropertyValue('background') :
elem.currentStyle['background']);
}

testStyles(' #modernizr { background-repeat: round; } ', function( elem, rule ) {
Modernizr.addTest('bgrepeatround', getBgRepeatValue(elem) == 'round');
});

testStyles(' #modernizr { background-repeat: space; } ', function( elem, rule ) {
Modernizr.addTest('bgrepeatspace', getBgRepeatValue(elem) == 'space');
});

define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
// Must value-test these
Modernizr.addTest('bgrepeatround', testAllProps('backgroundRepeat', 'round'));
Modernizr.addTest('bgrepeatspace', testAllProps('backgroundRepeat', 'space'));
});
2 changes: 1 addition & 1 deletion feature-detects/css/backgroundsize.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('backgroundsize', testAllProps('backgroundSize'));
Modernizr.addTest('backgroundsize', testAllProps('backgroundSize', '100%', true));
});
13 changes: 3 additions & 10 deletions feature-detects/css/backgroundsizecover.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@
}]
}
!*/
define(['Modernizr', 'testStyles'], function( Modernizr, testStyles ) {

testStyles('#modernizr{background-size:cover}', function( elem ) {
var style = window.getComputedStyle ?
window.getComputedStyle(elem, null)
: elem.currentStyle;

Modernizr.addTest('bgsizecover', style.backgroundSize == 'cover' );
});

define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
// Must test value, as this specifically tests the `cover` value
Modernizr.addTest('bgsizecover', testAllProps('backgroundSize', 'cover'));
});
2 changes: 1 addition & 1 deletion feature-detects/css/borderimage.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('borderimage', testAllProps('borderImage'));
Modernizr.addTest('borderimage', testAllProps('borderImage', 'url() 1', true));
});
2 changes: 1 addition & 1 deletion feature-detects/css/borderradius.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('borderradius', testAllProps('borderRadius'));
Modernizr.addTest('borderradius', testAllProps('borderRadius', '0px', true));
});
2 changes: 1 addition & 1 deletion feature-detects/css/boxshadow.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('boxshadow', testAllProps('boxShadow'));
Modernizr.addTest('boxshadow', testAllProps('boxShadow', '1px 1px', true));
});
2 changes: 1 addition & 1 deletion feature-detects/css/boxsizing.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('boxsizing', testAllProps('boxSizing') && (document.documentMode === undefined || document.documentMode > 7));
Modernizr.addTest('boxsizing', testAllProps('boxSizing', 'border-box', true) && (document.documentMode === undefined || document.documentMode > 7));
});
2 changes: 1 addition & 1 deletion feature-detects/css/columns.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('csscolumns', testAllProps('columnCount'));
Modernizr.addTest('csscolumns', testAllProps('columnCount', '1', true));
});
11 changes: 3 additions & 8 deletions feature-detects/css/displayrunin.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@
}]
}
!*/
define(['Modernizr', 'testStyles'], function( Modernizr, testStyles ) {
testStyles(' #modernizr { display: run-in; } ', function( elem, rule ) {
var ret = (window.getComputedStyle ?
getComputedStyle(elem, null).getPropertyValue('display') :
elem.currentStyle['display']);

Modernizr.addTest('displayrunin', ret == 'run-in', { aliases: ['display-runin'] });
});
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('displayrunin', testAllProps('display', 'run-in'),
{ aliases: ['display-runin'] });
});
2 changes: 1 addition & 1 deletion feature-detects/css/hyphens.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ define(['Modernizr', 'prefixes', 'createElement', 'testAllProps', 'addTest'], fu

addTest("csshyphens", function() {

if (!testAllProps('hyphens')) return false;
if (!testAllProps('hyphens', 'auto', true)) return false;

/* Chrome lies about its hyphens support so we need a more robust test
crbug.com/107111
Expand Down
2 changes: 1 addition & 1 deletion feature-detects/css/mask.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('cssmask', testAllProps('maskRepeat'));
Modernizr.addTest('cssmask', testAllProps('maskRepeat', 'repeat-x', true));
});
2 changes: 1 addition & 1 deletion feature-detects/css/overflow-scrolling.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('overflowscrolling', testAllProps('overflowScrolling'));
Modernizr.addTest('overflowscrolling', testAllProps('overflowScrolling', 'touch', true));
});
2 changes: 1 addition & 1 deletion feature-detects/css/reflections.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('cssreflections', testAllProps('boxReflect'));
Modernizr.addTest('cssreflections', testAllProps('boxReflect', 'above', true));
});
7 changes: 6 additions & 1 deletion feature-detects/css/resize.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
}]
}
!*/
/* DOC

Test for CSS 3 UI "resize" property

*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('cssresize', testAllProps('resize'));
Modernizr.addTest('cssresize', testAllProps('resize', 'both', true));
});
15 changes: 9 additions & 6 deletions feature-detects/css/shapes.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
"property": "shapes",
"tags": ["css"],
"notes": [{
"name": "Exclusions Spec",
"href": "http://www.w3.org/TR/css3-exclusions#shapes"
"name": "CSS Shapes W3C specification",
"href": "http://www.w3.org/TR/css-shapes"
},{
"name": "Example from Adobe",
"href": "http://html.adobe.com/webstandards/cssexclusions"
"name": "Examples from Adobe",
"href": "http://html.adobe.com/webplatform/layout/shapes"
}, {
"name": "Samples showcasing uses of Shapes",
"href": "http://codepen.io/collection/qFesk"
}]
}
!*/
Expand All @@ -22,10 +25,10 @@ define(['Modernizr', 'createElement', 'docElement', 'prefixed', 'testStyles'], f

var shapeInsideProperty = prefixedProperty.replace(/([A-Z])/g, function (str, m1) { return '-' + m1.toLowerCase(); }).replace(/^ms-/, '-ms-');

return testStyles('#modernizr { ' + shapeInsideProperty + ':rectangle(0,0,0,0) }', function (elem) {
return testStyles('#modernizr { ' + shapeInsideProperty + ':rectangle(0,0,0,0,0,0) }', function (elem) {
// Check against computed value
var styleObj = window.getComputedStyle ? getComputedStyle(elem, null) : elem.currentStyle;
return styleObj[prefixed('shapeInside', docElement.style, false)] == 'rectangle(0px, 0px, 0px, 0px)';
return styleObj[prefixed('shapeInside', docElement.style, false)] == 'rectangle(0px, 0px, 0px, 0px, 0px, 0px)';
});
});
});
2 changes: 1 addition & 1 deletion feature-detects/css/transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('csstransforms', !!testAllProps('transform'));
Modernizr.addTest('csstransforms', testAllProps('transform', 'scale(1)', true));
});
2 changes: 1 addition & 1 deletion feature-detects/css/transforms3d.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
!*/
define(['Modernizr', 'testAllProps', 'testStyles', 'docElement'], function( Modernizr, testAllProps, testStyles, docElement ) {
Modernizr.addTest('csstransforms3d', function() {
var ret = !!testAllProps('perspective');
var ret = !!testAllProps('perspective', '1px', true);

// Webkit's 3D transforms are passed off to the browser's own graphics renderer.
// It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
Expand Down
2 changes: 1 addition & 1 deletion feature-detects/css/transitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('csstransitions', testAllProps('transition'));
Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true));
});
3 changes: 2 additions & 1 deletion feature-detects/css/userselect.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
}
!*/
define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) {
Modernizr.addTest('userselect', testAllProps('userSelect'));
//https://github.com/Modernizr/Modernizr/issues/250
Modernizr.addTest('userselect', testAllProps('userSelect', 'none', true));
});
19 changes: 11 additions & 8 deletions feature-detects/css/wrapflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
"name": "CSS wrap-flow",
"property": "wrapflow",
"tags": ["css"],
"notes": [{
"name": "W3C Exclusions Spec",
"href": "http://www.w3.org/TR/css3-exclusions"
},{
"name": "Example by Adobe",
"href": "http://html.adobe.com/webstandards/cssexclusions"
}]
"notes": [
"This is a separate test from the rest of CSS Exclusions as as IE10 has just implemented this alone.",
{
"name": "W3C Exclusions spec",
"href": "http://www.w3.org/TR/css3-exclusions"
},
{
"name": "Example by Adobe",
"href": "http://html.adobe.com/webstandards/cssexclusions"
}
]
}
!*/
define(['Modernizr', 'prefixed', 'docElement', 'createElement'], function( Modernizr, prefixed, docElement, createElement ) {
// Separate test for `wrap-flow` property as IE10 has just implemented this alone
Modernizr.addTest('wrapflow', function () {
var prefixedProperty = prefixed('wrapFlow');
if (!prefixedProperty)
Expand Down
9 changes: 9 additions & 0 deletions src/domToHyphenated.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
define(function() {
// Helper function for e.g. boxSizing -> box-sizing
function domToHyphenated( name ) {
return name.replace(/([A-Z])/g, function(str, m1) {
return '-' + m1.toLowerCase();
}).replace(/^ms-/, '-ms-');
}
return domToHyphenated;
});
34 changes: 34 additions & 0 deletions src/nativeTestProps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
define(['injectElementWithStyles', 'domToHyphenated'], function ( injectElementWithStyles, domToHyphenated ) {
// 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
function nativeTestProps ( props, value ) {
var i = props.length;
// Start with the JS API: http://www.w3.org/TR/css3-conditional/#the-css-interface
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)) {
return true;
}
}
return false;
}
// Otherwise fall back to at-rule (for FF 17 and Opera 12.x)
else if ('CSSSupportsRule' in window) {
// Build a condition string for every prefixed variant
var conditionText = [];
while (i--) {
conditionText.push('(' + domToHyphenated(props[i]) + ':' + value + ')');
}
conditionText = conditionText.join(' or ');
return injectElementWithStyles('@supports (' + conditionText + ') { #modernizr { position: absolute; } }', function( node ) {
return (window.getComputedStyle ?
getComputedStyle(node, null) :
node.currentStyle)['position'] == 'absolute';
});
}
return undefined;
}
return nativeTestProps;
});
21 changes: 19 additions & 2 deletions src/testAllProps.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,21 @@
define(['ModernizrProto', 'testPropsAll'], function( ModernizrProto, testPropsAll ) {
var testAllProps = ModernizrProto.testAllProps = testPropsAll;
return testAllProps;
/**
* testAllProps determines whether a given CSS property, in some prefixed
* form, is supported by the browser. It can optionally be given a value; in
* which case testAllProps will only return true if the browser supports that
* value for the named property; this latter case will use native detection
* (via window.CSS.supports) if available. A boolean can be passed as a 3rd
* parameter to
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the end of the sentence seems missing

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha! I'll finish that off.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*
* @param prop - String naming the property to test
* @param value - [optional] String of the value to test
* @param skipValueTest - [optional] Whether to skip testing that the value
* is supported when using non-native detection
* (default: false)
*/
function testAllProps (prop, value, skipValueTest) {
return testPropsAll(prop, undefined, undefined, value, skipValueTest);
}
ModernizrProto.testAllProps = testAllProps;
return testAllProps;
});
8 changes: 5 additions & 3 deletions src/testProp.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
define(['ModernizrProto', 'testProps'], function( ModernizrProto, testProps ) {
define(['ModernizrProto', 'testProps', 'is'], function( ModernizrProto, testProps, is ) {
// Modernizr.testProp() investigates whether a given style property is recognized
// Note that the property names must be provided in the camelCase variant.
// Modernizr.testProp('pointerEvents')
var testProp = ModernizrProto.testProp = function( prop ) {
return testProps([prop]);
// Also accepts optional 2nd arg, of a value to use for native feature detection, e.g.:
// Modernizr.testProp('pointerEvents', 'none')
var testProp = ModernizrProto.testProp = function( prop, value, useValue ) {
return testProps([prop], undefined, value, useValue);
};
return testProp;
});
Loading