webcomponents / polyfills

Web Components Polyfills
BSD 3-Clause "New" or "Revised" License
1.13k stars 165 forks source link

Polyfill not loaded when upgrade is not a function #565

Open Jeroen-Veltmans opened 8 months ago

Jeroen-Veltmans commented 8 months ago

Description

The polyfill is not loaded when the browser version has CustomElementRegistry.define but doesn't have CustomElementRegistry.upgrade.

Example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
<p id="log"></p>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es2015"></script>
<script>
    // Uncomment below to make it work regardless
    // window.customElements = window.customElements || {};
    // window.customElements.forcePolyfill = true;
</script>
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.8.0/custom-elements-es5-adapter.js"></script>
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.8.0/webcomponents-bundle.js"></script>
<script type="text/javascript">
    "use strict";
    var __extends = (function () {
        var extendStatics = function (d, b) {
            extendStatics = Object.setPrototypeOf ||
                ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
                function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
            return extendStatics(d, b);
        };
        return function (d, b) {
            if (typeof b !== "function" && b !== null)
                throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
            extendStatics(d, b);
            function __() { this.constructor = d; }
            d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
        };
    })();

    var el = document.createElement("spider-man");
    var log = document.querySelector('#log');

    var SpiderMan = /** @class */ (function (_super) {
        __extends(SpiderMan, _super);
        function SpiderMan() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        return SpiderMan;
    }(HTMLElement));
    customElements.define("spider-man", SpiderMan);

    // Expected to be false
    console.log('instance of', (el instanceof SpiderMan)) // not yet upgraded
    log.innerHTML = 'instance of ' + (el instanceof SpiderMan);

    customElements.upgrade(el);
    // Expected to be true
    console.log('instance of', (el instanceof SpiderMan)) // upgraded!
    log.innerHTML = 'instance of ' + (el instanceof SpiderMan);
</script>
</body>
</html>

Steps to reproduce

Launch the app on an older browser that has the define method but not the upgrade method. Check the console logs.

Expected behavior

The polyfill is installed correctly and the code completes without an error being thrown.

Actual behavior

The polyfill isn't installed causing errors (customElements.upgrade is not a function) on browser versions that partly support custom elements.

Version

2.8.0

Browsers affected

Only experienced it on some Smart TVs (Tizen 4.0 which has Chrome v56 and Tizen 5.0 which has Chrome v63), but according to the browser compatibility table Safari would also have this issue.

Looking through the files it seems this part needs an extra check to see if upgrade is defined: https://github.com/webcomponents/polyfills/blob/master/packages/custom-elements/ts_src/custom-elements.ts#L57