Adding feature detection for :valid and :invalid CSS support. #718

Closed
wants to merge 1 commit into
from

Projects

None yet

5 participants

@ljharb

Adding feature detection for :valid and :invalid CSS selector support.

@ljharb

Tested in IE 9 and Safari 5.1 - got false, true as expected.

@sindresorhus sindresorhus and 1 other commented on an outdated diff Sep 30, 2012
feature-detects/css-valid.js
@@ -0,0 +1,17 @@
+// Support for :valid and :invalid CSS selectors
+// https://github.com/Modernizr/Modernizr/pull/718
+
+Modernizr.addTest(':valid', function () {
+ if (!document.querySelectorAll) { return false; }
+ if (!Modernizr.input.pattern) { return false; }
+ var frag = document.createDocumentFragment();
+ var input = document.createElement('input');
+ input.type = 'text';
+ input.pattern = '[0-9]+';
+ input.value = 'abc';
@sindresorhus
sindresorhus Sep 30, 2012

Weird indentation, use vertical space instead to group logic.

@ljharb
ljharb Sep 30, 2012

sorry, that's just a tabs/spaces thing. fixed.

@ljharb ljharb and 1 other commented on an outdated diff Sep 30, 2012
feature-detects/css-valid.js
@@ -0,0 +1,17 @@
+// Support for :valid and :invalid CSS selectors
+// https://github.com/Modernizr/Modernizr/pull/718
+
+Modernizr.addTest(':valid', function () {
+ if (!document.querySelectorAll) { return false; }
+ if (!Modernizr.input.pattern) { return false; }
@ljharb
ljharb Sep 30, 2012

I'm not sure how to force inclusion of the input tests. If its not available, should I return undefined, or can I include it somehow?

@ryanseddon
ryanseddon Sep 30, 2012

The builder right now will be updated to reflect any deps that a detect might have, in the future we'll be using AMD style modules. So don't worry about it now.

Also you should combine the above statement.

if (!document.querySelectorAll || !Modernizr.input.pattern) { 
    return false; 
}

Keep the formatting nice and readable too.

@ryanseddon ryanseddon commented on an outdated diff Sep 30, 2012
feature-detects/css-valid.js
@@ -0,0 +1,17 @@
+// Support for :valid and :invalid CSS selectors
+// https://github.com/Modernizr/Modernizr/pull/718
+
+Modernizr.addTest(':valid', function () {
@ryanseddon
ryanseddon Sep 30, 2012

I wouldn't name it :valid as this will need to be a class name too. Something like cssvalidation since you test both :valid and :invalid.

@ryanseddon ryanseddon commented on an outdated diff Sep 30, 2012
feature-detects/css-valid.js
@@ -0,0 +1,17 @@
+// Support for :valid and :invalid CSS selectors
+// https://github.com/Modernizr/Modernizr/pull/718
+
+Modernizr.addTest(':valid', function () {
+ if (!document.querySelectorAll) { return false; }
+ if (!Modernizr.input.pattern) { return false; }
+ var frag = document.createDocumentFragment();
+ var input = document.createElement('input');
+ input.type = 'text';
@ryanseddon
ryanseddon Sep 30, 2012

input will default to type text if no type is specified. Remove that line.

@ljharb ljharb referenced this pull request in jquery/jquery Oct 2, 2012
Closed

Add support indicator for CSS3 :valid pseudoselector #794

@aFarkas
Modernizr member

@ljharb

I'm not sure wether this feature detect adds any new information/data to Modernizr. From my knowledge all browsers, which have implemented Modernizr.input.pattern also have basic support for :invalid/:valid selectors. There might be some issues in existing browsers with :valid/:invalid/:required selectors, but those aren't tested. So could you please list some browsers including version number, which return true for Modernizr.input.pattern and false for your Modernizr.cssvalidation test?

Some other point: QSA should throw an error, if the selector isn't recognized. But I don't see any try catch, which guards against this error.

@ljharb

https://developer.mozilla.org/en-US/docs/HTML/Element/Input#pattern says that Chrome 5, Firefox 4, IE 10, Opera 9.6, and no Safari support "pattern" (although Modernizr.input.pattern returns true in Safari 5.1). However, https://developer.mozilla.org/en-US/docs/CSS/:invalid is supported in Chrome 10, Firefox 4, IE 10, Opera 10, and Safari 5.

I'm not sure which to trust at this point, but mdn implies that the support isn't the same.

I'll change it to require either "pattern" or "required" support, to make the test more reliable.

For querySelectorAll, in IE 8 (where qSA is supported, but :valid is not), qSA does indeed throw an error. So, at the least, I'll need to catch that error - I'll make that change now. However, that leads me to believe that perhaps the test could be as simple as (pseudocode) document.querySelectorAll && document.querySelectorAll(':valid').should_not_throw - however, as-is, the test actually verifies the functionality. Thoughts on which is better?

@aFarkas
Modernizr member

@ljharb

Your required addition doesn't really make your code better. Your provided support table doesn't make any difference between required and pattern support. So testing pattern || required doesn't make any difference to only test pattern. Indeed your code for required does never run in any browser and if it would, it would produce wrong results, because of this line (should have a value not be empty).

A simple test for invalid could look like this:

Modernizr.addTest('cssvalidation', function () {
    var bool = false;
    try {
        document.querySelector(':invalid');
        bool = true;
    } catch(e){}
    return bool;
});

Unfortunatley there is a bug in FF3.6 not throwing an error for :invalid/:valid/:required. You can guard against this bug by using Modernizr.input.pattern, which would change your test to this:

Modernizr.addTest('cssvalidation', function () {
    var bool = false;
    if(Modernizr.input.pattern){
        try {
            document.querySelector(':invalid');
            bool = true;
        } catch(e){}
    }
    return bool;
});

But I still don't see the additional information. pattern is a specific part of the constraint validation API and :invalid/:valid is the corresponding general CSS extension for the constraint validation API. For browser vendors it is usefull and logic to implement the general rules (i.e. checkValidity, validity, :invalid and so on) before implementing specific rules (i.e.: required, pattern, [type="email"]) for a given feature. Although sometimes browser vendors don't follow always those rules, in case of the HTML5 form API IE10 is the last browser implementing a portion of it and now we know, that the following test would be enough:

Modernizr.addTest('cssvalidation', Modernizr.input.pattern);
@patrickkettner
Modernizr member

@ljharb would you still be interested landing this?

I think you can pretty much crib the new :target test.

@patrickkettner
Modernizr member

ping @ljharb

@ljharb

Thanks @patrickkettner, I've updated this PR to include separate :valid and :invalid tests, copied from the :target test you linked to.

@patrickkettner
Modernizr member

great! now just have to test it out.

thanks again!

@patrickkettner
Modernizr member

So sorry this took forever, it fell off my plate and I didn't notice :[

So it looks good for all but firefox >=3.6 (false positive on both), and android 2.X gives a false positive on :valid support.

As a result, I think that we're gonna have to actually test some styles, similar to what we do in the generatedcontent detect.

First thought would be something like this.

@patrickkettner
Modernizr member

@ljharb were you still interested in this 'un?

@ljharb

Yes! Sorry, I haven't had time to take another look at it yet. I'll try to do that this week.

@ljharb

@patrickkettner Thanks!!!! I hadn't had time to do this myself, and I'm thrilled you took it on.

@patrickkettner
Modernizr member

my pleasure! cheers

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