Search code examples
javascriptyoutubecustom-elementstenciljs

Adding element to youtube


I am trying to add this custom element to YouTube.

at first, I wrote in the console:

const script1 = document.createElement("script")
script1.type = "module"
script1.src = "https://unpkg.com/[email protected]/dist/pose-viewer/pose-viewer.esm.js"
document.head.appendChild(script1)

and then:

document.createElement('pose-viewer')

but I got this error:

Uncaught TypeError: Class constructor a cannot be invoked without 'new' at new g (custom-elements-es5-adapter.js:11) at :1:10

so I compiled to es5:

const script1 = document.createElement("script")
script1.src = "https://unpkg.com/[email protected]/dist/pose-viewer/pose-viewer.js"
document.head.appendChild(script1)

but I got this error:

Uncaught TypeError: Illegal invocation at n.f (pose-viewer.js:15) at Function.getOwnPropertyDescriptor (pose-viewer.js:15) at pose-viewer.js:44 at pose-viewer.js:58 at pose-viewer.js:130

What I am doing wrong? Why is this not working specifically on YouTube, but does work everywhere else?


Solution

  • If you look at the source of the https://unpkg.com/[email protected]/dist/pose-viewer/pose-viewer.js you'll see that is transpiled to ES5, however the custom elements should be defined in ES6, ex:

    class MyElement extends HtmlElement {}
    

    more info about the adapter here :

    https://www.npmjs.com/package/@webcomponents/webcomponentsjs#custom-elements-es5-adapterjs

    You just need to follow the error message and add this to your html before you run your script:

    <script src="https://unpkg.com/@webcomponents/[email protected]/custom-elements-es5-adapter.js"></script>
    

    Update

    If you are using the esm script, you don't need the adapter as the script is using es6 syntax.

    you can load the script as a module:

    <!DOCTYPE html>
     <html>
    <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width">
          <title>pose viewer example</title>
    </head>
    <body>
    <script src="https://unpkg.com/pose-viewer@latest/dist/pose-viewer/pose-viewer.esm.js" type="module"></script>
    <pose-viewer></pose-viewer>
    </body>
    </html>
    

    Or if you want to import it from another js script you just need to add an import statement

    Where the html might look like this:

    <!DOCTYPE html>
     <html>
    <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width">
          <title>pose viewer example</title>
    </head>
    <body>
    <script src="./index.js" type="module"></script>
    </body>
    </html>
    

    And the script like this :

      import "https://unpkg.com/pose-viewer@latest/dist/pose-viewer/pose-viewer.esm.js";
     const x = document.createElement('pose-viewer');
     document.body.appendChild(x);
    

    Update

    To load it into the youtube website via the console you need to use the new operator, using the esm module the loading part looks like this

     const script = document.createElement('script')
     script.setAttribute('type', 'module');
     script.setAttribute('src', 'https://unpkg.com/[email protected]/dist/pose-viewer/pose-viewer.esm.js' );
     document.body.appendChild(script);
    

    Then get the class from the customElement registry and invoke it with new:

     const PoseViewer = customElements.get('pose-viewer');
     new PoseViewer();