Skip to content

Instantly share code, notes, and snippets.

@agektmr
Last active Sep 11, 2020
Embed
What would you like to do?
`input[autocomplete="one-time-code"]` polyfill using Web OTP API
if ('customElements' in window && 'OTPCredential' in window) {
  customElements.define("web-otp",
    class extends HTMLInputElement {
      connectedCallback() {
        this.abortController = new AbortController();
        this.receive(); 
      }
      disconnectedCallback() {
        this.abort();
      }
      abort() {
        this.abortController.abort();
      }
      async receive() {
        try {
          const content = await navigator.credentials.get({
            otp: {transport:['sms']}, signal: this.abortController.signal
          });
          this.value = content.code;
          this.dispatchEvent(new Event('autocomplete'));
        } catch (e) {
          console.error(e);
        }
      }
    }, {
      extends: "input"
  });
}
@samthor
Copy link

samthor commented Apr 14, 2020

Thoughts:

  • Rename this.signal to this.abortController
  • navigator.credentials.get accepts signal, not abort, and you then want to pass the .signal property of the AbortController
    • The point is you hold onto AbortController so you can abort it, but only give out the AbortSignal to things that get aborted
  • IIRC Safari doesn't support extending anything but HTMLElement, I'm not sure where the polyfill is for—Chrome or somewhere else?

@agektmr
Copy link
Author

agektmr commented Apr 14, 2020

  • Replaced this.signal with this.abortController
  • Replaced .abort property with .signal. It was a spec issue.

Regarding "polyfill", this is more of making Chrome to work like Safari's declarative behavior.

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