diff --git a/feature-detects/css/animations.js b/feature-detects/css/animations.js index b379c8fe22..098d266bc6 100644 --- a/feature-detects/css/animations.js +++ b/feature-detects/css/animations.js @@ -13,5 +13,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('cssanimations', testAllProps('animationName')); + Modernizr.addTest('cssanimations', testAllProps('animationName', 'a', true)); }); diff --git a/feature-detects/css/backgroundposition-xy.js b/feature-detects/css/backgroundposition-xy.js index a979e7a048..ef7b376f2d 100644 --- a/feature-detects/css/backgroundposition-xy.js +++ b/feature-detects/css/backgroundposition-xy.js @@ -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); }); }); diff --git a/feature-detects/css/backgroundrepeat.js b/feature-detects/css/backgroundrepeat.js index f748c9eb49..8bf5ab563f 100644 --- a/feature-detects/css/backgroundrepeat.js +++ b/feature-detects/css/backgroundrepeat.js @@ -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')); }); diff --git a/feature-detects/css/backgroundsize.js b/feature-detects/css/backgroundsize.js index ae7634cc4b..3d490f21ae 100644 --- a/feature-detects/css/backgroundsize.js +++ b/feature-detects/css/backgroundsize.js @@ -11,5 +11,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('backgroundsize', testAllProps('backgroundSize')); + Modernizr.addTest('backgroundsize', testAllProps('backgroundSize', '100%', true)); }); diff --git a/feature-detects/css/backgroundsizecover.js b/feature-detects/css/backgroundsizecover.js index 65b035761f..7125f54f36 100644 --- a/feature-detects/css/backgroundsizecover.js +++ b/feature-detects/css/backgroundsizecover.js @@ -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')); }); diff --git a/feature-detects/css/borderimage.js b/feature-detects/css/borderimage.js index 8fa7429ed5..d86f6fe96f 100644 --- a/feature-detects/css/borderimage.js +++ b/feature-detects/css/borderimage.js @@ -8,5 +8,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('borderimage', testAllProps('borderImage')); + Modernizr.addTest('borderimage', testAllProps('borderImage', 'url() 1', true)); }); diff --git a/feature-detects/css/borderradius.js b/feature-detects/css/borderradius.js index fb16d9639f..a91598c570 100644 --- a/feature-detects/css/borderradius.js +++ b/feature-detects/css/borderradius.js @@ -12,5 +12,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('borderradius', testAllProps('borderRadius')); + Modernizr.addTest('borderradius', testAllProps('borderRadius', '0px', true)); }); diff --git a/feature-detects/css/boxshadow.js b/feature-detects/css/boxshadow.js index d83b323cbb..ad0f6a521f 100644 --- a/feature-detects/css/boxshadow.js +++ b/feature-detects/css/boxshadow.js @@ -8,5 +8,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('boxshadow', testAllProps('boxShadow')); + Modernizr.addTest('boxshadow', testAllProps('boxShadow', '1px 1px', true)); }); diff --git a/feature-detects/css/boxsizing.js b/feature-detects/css/boxsizing.js index 83a3b50623..415d50e515 100644 --- a/feature-detects/css/boxsizing.js +++ b/feature-detects/css/boxsizing.js @@ -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)); }); diff --git a/feature-detects/css/columns.js b/feature-detects/css/columns.js index 57476edc8a..e2a94f063a 100644 --- a/feature-detects/css/columns.js +++ b/feature-detects/css/columns.js @@ -8,5 +8,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('csscolumns', testAllProps('columnCount')); + Modernizr.addTest('csscolumns', testAllProps('columnCount', '1', true)); }); diff --git a/feature-detects/css/displayrunin.js b/feature-detects/css/displayrunin.js index 029756a192..035598be58 100644 --- a/feature-detects/css/displayrunin.js +++ b/feature-detects/css/displayrunin.js @@ -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'] }); }); diff --git a/feature-detects/css/hyphens.js b/feature-detects/css/hyphens.js index 5de406c252..bcfe838fb1 100644 --- a/feature-detects/css/hyphens.js +++ b/feature-detects/css/hyphens.js @@ -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 diff --git a/feature-detects/css/mask.js b/feature-detects/css/mask.js index d6f5e04331..9bc10d33f6 100644 --- a/feature-detects/css/mask.js +++ b/feature-detects/css/mask.js @@ -26,5 +26,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('cssmask', testAllProps('maskRepeat')); + Modernizr.addTest('cssmask', testAllProps('maskRepeat', 'repeat-x', true)); }); diff --git a/feature-detects/css/overflow-scrolling.js b/feature-detects/css/overflow-scrolling.js index c55c53016c..e169211f78 100644 --- a/feature-detects/css/overflow-scrolling.js +++ b/feature-detects/css/overflow-scrolling.js @@ -11,5 +11,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('overflowscrolling', testAllProps('overflowScrolling')); + Modernizr.addTest('overflowscrolling', testAllProps('overflowScrolling', 'touch', true)); }); diff --git a/feature-detects/css/reflections.js b/feature-detects/css/reflections.js index 38a689c3c0..c34c3ef7c5 100644 --- a/feature-detects/css/reflections.js +++ b/feature-detects/css/reflections.js @@ -7,5 +7,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('cssreflections', testAllProps('boxReflect')); + Modernizr.addTest('cssreflections', testAllProps('boxReflect', 'above', true)); }); diff --git a/feature-detects/css/resize.js b/feature-detects/css/resize.js index 58af90465d..82219ad07b 100644 --- a/feature-detects/css/resize.js +++ b/feature-detects/css/resize.js @@ -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)); }); diff --git a/feature-detects/css/shapes.js b/feature-detects/css/shapes.js index 3d60777672..06b7214881 100644 --- a/feature-detects/css/shapes.js +++ b/feature-detects/css/shapes.js @@ -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" }] } !*/ @@ -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)'; }); }); }); diff --git a/feature-detects/css/transforms.js b/feature-detects/css/transforms.js index c40e6693e6..83a4f4baa1 100644 --- a/feature-detects/css/transforms.js +++ b/feature-detects/css/transforms.js @@ -7,5 +7,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('csstransforms', !!testAllProps('transform')); + Modernizr.addTest('csstransforms', testAllProps('transform', 'scale(1)', true)); }); diff --git a/feature-detects/css/transforms3d.js b/feature-detects/css/transforms3d.js index 95de5f00fd..0c4f70c310 100644 --- a/feature-detects/css/transforms3d.js +++ b/feature-detects/css/transforms3d.js @@ -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 diff --git a/feature-detects/css/transitions.js b/feature-detects/css/transitions.js index 84c8dd02e1..ce4e9e31b2 100644 --- a/feature-detects/css/transitions.js +++ b/feature-detects/css/transitions.js @@ -7,5 +7,5 @@ } !*/ define(['Modernizr', 'testAllProps'], function( Modernizr, testAllProps ) { - Modernizr.addTest('csstransitions', testAllProps('transition')); + Modernizr.addTest('csstransitions', testAllProps('transition', 'all', true)); }); diff --git a/feature-detects/css/userselect.js b/feature-detects/css/userselect.js index c1ac87b3e0..aab7c49ad0 100644 --- a/feature-detects/css/userselect.js +++ b/feature-detects/css/userselect.js @@ -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)); }); diff --git a/feature-detects/css/wrapflow.js b/feature-detects/css/wrapflow.js index cd005c745b..c1c5558aaa 100644 --- a/feature-detects/css/wrapflow.js +++ b/feature-detects/css/wrapflow.js @@ -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) diff --git a/src/domToHyphenated.js b/src/domToHyphenated.js new file mode 100644 index 0000000000..318f5f6b5a --- /dev/null +++ b/src/domToHyphenated.js @@ -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; +}); diff --git a/src/nativeTestProps.js b/src/nativeTestProps.js new file mode 100644 index 0000000000..c7c4354f39 --- /dev/null +++ b/src/nativeTestProps.js @@ -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; +}); diff --git a/src/testAllProps.js b/src/testAllProps.js index e549272e8a..501c0a7b75 100644 --- a/src/testAllProps.js +++ b/src/testAllProps.js @@ -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 + * + * @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; }); diff --git a/src/testProp.js b/src/testProp.js index 70a7294e0a..f281664f5a 100644 --- a/src/testProp.js +++ b/src/testProp.js @@ -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; }); diff --git a/src/testProps.js b/src/testProps.js index cdfc305c28..1d0cc3ca33 100644 --- a/src/testProps.js +++ b/src/testProps.js @@ -1,4 +1,4 @@ -define(['contains', 'mStyle', 'createElement'], function( contains, mStyle, createElement ) { +define(['contains', 'mStyle', 'createElement', 'nativeTestProps', 'is'], function( contains, mStyle, createElement, nativeTestProps, is ) { // testProps is a generic CSS / DOM property test. // In testing support for a given CSS property, it's legit to test: @@ -17,8 +17,19 @@ define(['contains', 'mStyle', 'createElement'], function( contains, mStyle, crea // developing in WebKit or IE first don't end up with // browser-specific content by accident. - function testProps( props, prefixed ) { - var afterInit; + function testProps( props, prefixed, value, skipValueTest ) { + skipValueTest = is(skipValueTest, 'undefined') ? false : skipValueTest; + + // Try native detect first + if (!is(value, 'undefined')) { + var result = nativeTestProps(props, value); + if(!is(result, 'undefined')) { + return result; + } + } + + // Otherwise do it properly + var afterInit, i, j, prop, before; // If we don't have a style element, that means // we're running async or after the core tests, @@ -38,11 +49,38 @@ define(['contains', 'mStyle', 'createElement'], function( contains, mStyle, crea } } - for ( var i in props ) { - var prop = props[i]; + for ( i in props ) { + prop = props[i]; + before = mStyle.style[prop]; + if ( !contains(prop, "-") && mStyle.style[prop] !== undefined ) { - cleanElems(); - return prefixed == 'pfx' ? prop : true; + + // If value to test has been passed in, do a set-and-check test. + // 0 (integer) is a valid property value, so check that `value` isn't + // undefined, rather than just checking it's truthy. + if (!skipValueTest && !is(value, 'undefined')) { + + // Needs a try catch block because of old IE. This is slow, but will + // be avoided in most cases because `skipValueTest` will be used. + try { + mStyle.style[prop] = value; + } catch (e) {} + + // If the property value has changed, we assume the value used is + // supported. If `value` is empty string, it'll fail here (because + // it hasn't changed), which matches how browsers have implemented + // CSS.supports() + if (mStyle.style[prop] != before) { + cleanElems(); + return prefixed == 'pfx' ? prop : true; + } + } + // Otherwise just return true, or the property name if this is a + // `prefixed()` call + else { + cleanElems(); + return prefixed == 'pfx' ? prop : true; + } } } cleanElems(); diff --git a/src/testPropsAll.js b/src/testPropsAll.js index beed1026dd..b237f5b41c 100644 --- a/src/testPropsAll.js +++ b/src/testPropsAll.js @@ -1,31 +1,31 @@ -define(['ModernizrProto', 'cssomPrefixes', 'is', 'testProps', 'domPrefixes', 'testDOMProps'], function( ModernizrProto, cssomPrefixes, is, testProps, domPrefixes, testDOMProps ) { - /** - * testPropsAll tests a list of DOM properties we want to check against. - * We specify literally ALL possible (known and/or likely) properties on - * the element including the non-vendor prefixed one, for forward- - * compatibility. - */ - function testPropsAll( prop, prefixed, elem ) { +define(['ModernizrProto', 'cssomPrefixes', 'is', 'testProps', 'domPrefixes', 'testDOMProps', 'prefixes'], function( ModernizrProto, cssomPrefixes, is, testProps, domPrefixes, testDOMProps, prefixes ) { + /** + * testPropsAll tests a list of DOM properties we want to check against. + * We specify literally ALL possible (known and/or likely) properties on + * the element including the non-vendor prefixed one, for forward- + * compatibility. + */ + function testPropsAll( prop, prefixed, elem, value, skipValueTest ) { - var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), - props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); + var ucProp = prop.charAt(0).toUpperCase() + prop.slice(1), + props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); - // did they call .prefixed('boxSizing') or are we just testing a prop? - if(is(prefixed, "string") || is(prefixed, "undefined")) { - return testProps(props, prefixed); + // did they call .prefixed('boxSizing') or are we just testing a prop? + if(is(prefixed, "string") || is(prefixed, "undefined")) { + return testProps(props, prefixed, value, skipValueTest); - // otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) - } else { - props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); - return testDOMProps(props, prefixed, elem); + // otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) + } else { + props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); + return testDOMProps(props, prefixed, elem); + } } - } - // Modernizr.testAllProps() investigates whether a given style property, - // or any of its vendor-prefixed variants, is recognized - // Note that the property names must be provided in the camelCase variant. - // Modernizr.testAllProps('boxSizing') - ModernizrProto.testAllProps = testPropsAll; + // Modernizr.testAllProps() investigates whether a given style property, + // or any of its vendor-prefixed variants, is recognized + // Note that the property names must be provided in the camelCase variant. + // Modernizr.testAllProps('boxSizing') + ModernizrProto.testAllProps = testPropsAll; - return testPropsAll; + return testPropsAll; }); diff --git a/test/js/unit.js b/test/js/unit.js index 34f80699ed..d5a1ac4889 100644 --- a/test/js/unit.js +++ b/test/js/unit.js @@ -468,6 +468,17 @@ test('Modernizr.testProp()',function(){ Modernizr.testProp('pointerEvents'), 'results for `pointer-events` are consistent with a homegrown feature test'); + // Native detection tests + + equal(true, Modernizr.testProp('display'), 'Everyone supports display'); + equal(true, Modernizr.testProp('display', 'block'), 'Everyone supports display:block'); + equal(false, Modernizr.testProp('display', 'penguin'), 'Nobody supports display:penguin'); + + // This test is only relevant to browsers which *don't* support native detection + if (!(('CSS' in window && 'supports' in window.CSS) || 'CSSSupportsRule' in window)) { + equal(true, Modernizr.testProp('display', 'penguin', true), 'skipTestValue shouldn\'t value test without native detection'); + } + }); @@ -484,6 +495,17 @@ test('Modernizr.testAllProps()',function(){ equal(Modernizr.csscolumns, Modernizr.testAllProps('columnCount'), 'Modernizr result matches API result: csscolumns'); + // Native detection tests + + equal(true, Modernizr.testAllProps('display'), 'Everyone supports display'); + equal(true, Modernizr.testAllProps('display', 'block'), 'Everyone supports display:block'); + equal(false, Modernizr.testAllProps('display', 'penguin'), 'Nobody supports display:penguin'); + + // This test is only relevant to browsers which *don't* support native detection + if (!(('CSS' in window && 'supports' in window.CSS) || 'CSSSupportsRule' in window)) { + equal(true, Modernizr.testAllProps('display', 'penguin', true), 'skipTestValue shouldn\'t value test without native detection'); + } + });