Repository: Modernizr/Modernizr
Pull request #2561 (2020-05-13 11:18:21)

Fill the documentation
Adds these new sections to the HOW_TO_WRITE_FEATURE_DETECTS.md:

- Polyfills
- Submitting a PR (simple)
- Testing
- Install the basics (simplistic)
- Multiple rephrases for better readability

It also reorders some files to follow alphabetical order. 

codecov[bot]: # [Codecov](https://codecov.io/gh/Modernizr/Modernizr/pull/2561?src=pr&el=h1) Report
> Merging [#2561](https://codecov.io/gh/Modernizr/Modernizr/pull/2561?src=pr&el=desc) into [master](https://codecov.io/gh/Modernizr/Modernizr/commit/59f35a14c5e63dab964dd25d2c10ffcbecbfb918&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/Modernizr/Modernizr/pull/2561/graphs/tree.svg?width=650&height=150&src=pr&token=pEqLyAS3IB)](https://codecov.io/gh/Modernizr/Modernizr/pull/2561?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #2561   +/-   ##
=======================================
  Coverage   95.15%   95.15%           
=======================================
  Files           5        5           
  Lines         165      165           
=======================================
  Hits          157      157           
  Misses          8        8           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/Modernizr/Modernizr/pull/2561?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Modernizr/Modernizr/pull/2561?src=pr&el=footer). Last update [59f35a1...4fd3e78](https://codecov.io/gh/Modernizr/Modernizr/pull/2561?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

MarkelFe: I'll soon solve the conflicts
MarkelFe: Okay merge conflicts solved, still there is a broken link link with the `Verify/Run your tests` (seems that Github Markdown parser doesn't like slashes but the url redirect yes, etc) so I'll probably will change the name in the next commit (I assume that some extra tweaking will be needed).
Also, the install the basics section doesn't end up convincing me :/

Patch:
diff --git a/HOW_TO_WRITE_FEATURE_DETECTS.md b/HOW_TO_WRITE_FEATURE_DETECTS.md
index b81c4a9a..e45707e0 100644
--- a/HOW_TO_WRITE_FEATURE_DETECTS.md
+++ b/HOW_TO_WRITE_FEATURE_DETECTS.md
@@ -1,14 +1,31 @@
 # How to Write Feature Detects
-The scope of this file is to help you to create new feature detects or edit existing ones. Here you will find details and guidelines that will help you understand how
-Modernizr works.
 
-#### Table of contents
+The scope of this file is to help you to create new feature detects or edit existing ones. Here you will find details and guidelines that will help you understand how Modernizr works. All these sections assume that you have npm, node and Modernizr downloaded. If that is not the case, check first the [Install the basics](#install-the-basics) section.
+
+## Table of contents
+
 [Metadata](#metadata)
 
+[Polyfills](#polyfills)
+
+[Submitting a PR](#submitting-a-pr)
+
+[Testing](#testing)
+
+* [General Testing](#general-testing)
+* [Caniuse Testing](#caniuse-testing)
+* [Verifying and Running Your Tests](#verifying-and-running-your-tests)
+
+[Install the Basics](#install-the-basics)
+
 ## Metadata
+
 A JSON fragment at the top of every feature detect in Modernizr represents the metadata of the test. This data is used, for example, to build the webpage.
-### Schema
+
+### Metadata Schema
+
 The following code represents an example of the schema (it does not represent a real test):
+
 ```json
 /*!
 {
@@ -36,20 +53,116 @@ The following code represents an example of the schema (it does not represent a
 Here it would go a description of the feature test. You can use **markdown** here :)
 */
 ```
+
 > Metadata does no need to appear in a set order, however, it is common to see `name` and `property` at the top while `notes` at the bottom.
 
-### Item description
-|                  | Necessity |                      Description                     |                                       Notes                                      |
-|------------------|:---------:|:----------------------------------------------------:|:--------------------------------------------------------------------------------:|
-| `name`           |  required |             Name of the feature detection            |                                                                                  |
-| `property`       |  required | The property name established in `Modernizr.addTest` |                   It must be lowercase, without any punctuation                  |
-| `tags`           |  optional |    A group that encapsulates many feature detects    |                                                                                  |
-| `caniuse`        |  optional |      A conversion table of caniuse and Modernizr     |      Consider adding it to [caniuse.js](test/browser/integration/caniuse.js)     |
-| `authors`        |  optional |          List of contributors of the script          |                                                                                  |
-| `builderAliases` |  optional |     Used by CI and the web when tests are renamed    |                         Should not be needed in new tests                        |
-| `polyfills`      |  optional |     Available polyfills for not working versions     | Any polyfill listed needs to be included in [polyfills.json](lib/polyfills.json) |
-| `aliases`        |  optional |   Used if a feature has more than a canonical name   |                             Legacy only - do not use                             |
-| `async`          |  optional |       If the test supports async functionality       |                                 Defaults to false                                |
-| `warnings`       |  optional |        Notes to the developer using the script       |                          Don't mistake it for knownBugs                          |
-| `knownBugs`      |  optional |  Bugs known of the test (e.g.: doesn't work in IE6)  |                                                                                  |
-| `notes`          |  optional |                  Links to resources                  |                                                                                  |
+### Metadata Item description
+
+|                  | Necessity |                      Description                     |                        Notes                        |
+|------------------|:---------:|:----------------------------------------------------:|:---------------------------------------------------:|
+| `name`           |  required |             Name of the feature detection            |                                                     |
+| `property`       |  required | The property name established in `Modernizr.addTest` |    It must be lowercase, without any punctuation    |
+| `tags`           |  optional |    A group that encapsulates many feature detects    |                                                     |
+| `caniuse`        |  optional |      A conversion table of caniuse and Modernizr     | Consider adding [caniuse testing](#caniuse-testing) |
+| `authors`        |  optional |          List of contributors of the script          |                                                     |
+| `builderAliases` |  optional |     Used by CI and the web when tests are renamed    |          Should not be needed in new tests          |
+| `polyfills`      |  optional |     Available polyfills for not working versions     |      Check the [polyfills section](#polyfills)      |
+| `aliases`        |  optional |   Used if a feature has more than a canonical name   |               Legacy only - do not use              |
+| `async`          |  optional |       If the test supports async functionality       |                  Defaults to false                  |
+| `warnings`       |  optional |        Notes to the developer using the script       |            Don't mistake it for knownBugs           |
+| `knownBugs`      |  optional |  Bugs known of the test (e.g.: doesn't work in IE6)  |                                                     |
+| `notes`          |  optional |                  Links to resources                  |                                                     |
+
+## Polyfills
+
+Polyfills can be included in the [metadata](#metadata) with a simple word. In order to do this the [lib/polyfills.json](lib/polyfills.json) must include the description of all polyfills.
+
+### Polyfill Schema
+
+The following example represents the schema in which polyfills must be defined in the [polyfills.json](lib/polyfills.json) file:
+
+```json
+"css3pie": {
+  "name": "CSS3 PIE",
+  "authors": ["Jason Johnston"],
+  "href": "http://css3pie.com/",
+  "licenses": ["Apache2", "GPL2"],
+  "notes": ["CSS3 decoration rendering for IE 6-9. Supports: border-radius, box-shadow, multiple backgrounds, linear gradients, border-image"]
+},
+```
+
+> Metadata does no need to appear in a set order, however, it is common to follow the order stated above.
+
+### Polyfill Item Description
+
+|            | Necessity |           Description          |
+|------------|:---------:|:------------------------------:|
+| `name`     |  required |    The name of the polyfill    |
+| `authors`  |  optional |  Main authors of the polyfill  |
+| `notes`    |  optional |        Extra information       |
+| `href`     |  required | Link to the polyfill main page |
+| `licenses` |  required |     License of the polyfill    |
+
+> To reference the polyfill in the [metadata](#metadata) use the head of the object, in this case `css3pie`
+
+## Submitting a PR
+
+Once you have a feature or bug fix ready commit it to your own branch and submit a PR! There are no requirements to send a PR, no CLA, template you have to follow, title requirements, etc. However, provide a descriptive title and description.
+
+If you need to submit an issue, please include the Modernizr and Node version as well as your OS.
+
+## Testing
+
+### General Testing
+
+After creating your feature detect you'll need to add testing. In order to do it you must head to the [lib/config-all.json](lib/config-all.json) and include the relative path with root in the `feature-detects` folder to your test file (without the extension) under the `feature-detects` section. Here are some examples:
+
+```js
+// lib/config-all.json
+"img/apng", // for "feature-detects/img/apng.js"
+"mathml", // for feature-detects/mathml.js
+```
+
+> Note that it follows JSON schema in alphabetical order. Also consider adding caniuse testing if possible.
+
+### Caniuse Testing
+
+This testing is optional but highly recommended if a caniuse equivalent exists. In order to do it follow this steps:
+
+1. Firstly, click on the `#` symbol to the left of the name of the feature in [caniuse.com](https://caniuse.com).
+2. Copy everything in the URL following `https://caniuse.com/#feat=`, for example, in `https://caniuse.com/#feat=channel-messaging` copy only `channel-messaging`.
+3. Add this information to the [test/browser/integration/caniuse.js](test/browser/integration/caniuse.js) file under the map variable. The Modernizr property value appears in the left and the caniuse value in the right, for example, the `channel-messaging` corresponds to the `messagechannel` test  so it should appear like this:
+
+```js
+// test/browser/integration/caniuse.js
+messagechannel: 'channel-messaging', // Modernizr left, caniuse right
+```
+
+> Note that it follows JSON schema in alphabetical order. Also consider adding `caniuse` in [the metadata field](#metadata).
+> The following situations may cause errors: MDN Data, partial supports, flag only support, unknown support.
+
+### Verifying and Running Your Tests
+
+There are 2 main ways you can verify if your test works correctly:
+
+**Basic checking:** If only you want to check that your test returns the correct answer run `npm test` as it will throw an error if something goes wrong.
+
+**Specific checking:** In case you want to check the test in a specific browser run `npm run serve-gh-pages` and navigate to [localhost:8080/test/integration.html](http://localhost:8080/test/integration.html), where you should find the name of your test in case you performed the [General Testing](#general-testing) steps right. You will also find the caniuse comparison of your feature detect under the [caniuse section](http://localhost:8080/test/integration.html?grep=caniuse) (at the bottom) if you performed the [Caniuse Testing](#caniuse-testing) steps right. You may want to use the search function of your browser.
+
+## Install the Basics
+
+### Installing Node and Npm
+
+Firstly you will need to install nodejs on your system. Go to [nodejs.org](https://nodejs.org) and download the latest LTS release. NPM will come along the installer.
+
+> In case of being using linux use you may use this [DigitalOcean tutorial](https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-20-04).
+
+### Downloading the Modernizr Repository
+
+> Note: It is recommended that you set your own git environment, however this is a complicated and diverse task so we won't be explaining it here. We recommend using, for example, [Github Desktop](https://desktop.github.com/) (very beginner friendly), [Sublime Merge](https://www.sublimemerge.com/) or the git command-line tool. We also recommend checking this [tutorial website](https://rogerdudler.github.io/git-guide/) if you never used git before.
+
+To download the code of the repository:
+
+* Head to the main [Modernizr repository](https://github.com/Modernizr/Modernizr)
+* Click `Clone or download` and `Download ZIP` afterwards. Optionally you can click [https://github.com/Modernizr/Modernizr/archive/master.zip](https://github.com/Modernizr/Modernizr/archive/master.zip) to download it directly.
+* Finally, unzip the file.
diff --git a/README.md b/README.md
index 467ac1d9..a7fd1d9d 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,8 @@ Modernizr tests which native CSS3 and HTML5 features are available in the curren
     - `touchevents`: [discussion](https://github.com/Modernizr/Modernizr/pull/2432) 
     - `unicode`: [discussion](https://github.com/Modernizr/Modernizr/issues/2468) 
     - `templatestrings`: duplicate of the es6 detect `stringtemplate`
-    
+    - `datalistelem`: A dupe of Modernizr.input.list
+
 ## New Asynchronous Event Listeners
 
 Often times people want to know when an asynchronous test is done so they can allow their application to react to it.
diff --git a/feature-detects/audio/webaudio.js b/feature-detects/audio/webaudio.js
index 6557efba..8947f6d1 100644
--- a/feature-detects/audio/webaudio.js
+++ b/feature-detects/audio/webaudio.js
@@ -3,18 +3,18 @@
   "name": "Web Audio API",
   "property": "webaudio",
   "caniuse": "audio-api",
-  "polyfills": ["xaudiojs", "dynamicaudiojs", "audiolibjs"],
+  "polyfills": ["dynamicaudiojs", "audiolibjs"],
   "tags": ["audio", "media"],
   "builderAliases": ["audio_webaudio_api"],
   "authors": ["Addy Osmani"],
   "notes": [{
     "name": "W3C Spec",
-    "href": "https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html"
+    "href": "https://webaudio.github.io/web-audio-api/"
   }]
 }
 !*/
 /* DOC
-Detects the older non standard webaudio API, (as opposed to the standards based AudioContext API)
+Check for the Web Audio API
 */
 define(['Modernizr'], function(Modernizr) {
   Modernizr.addTest('webaudio', function() {
diff --git a/feature-detects/canvas.js b/feature-detects/canvas.js
index 149ab299..859a87c5 100644
--- a/feature-detects/canvas.js
+++ b/feature-detects/canvas.js
@@ -4,7 +4,7 @@
   "property": "canvas",
   "caniuse": "canvas",
   "tags": ["canvas", "graphics"],
-  "polyfills": ["flashcanvas", "excanvas", "slcanvas", "fxcanvas"]
+  "polyfills": ["excanvas", "slcanvas"]
 }
 !*/
 /* DOC
diff --git a/feature-detects/crypto.js b/feature-detects/crypto.js
index e4dfa8ce..93a65d47 100644
--- a/feature-detects/crypto.js
+++ b/feature-detects/crypto.js
@@ -8,8 +8,7 @@
   "notes": [{
     "name": "W3C Editor's Draft Spec",
     "href": "https://www.w3.org/TR/WebCryptoAPI/"
-  }],
-  "polyfills": ["polycrypt"]
+  }]
 }
 !*/
 /* DOC
diff --git a/feature-detects/crypto/getrandomvalues.js b/feature-detects/crypto/getrandomvalues.js
index c64a81b2..2bb398f9 100644
--- a/feature-detects/crypto/getrandomvalues.js
+++ b/feature-detects/crypto/getrandomvalues.js
@@ -8,8 +8,7 @@
   "notes": [{
     "name": "W3C Editor’s Draft Spec",
     "href": "https://w3c.github.io/webcrypto/#Crypto-interface-methods"
-  }],
-  "polyfills": ["polycrypt"]
+  }]
 }
 !*/
 /* DOC
diff --git a/feature-detects/css/columns.js b/feature-detects/css/columns.js
index 9ec26b2f..ca73fdb9 100644
--- a/feature-detects/css/columns.js
+++ b/feature-detects/css/columns.js
@@ -3,7 +3,6 @@
   "name": "CSS Columns",
   "property": "csscolumns",
   "caniuse": "multicolumn",
-  "polyfills": ["css3multicolumnjs"],
   "tags": ["css"]
 }
 !*/
diff --git a/feature-detects/css/ellipsis.js b/feature-detects/css/ellipsis.js
index 2e26acb1..cf120e7f 100644
--- a/feature-detects/css/ellipsis.js
+++ b/feature-detects/css/ellipsis.js
@@ -3,7 +3,6 @@
   "name": "CSS text-overflow ellipsis",
   "property": "ellipsis",
   "caniuse": "text-overflow",
-  "polyfills": ["text-overflow"],
   "tags": ["css"]
 }
 !*/
diff --git a/feature-detects/css/fontface.js b/feature-detects/css/fontface.js
index 4fe111c9..9e1eeda3 100644
--- a/feature-detects/css/fontface.js
+++ b/feature-detects/css/fontface.js
@@ -27,13 +27,13 @@
 }
 !*/
 define(['Modernizr', 'testStyles'], function(Modernizr, testStyles) {
-  var blacklist = (function() {
+  var unsupportedUserAgent = (function() {
     var ua = navigator.userAgent;
     var webos = ua.match(/w(eb)?osbrowser/gi);
     var wppre8 = ua.match(/windows phone/gi) && ua.match(/iemobile\/([0-9])+/gi) && parseFloat(RegExp.$1) >= 9;
     return webos || wppre8;
   }());
-  if (blacklist) {
+  if (unsupportedUserAgent) {
     Modernizr.addTest('fontface', false);
   } else {
     testStyles('@font-face {font-family:"font";src:url("https://")}', function(node, rule) {
diff --git a/feature-detects/css/hyphens.js b/feature-detects/css/hyphens.js
index 3e96d994..4f8289f3 100644
--- a/feature-detects/css/hyphens.js
+++ b/feature-detects/css/hyphens.js
@@ -136,11 +136,11 @@ define(['Modernizr', 'prefixes', 'createElement', 'testAllProps', 'addTest'], fu
       // testing if in-browser Find functionality will work on hyphenated text
       function test_hyphens_find(delimiter) {
         try {
-          /* create a dummy input for resetting selection location, and a div container
+          /* create a sample input for resetting selection location, and a div container
            * these have to be appended to document.body, otherwise some browsers can give false negative
            * div container gets the doubled testword, separated by the delimiter
            * Note: giving a width to div gives false positive in iOS Safari */
-          var dummy = createElement('input');
+          var sampleInput = createElement('input');
           var div = createElement('div');
           var testword = 'lebowski';
           var result = false;
@@ -148,21 +148,21 @@ define(['Modernizr', 'prefixes', 'createElement', 'testAllProps', 'addTest'], fu
           var firstChild = document.body.firstElementChild || document.body.firstChild;
 
           /* Make the elements fixed to prevent that the browser's viewport will jump to the top  */
-          dummy.style.cssText = 'position:fixed;top:0;';
+          sampleInput.style.cssText = 'position:fixed;top:0;';
           div.style.cssText = 'position:fixed;top:0;';
 
           div.innerHTML = testword + delimiter + testword;
 
           document.body.insertBefore(div, firstChild);
-          document.body.insertBefore(dummy, div);
+          document.body.insertBefore(sampleInput, div);
 
-          /* reset the selection to the dummy input element, i.e. BEFORE the div container
+          /* reset the selection to the sample input element, i.e. BEFORE the div container
            *   stackoverflow.com/questions/499126/jquery-set-cursor-position-in-text-area */
-          if (dummy.setSelectionRange) {
-            dummy.focus();
-            dummy.setSelectionRange(0, 0);
-          } else if (dummy.createTextRange) {
-            textrange = dummy.createTextRange();
+          if (sampleInput.setSelectionRange) {
+            sampleInput.focus();
+            sampleInput.setSelectionRange(0, 0);
+          } else if (sampleInput.createTextRange) {
+            textrange = sampleInput.createTextRange();
             textrange.collapse(true);
             textrange.moveEnd('character', 0);
             textrange.moveStart('character', 0);
@@ -182,7 +182,7 @@ define(['Modernizr', 'prefixes', 'createElement', 'testAllProps', 'addTest'], fu
           }
 
           document.body.removeChild(div);
-          document.body.removeChild(dummy);
+          document.body.removeChild(sampleInput);
 
           return result;
         } catch (e) {
diff --git a/feature-detects/css/transforms.js b/feature-detects/css/transforms.js
index b19dcfe2..2cb00080 100644
--- a/feature-detects/css/transforms.js
+++ b/feature-detects/css/transforms.js
@@ -8,7 +8,7 @@
 !*/
 define(['Modernizr', 'testAllProps'], function(Modernizr, testAllProps) {
   Modernizr.addTest('csstransforms', function() {
-    // Android < 3.0 is buggy, so we sniff and blacklist
+    // Android < 3.0 is buggy, so we sniff and reject it
     // https://github.com/Modernizr/Modernizr/issues/903
     return navigator.userAgent.indexOf('Android 2.') === -1 &&
            testAllProps('transform', 'scale(1)', true);
diff --git a/feature-detects/elem/datalist.js b/feature-detects/elem/datalist.js
deleted file mode 100644
index 765d538b..00000000
--- a/feature-detects/elem/datalist.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*!
-{
-  "name": "datalist Element",
-  "caniuse": "datalist",
-  "property": "datalistelem",
-  "tags": ["elem"],
-  "builderAliases": ["elem_datalist"],
-  "warnings": ["This test is a dupe of Modernizr.input.list. Only around for legacy reasons."],
-  "notes": [{
-    "name": "CSS Tricks Article",
-    "href": "https://css-tricks.com/relevant-dropdowns-polyfill-for-datalist/"
-  }, {
-    "name": "Mike Taylor Code",
-    "href": "https://miketaylr.com/code/datalist.html"
-  }]
-}
-!*/
-define(['Modernizr', 'test/input'], function(Modernizr) {
-  // lol. we already have a test for datalist built in! silly you.
-  // Leaving it around in case anyone's using it
-
-  Modernizr.addTest('datalistelem', Modernizr.input.list);
-});
diff --git a/feature-detects/gamepad.js b/feature-detects/gamepad.js
index a7312ede..93427a80 100644
--- a/feature-detects/gamepad.js
+++ b/feature-detects/gamepad.js
@@ -5,6 +5,7 @@
   "caniuse": "gamepad",
   "authors": ["Eric Bidelman"],
   "tags": ["media"],
+  "warnings": ["In new browsers it may return false in non-HTTPS connections"],
   "notes": [{
     "name": "W3C Spec",
     "href": "https://www.w3.org/TR/gamepad/"
diff --git a/feature-detects/storage/sessionstorage.js b/feature-detects/storage/sessionstorage.js
index 1e2df824..8af065c4 100644
--- a/feature-detects/storage/sessionstorage.js
+++ b/feature-detects/storage/sessionstorage.js
@@ -3,7 +3,7 @@
   "name": "Session Storage",
   "property": "sessionstorage",
   "tags": ["storage"],
-  "polyfills": ["joshuabell-polyfill", "cupcake", "sessionstorage"]
+  "polyfills": ["joshuabell-polyfill", "cupcake", "storagepolyfill"]
 }
 !*/
 define(['Modernizr'], function(Modernizr) {
diff --git a/feature-detects/svg.js b/feature-detects/svg.js
index 3359d92e..58bca673 100644
--- a/feature-detects/svg.js
+++ b/feature-detects/svg.js
@@ -8,11 +8,9 @@
   "polyfills": [
     "svgweb",
     "raphael",
-    "amplesdk",
     "canvg",
     "svg-boilerplate",
     "sie",
-    "dojogfx",
     "fabricjs"
   ]
 }
diff --git a/feature-detects/svg/filters.js b/feature-detects/svg/filters.js
index f8c82f39..b8f51f74 100644
--- a/feature-detects/svg/filters.js
+++ b/feature-detects/svg/filters.js
@@ -13,7 +13,7 @@
 }
 !*/
 define(['Modernizr'], function(Modernizr) {
-  // Should fail in Safari: https://stackoverflow.com/questions/9739955/feature-detecting-support-for-svg-filters.
+  // How it is made to fail in pre 6 versions of Safari: https://stackoverflow.com/questions/9739955/feature-detecting-support-for-svg-filters.
   Modernizr.addTest('svgfilters', function() {
     var result = false;
     try {
diff --git a/feature-detects/url/data-uri.js b/feature-detects/url/data-uri.js
index 96154abc..251eb116 100644
--- a/feature-detects/url/data-uri.js
+++ b/feature-detects/url/data-uri.js
@@ -26,7 +26,7 @@ define(['Modernizr'], function(Modernizr) {
   Modernizr.addAsyncTest(function() {
 
     // IE7 throw a mixed content warning on HTTPS for this test, so we'll
-    // just blacklist it (we know it doesn't support data URIs anyway)
+    // just reject it (we know it doesn't support data URIs anyway)
     // https://github.com/Modernizr/Modernizr/issues/362
     if (navigator.userAgent.indexOf('MSIE 7.') !== -1) {
       // Keep the test async
diff --git a/feature-detects/video.js b/feature-detects/video.js
index 9356fa72..094dd4f5 100644
--- a/feature-detects/video.js
+++ b/feature-detects/video.js
@@ -8,7 +8,6 @@
   "polyfills": [
     "html5media",
     "mediaelementjs",
-    "sublimevideo",
     "videojs",
     "leanbackplayer",
     "videoforeverybody"
diff --git a/feature-detects/web-intents.js b/feature-detects/web-intents.js
index 26d6eafe..10c79e62 100644
--- a/feature-detects/web-intents.js
+++ b/feature-detects/web-intents.js
@@ -7,7 +7,6 @@
     "name": "Web Intents project site",
     "href": "http://www.webintents.org/"
   }],
-  "polyfills": ["webintents"],
   "builderAliases": ["web_intents"]
 }
 !*/
diff --git a/feature-detects/websockets.js b/feature-detects/websockets.js
index cb21f7f9..9986deba 100644
--- a/feature-detects/websockets.js
+++ b/feature-detects/websockets.js
@@ -13,7 +13,6 @@
   "polyfills": [
     "sockjs",
     "socketio",
-    "kaazing-websocket-gateway",
     "websocketjs",
     "atmosphere",
     "graceful-websocket",
diff --git a/feature-detects/window/resizeobserver.js b/feature-detects/window/resizeobserver.js
new file mode 100644
index 00000000..c95e2b63
--- /dev/null
+++ b/feature-detects/window/resizeobserver.js
@@ -0,0 +1,29 @@
+/*!
+{
+  "name": "ResizeObserver",
+  "property": "resizeobserver",
+  "caniuse": "resizeobserver",
+  "tags": ["ResizeObserver"],
+  "authors": ["Christian Andersson"],
+  "notes": [{
+    "name": "W3C Spec",
+    "href": "https://www.w3.org/TR/resize-observer/"
+  }, {
+    "name": "MDN Docs",
+    "href": "https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver"
+  }, {
+    "name": "Web.dev Article",
+    "href": "https://web.dev/resize-observer/"
+  }, {
+    "name": "Digital Ocean tutorial",
+    "href": "https://www.digitalocean.com/community/tutorials/js-resize-observer"
+  }]
+}
+!*/
+
+/* DOC
+Detects support for ResizeObserver.
+*/
+define(['Modernizr'], function(Modernizr) {
+  Modernizr.addTest('resizeobserver', 'ResizeObserver' in window);
+});
diff --git a/lib/config-all.json b/lib/config-all.json
index 99163b3c..33302502 100644
--- a/lib/config-all.json
+++ b/lib/config-all.json
@@ -77,8 +77,8 @@
     "css/flexbox",
     "css/flexboxlegacy",
     "css/flexboxtweener",
-    "css/flexwrap",
     "css/flexgap",
+    "css/flexwrap",
     "css/focuswithin",
     "css/fontdisplay",
     "css/fontface",
@@ -146,7 +146,6 @@
     "dom/shadowroot",
     "dom/shadowrootlegacy",
     "elem/bdi",
-    "elem/datalist",
     "elem/details",
     "elem/output",
     "elem/picture",
@@ -176,11 +175,11 @@
     "es6/number",
     "es6/object",
     "es6/promises",
-    "es6/string",
-    "es6/symbol",
     "es6/rest-parameters",
-    "es6/string-template",
     "es6/spread-array",
+    "es6/string-template",
+    "es6/string",
+    "es6/symbol",
     "es7/array",
     "es7/rest-destructuring",
     "es7/spread-object",
@@ -220,10 +219,10 @@
     "img/lazyloading",
     "img/sizes",
     "img/srcset",
-    "img/webp",
     "img/webp-alpha",
     "img/webp-animation",
     "img/webp-lossless",
+    "img/webp",
     "indexeddb",
     "indexeddbblob",
     "input",
@@ -239,22 +238,22 @@
     "ligatures",
     "lists-reversed",
     "mathml",
+    "media-source-extension-api",
     "mediaquery/hovermq",
     "mediaquery/pointermq",
-    "media-source-extension-api",
     "messagechannel",
     "network/beacon",
-    "network/connection",
     "network/connection-effectivetype",
+    "network/connection",
     "network/eventsource",
     "network/fetch",
-    "network/xhr2",
-    "network/xhr-responsetype",
     "network/xhr-responsetype-arraybuffer",
     "network/xhr-responsetype-blob",
     "network/xhr-responsetype-document",
     "network/xhr-responsetype-json",
     "network/xhr-responsetype-text",
+    "network/xhr-responsetype",
+    "network/xhr2",
     "notification",
     "pagevisibility-api",
     "performance",
@@ -311,6 +310,7 @@
     "window/atob-btoa",
     "window/framed",
     "window/matchmedia",
+    "window/resizeobserver",
     "workers/blobworkers",
     "workers/dataworkers",
     "workers/sharedworkers",
diff --git a/lib/polyfills.json b/lib/polyfills.json
index 1b367e88..6e7bd3e8 100644
--- a/lib/polyfills.json
+++ b/lib/polyfills.json
@@ -27,20 +27,10 @@
     "licenses": ["Apache2", "GPL2"],
     "notes": ["CSS3 decoration rendering for IE 6-9. Supports: border-radius, box-shadow, multiple backgrounds, linear gradients, border-image"]
   },
-  "xaudiojs": {
-    "name": "XAudioJS",
-    "authors": ["Grant Galitz"],
-    "href": "https://github.com/grantgalitz/XAudioJS",
-    "licenses": [],
-    "notes": [
-      "Audio sample stream output thin-abstraction library that supports mono and stereo audio, as well as resampling the audio stream.",
-      "Supports the Mozilla Audio Data API, Web Audio API, Adobe Flash 10, real-time WAV PCM Data URI generation"
-    ]
-  },
   "dynamicaudiojs": {
     "name": "dynamicaudio.js",
     "authors": ["Ben Firshman"],
-    "href": "http://github.com/bfirsh/dynamicaudio.js",
+    "href": "https://github.com/bfirsh/dynamicaudio.js",
     "licenses": ["BSD"],
     "notes": []
   },
@@ -61,14 +51,14 @@
   "csssandpaper": {
     "name": "CSS Sandpaper",
     "authors": ["Zoltan Hawryluk"],
-    "href": "http://www.useragentman.com/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/",
+    "href": "https://www.useragentman.com/blog/2010/03/09/cross-browser-css-transforms-even-in-ie/",
     "licenses": ["MIT"],
     "notes": []
   },
   "css-escape": {
     "name": "CSS.escape()",
     "authors": ["Mathias Bynens"],
-    "href": "http://mths.be/cssescape",
+    "href": "https://github.com/mathiasbynens/CSS.escape",
     "licenses": ["MIT"],
     "notes": []
   },
@@ -93,16 +83,6 @@
     "licenses": [],
     "notes": ["box-sizing: border-box; polyfill for SASS/Compass. Outputs equivalent CSS for IE6 & 7"]
   },
-  "css3multicolumnjs": {
-    "name": "css3-multi-column.js",
-    "authors": ["Betley Whitehorne Image", "Cdric Savarese"],
-    "href": "https://github.com/BetleyWhitehorne/CSS3MultiColumn",
-    "licenses": ["CC-GNU LGPL"],
-    "notes": [
-      "Supported Properties: column-count, column-width, column-gap, column-rule.",
-      "Unsupported Properties: column-rule-width (use column-rule instead), column-rule-style (use column-rule instead), column-rule-color (use column-rule instead), column-span, column-width-policy, column-space-distribution"
-    ]
-  },
   "polyfilter": {
     "name": "Polyfilter",
     "authors": ["Christian \"Schepp\" Schaefer"],
@@ -113,7 +93,7 @@
   "flexie": {
     "name": "Flexie",
     "authors": ["Richard Herrera"],
-    "href": "http://github.com/doctyper/flexie",
+    "href": "https://github.com/doctyper/flexie",
     "licenses": ["MIT"],
     "notes": ["Flexible box model - old spec from 2009. (flexbox) Supports: box-orient, box-align, box-direction, box-pack, box-flex, box-ordinal-group"]
   },
@@ -136,7 +116,7 @@
   "html5gears": {
     "name": "html5-gears",
     "authors": ["Brad Neuberg"],
-    "href": "https://code.google.com/p/html5-gears/",
+    "href": "https://code.google.com/archive/p/html5-gears/",
     "licenses": ["Apache2"]
   },
   "blobjs": {
@@ -145,33 +125,21 @@
     "href": "https://github.com/eligrey/Blob.js",
     "licenses": ["MIT"]
   },
-  "flashcanvas": {
-    "name": "FlashCanvas",
-    "authors": ["Shinya Muramatsu"],
-    "href": "http://flashcanvas.net/",
-    "licenses": ["MIT"]
-  },
   "excanvas": {
     "name": "Explorer Canvas",
     "authors": ["Erik Arvidsson"],
-    "href": "https://code.google.com/p/explorercanvas/",
+    "href": "https://github.com/arv/explorercanvas",
     "licenses": ["Apache2"]
   },
   "slcanvas": {
     "name": "Silverlight HTML 5 Canvas",
-    "href": "http://slcanvas.codeplex.com/",
+    "href": "https://archive.codeplex.com/?p=slcanvas",
     "licenses": ["Microsoft Public License (Ms-PL)"]
   },
-  "fxcanvas": {
-    "name": "fxCanvas",
-    "authors": ["Evgeny Burzak"],
-    "href": "http://burzak.com/proj/fxcanvas/",
-    "licenses": ["MIT"]
-  },
   "canvastext": {
     "name": "canvas-text",
     "authors": ["Fabien Ménager"],
-    "href": "https://code.google.com/p/canvas-text/",
+    "href": "https://code.google.com/archive/p/canvas-text/",
     "licenses": ["MIT"]
   },
   "jquery-contextmenu": {
@@ -232,7 +200,7 @@
   "geo-location-javascript": {
     "name": "geo-location-javascript",
     "authors": ["whoisstan"],
-    "href": "https://code.google.com/p/geo-location-javascript/",
+    "href": "https://code.google.com/archive/p/geo-location-javascript/",
     "notes": ["Mobile-centric: uses non-standard Blackberry and WebOS tricks"],
     "licenses": ["MIT"]
   },
@@ -251,7 +219,7 @@
   "moo-historymanager": {
     "name": "HistoryManager Mootools Plugin",
     "authors": ["Arieh Glazer"],
-    "href": "http://mootools.net/forge/p/historymanager/",
+    "href": "https://mootools.net/forge/p/historymanager/",
     "licenses": ["MIT"]
   },
   "jquery-ajaxy": {
@@ -287,18 +255,18 @@
   "indexeddb": {
     "name": "IndexedDB",
     "authors": ["Parashuram"],
-    "href": "http://nparashuram.com/IndexedDBShim/",
+    "href": "https://nparashuram.com/IndexedDBShim/",
     "licenses": ["GPL2", "BSD"]
   },
   "jquerytools": {
     "name": "jQuery Tools",
-    "href": "http://jquerytools.org",
+    "href": "https://jquerytools.org",
     "licenses": ["public domain"]
   },
   "webshims": {
     "name": "Webshims",
     "authors": ["Alexander Farkas"],
-    "href": "http://afarkas.github.io/webshim/demos/",
+    "href": "https://afarkas.github.io/webshim/demos/",
     "licenses": ["MIT"]
   },
   "h5f": {
@@ -345,7 +313,7 @@
   "galleryhtml5forms": {
     "name": "YUI Gallery HTML5 Forms",
     "authors": ["Matt Snider"],
-    "href": "http://yuilibrary.com/gallery/show/html5-forms",
+    "href": "https://yuilibrary.com/gallery-archive/gallery/show/html5-forms.html",
     "licenses": ["BSD"]
   },
   "jscolor": {
@@ -381,7 +349,7 @@
   "mathjax": {
     "name": "MathJax",
     "authors": ["Davide P. Cervone"],
-    "href": "http://www.mathjax.org/",
+    "href": "https://www.mathjax.org/",
     "licenses": ["Apache2"]
   },
   "visibilityjs": {
@@ -405,7 +373,7 @@
   "notificationjs": {
     "name": "notification.js",
     "authors": ["Andrew Dodson"],
-    "href": "http://adodson.com/notification.js/",
+    "href": "https://adodson.com/notification.js/",
     "licenses": ["MIT"]
   },
   "perfnow": {
@@ -417,7 +385,7 @@
   "easyxdm": {
     "name": "easyXDM",
     "authors": ["Sean Kinsey"],
-    "href": "http://easyxdm.net/wp/",
+    "href": "https://github.com/oyvindkinsey/easyXDM",
     "notes": ["Implements XDM and RPC in most browsers since IE6. Also ships with an endpoint for exposing ajax across the domain boundary."],
     "licenses": ["MIT"]
   },
@@ -448,39 +416,32 @@
   "storagepolyfill": {
     "name": "Storage Polyfill",
     "authors": ["Remy Sharp"],
-    "href": "http://gist.github.com/350433",
-    "notes": [],
-    "licenses": ["MIT"]
-  },
-  "sessionstorage": {
-    "name": "sessionstorage",
-    "authors": ["Andrea Giammarchi"],
-    "href": "http://gist.github.com/350433",
+    "href": "https://gist.github.com/remy/350433",
     "licenses": ["MIT"]
   },
   "amplifyjs": {
     "name": "Amplify.js",
     "authors": ["appendTo"],
-    "href": "http://amplifyjs.com/",
+    "href": "https://amplifyjs.com/",
     "licenses": ["MIT", "GPL2"]
   },
   "yui-cacheoffline": {
     "name": "YUI3 CacheOffline",
     "authors": ["YUI Team"],
-    "href": "http://yuilibrary.com/yui/docs/cache/#offline",
+    "href": "https://yuilibrary.com/yui/docs/cache/#offline",
     "licenses": ["BSD"]
   },
   "scoped-styles": {
     "name": "Scoped Styles",
     "authors": ["Simon Madine"],
     "notes": ["jQuery Plugin to enable the scoped attribute on style blocks so they only affect their parent element's children."],
-    "href": "http://github.com/thingsinjars/jQuery-Scoped-CSS-plugin",
+    "href": "https://github.com/thingsinjars/jQuery-Scoped-CSS-plugin",
     "licenses": ["MIT"]
   },
   "svgweb": {
     "name": "SVG Web",
     "authors": ["Rick Masters", "Brad Neuberg", "James Hight"],
-    "href": "https://code.google.com/p/svgweb/",
+    "href": "https://code.google.com/archive/p/svgweb/",
     "licenses": ["Apache2"]
   },
   "raphael": {
@@ -490,16 +451,10 @@
     "notes": ["Abstracted API. adds features. fallback for IE via VML"],
     "licenses": ["MIT"]
   },
-  "amplesdk": {
-    "name": "Ample SDK",
-    "authors": ["Sergey Ilinsky"],
-    "href": "http://www.amplesdk.com/examples/svg/",
-    "licenses": ["MIT", "GPL2"]
-  },
   "canvg": {
     "name": "canvg",
     "authors": ["Gabe Lerner"],
-    "href": "http://code.google.com/p/canvg/",
+    "href": "https://github.com/canvg/canvg",
     "notes": ["Writes SVG to canvas. Good for Android"],
     "licenses": ["MIT"]
   },
@@ -513,17 +468,10 @@
   "sie": {
     "name": "SIE SVG library",
     "authors": ["Hiroki Dehara"],
-    "href": "http://sie.sourceforge.jp/",
+    "href": "https://sie.osdn.jp/",
     "notes": ["Fallback to VML for oldIE"],
     "licenses": ["Mozilla1.1", "GPL2", "LGPL2.1"]
   },
-  "dojogfx": {
-    "name": "Dojo GFX",
-    "authors": ["Eugene Lazutkin", "Kun Xi", "Chris Mitchell"],
-    "href": "http://docs.dojocampus.org/dojox/gfx/",
-    "notes": ["Fallback via VML, Canvas, Silverlight and Flash"],
-    "licenses": ["BSD", "AFL"]
-  },
   "fabricjs": {
     "name": "fabric.js",
     "authors": ["Juriy Zaytsev (@kangax)"],
@@ -543,12 +491,6 @@
     "href": "https://github.com/inexorabletash/polyfill",
     "licenses": ["various"]
   },
-  "text-overflow": {
-    "name": "jQuery text-overflow",
-    "authors": ["Devon Govett"],
-    "href": "http://ajaxian.com/archives/text-overflow-for-firefox-via-jquery",
-    "licenses": ["MIT"]
-  },
   "html5media": {
     "name": "html5media",
     "authors": ["Dave Hall"],
@@ -558,25 +500,19 @@
   "mediaelementjs": {
     "name": "MediaElement.js",
     "authors": ["John Dyer"],
-    "href": "http://mediaelementjs.com/",
+    "href": "https://www.mediaelementjs.com/",
     "licenses": ["MIT"]
   },
-  "sublimevideo": {
-    "name": "SublimeVideo",
-    "authors": ["Jilion SA"],
-    "href": "http://sublimevideo.net/",
-    "licenses": ["proprietary"]
-  },
   "videojs": {
     "name": "video.js",
     "authors": ["Steve Heffernan"],
-    "href": "http://videojs.com/",
+    "href": "https://videojs.com/",
     "licenses": ["Apache2"]
   },
   "leanbackplayer": {
     "name": "LeanBack Player",
     "authors": ["Kapelan Medien GmbH"],
-    "href": "http://www.leanbackplayer.com/",
+    "href": "https://www.leanbackplayer.com/",
     "licenses": ["GPL3"]
   },
   "videoforeverybody": {
@@ -585,22 +521,16 @@
     "href": "http://camendesign.com/code/video_for_everybody",
     "licenses": ["public domain"]
   },
-  "webintents": {
-    "name": "Web Intents JavaScript Shim",
-    "authors": ["Paul Kinlan"],
-    "href": "http://webintents.org/#javascriptshim",
-    "licenses": ["Apache2"]
-  },
   "jebgl": {
     "name": "jebgl",
     "authors": ["Martin Qvist"],
-    "href": "http://code.google.com/p/jebgl/",
+    "href": "https://code.google.com/archive/p/jebgl/",
     "licenses": ["MIT"]
   },
   "cwebgl": {
     "name": "cwebgl",
     "authors": ["Cimaron Shanahan"],
-    "href": "http://code.google.com/p/cwebgl/",
+    "href": "https://code.google.com/archive/p/cwebgl/",
     "licenses": ["MIT"]
   },
   "iewebgl": {
@@ -617,24 +547,19 @@
   "socketio": {
     "name": "socket.io",
     "authors": ["Guillermo Rauch"],
-    "href": "http://socket.io/",
+    "href": "https://socket.io/",
     "licenses": ["MIT"]
   },
-  "kaazing-websocket-gateway": {
-    "name": "Kaazing WebSocket Gateway",
-    "href": "http://kaazing.com/products/kaazing-websocket-gateway/",
-    "licenses": ["proprietary"]
-  },
   "websocketjs": {
     "name": "web-socket-js",
     "authors": ["Hiroshi Ichikawa"],
-    "href": "http://github.com/gimite/web-socket-js/",
+    "href": "https://github.com/gimite/web-socket-js/",
     "licenses": ["BSD"]
   },
   "atmosphere": {
     "name": "atmosphere jQuery plugin",
     "authors": ["Jeanfrancois Arcand"],
-    "href": "http://jfarcand.wordpress.com/2010/06/15/using-atmospheres-jquery-plug-in-to-build-applicationsupporting-both-websocket-and-comet/",
+    "href": "https://jfarcand.wordpress.com/2010/06/15/using-atmospheres-jquery-plug-in-to-build-applicationsupporting-both-websocket-and-comet/",
     "licenses": ["Apache2"]
   },
   "graceful-websocket": {
@@ -664,21 +589,15 @@
   "fakeworker": {
     "name": "fakeworker.js",
     "authors": ["Shumpei Shiraishi"],
-    "href": "https://code.google.com/p/fakeworker-js/",
+    "href": "https://code.google.com/archive/p/fakeworker-js/",
     "licenses": ["Apache2"]
   },
   "html5shims": {
     "name": "web worker api shim",
     "authors": ["Jonathan 'J5' Cook"],
-    "href": "https://code.google.com/p/html5-shims/",
+    "href": "https://code.google.com/archive/p/html5-shims/",
     "licenses": ["Apache2"]
   },
-  "polycrypt": {
-    "name": "PolyCrypt",
-    "authors": ["BBN Technologies"],
-    "href": "http://polycrypt.net/",
-    "licenses": ["BSD"]
-  },
   "webanimationsjs": {
     "name": "web-animations-js",
     "authors": ["web-animations"],
@@ -694,7 +613,7 @@
   "maxlength": {
     "name": "maxlength plugin",
     "authors": ["Remy Sharp"],
-    "href": "http://remysharp.com/2008/06/30/maxlength-plugin/",
+    "href": "https://remysharp.com/2008/06/30/maxlength-plugin/",
     "licenses": ["CC SA"]
   },
   "weakmap": {
diff --git a/package-lock.json b/package-lock.json
index a1381823..3e97732d 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9697,9 +9697,9 @@
       }
     },
     "websocket-extensions": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
-      "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+      "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
       "dev": true
     },
     "which": {
diff --git a/src/ModernizrProto.js b/src/ModernizrProto.js
index 56e0d7c3..f14c2b08 100644
--- a/src/ModernizrProto.js
+++ b/src/ModernizrProto.js
@@ -6,7 +6,6 @@ define(['tests'], function(tests) {
    * @access public
    */
   var ModernizrProto = {
-    // The current version, dummy
     _version: '__VERSION__',
 
     // Any settings that don't work as separate modules


Test patch:
diff --git a/test/browser/integration/caniuse.js b/test/browser/integration/caniuse.js
index 37138e35..c4fabe10 100644
--- a/test/browser/integration/caniuse.js
+++ b/test/browser/integration/caniuse.js
@@ -66,7 +66,6 @@ window.caniusecb = function(caniuse) {
       cssvwunit: 'viewport-units',
       customelements: 'custom-elementsv1',
       customproperties: 'css-variables',
-      datalistelem: 'datalist',
       dataset: 'dataset',
       datauri: 'datauri',
       details: 'details',
@@ -131,6 +130,7 @@ window.caniusecb = function(caniuse) {
       queryselector: 'queryselector',
       regions: 'css-regions',
       requestanimationframe: 'requestanimationframe',
+      resizeobserver: 'resizeobserver',
       rgba: 'css3-colors',
       ruby: 'ruby',
       sandbox: 'iframe-sandbox',