{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./app/javascript/packs/lite-yt-embed.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","LiteYTEmbed","_this","_classCallCheck","this","_possibleConstructorReturn","_getPrototypeOf","videoId","encodeURIComponent","getAttribute","posterUrl","concat","addPrefetch","HTMLElement","kind","url","as","linkElem","document","createElement","rel","href","crossorigin","head","append","preconnected","_this2","style","backgroundImage","playBtn","classList","add","addEventListener","warmConnections","once","e","addIframe","iframeHTML","insertAdjacentHTML","customElements","define"],"mappings":"aACA,IAAAA,EAAA,GAGA,SAAAC,EAAAC,GAGA,GAAAF,EAAAE,GACA,OAAAF,EAAAE,GAAAC,QAGA,IAAAC,EAAAJ,EAAAE,GAAA,CACAG,EAAAH,EACAI,GAAA,EACAH,QAAA,IAUA,OANAI,EAAAL,GAAAM,KAAAJ,EAAAD,QAAAC,IAAAD,QAAAF,GAGAG,EAAAE,GAAA,EAGAF,EAAAD,QAKAF,EAAAQ,EAAAF,EAGAN,EAAAS,EAAAV,EAGAC,EAAAU,EAAA,SAAAR,EAAAS,EAAAC,GACAZ,EAAAa,EAAAX,EAAAS,IACAG,OAAAC,eAAAb,EAAAS,EAAA,CAA0CK,YAAA,EAAAC,IAAAL,KAK1CZ,EAAAkB,EAAA,SAAAhB,GACA,qBAAAiB,eAAAC,aACAN,OAAAC,eAAAb,EAAAiB,OAAAC,YAAA,CAAwDC,MAAA,WAExDP,OAAAC,eAAAb,EAAA,cAAiDmB,OAAA,KAQjDrB,EAAAsB,EAAA,SAAAD,EAAAE,GAEA,GADA,EAAAA,IAAAF,EAAArB,EAAAqB,IACA,EAAAE,EAAA,OAAAF,EACA,KAAAE,GAAA,kBAAAF,QAAAG,WAAA,OAAAH,EACA,IAAAI,EAAAX,OAAAY,OAAA,MAGA,GAFA1B,EAAAkB,EAAAO,GACAX,OAAAC,eAAAU,EAAA,WAAyCT,YAAA,EAAAK,UACzC,EAAAE,GAAA,iBAAAF,EAAA,QAAAM,KAAAN,EAAArB,EAAAU,EAAAe,EAAAE,EAAA,SAAAA,GAAgH,OAAAN,EAAAM,IAAqBC,KAAA,KAAAD,IACrI,OAAAF,GAIAzB,EAAA6B,EAAA,SAAA1B,GACA,IAAAS,EAAAT,KAAAqB,WACA,WAA2B,OAAArB,EAAA,SAC3B,WAAiC,OAAAA,GAEjC,OADAH,EAAAU,EAAAE,EAAA,IAAAA,GACAA,GAIAZ,EAAAa,EAAA,SAAAiB,EAAAC,GAAsD,OAAAjB,OAAAkB,UAAAC,eAAA1B,KAAAuB,EAAAC,IAGtD/B,EAAAkC,EAAA,UAIAlC,IAAAmC,EAAA,ohDCtEMC,cACF,SAAAA,IAAc,IAAAC,EAAA,mGAAAC,CAAAC,KAAAH,IACVC,EAAAG,EAAAD,KAAAE,EAAAL,GAAA7B,KAAAgC,QAIKG,QAAUC,mBAAmBN,EAAKO,aAAa,YAkBpDP,EAAKQ,UAAL,0BAAAC,OAA2CT,EAAKK,QAAhD,kBAEAN,EAAYW,YAAY,UAAWV,EAAKQ,UAAW,SAzBzCR,2PADQW,uDAqDHC,EAAMC,EAAKC,GAC1B,IAAMC,EAAWC,SAASC,cAAc,QACxCF,EAASG,IAAMN,EACfG,EAASI,KAAON,EACZC,IACAC,EAASD,GAAKA,GAElBC,EAASK,aAAc,EACvBJ,SAASK,KAAKC,OAAOP,6CAajBhB,EAAYwB,eAGhBxB,EAAYW,YAAY,aAAc,oCAEtCX,EAAYW,YAAY,aAAc,0BAGtCX,EAAYW,YAAY,aAAc,uCACtCX,EAAYW,YAAY,aAAc,kCAEtCX,EAAYwB,cAAe,oDAvDX,IAAAC,EAAAtB,KAChBA,KAAKuB,MAAMC,gBAAX,QAAAjB,OAAqCP,KAAKM,UAA1C,MAEA,IAAMmB,EAAUX,SAASC,cAAc,OACvCU,EAAQC,UAAUC,IAAI,eACtB3B,KAAKoB,OAAOK,GAGZzB,KAAK4B,iBAAiB,cAAe/B,EAAYgC,gBAAiB,CAACC,MAAM,IAKzE9B,KAAK4B,iBAAiB,QAAS,SAAAG,GAAC,OAAIT,EAAKU,kDA8CzC,IAAMC,EAAU,wMAAA1B,OAGwBP,KAAKG,QAH7B,8DAKhBH,KAAKkC,mBAAmB,YAAaD,GACrCjC,KAAK0B,UAAUC,IAAI,sDAI3BQ,eAAeC,OAAO,eAAgBvC","file":"js/lite-yt-embed-627840ea014dbaadfccf.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/packs/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 48);\n","/**\n * A lightweight youtube embed. Still should feel the same to the user, just MUCH faster to initialize and paint.\n *\n * Thx to these as the inspiration\n * https://storage.googleapis.com/amp-vs-non-amp/youtube-lazy.html\n * https://autoplay-youtube-player.glitch.me/\n *\n * Once built it, I also found these:\n * https://github.com/ampproject/amphtml/blob/master/extensions/amp-youtube (👍👍)\n * https://github.com/Daugilas/lazyYT\n * https://github.com/vb/lazyframe\n */\nclass LiteYTEmbed extends HTMLElement {\n constructor() {\n super();\n\n // Gotta encode the untrusted value\n // https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#rule-2---attribute-escape-before-inserting-untrusted-data-into-html-common-attributes\n this.videoId = encodeURIComponent(this.getAttribute('videoid'));\n\n /**\n * Lo, the youtube placeholder image! (aka the thumbnail, poster image, etc)\n * There is much internet debate on the reliability of thumbnail URLs. Weak consensus is that you\n * cannot rely on anything and have to use the YouTube Data API.\n *\n * amp-youtube also eschews using the API, so they just try sddefault with a hqdefault fallback:\n * https://github.com/ampproject/amphtml/blob/6039a6317325a8589586e72e4f98c047dbcbf7ba/extensions/amp-youtube/0.1/amp-youtube.js#L498-L537\n * For now I'm gonna go with this confident (lol) assertion: https://stackoverflow.com/a/20542029, though I'll use `i.ytimg` to optimize for origin reuse.\n *\n * Worth noting that sddefault is _higher_ resolution than hqdefault. Naming is hard. ;)\n * From my own testing, it appears that hqdefault is ALWAYS there sddefault is missing for ~10% of videos\n *\n * TODO: Do the sddefault->hqdefault fallback\n * - When doing this, apply referrerpolicy (https://github.com/ampproject/amphtml/pull/3940)\n * TODO: Consider using webp if supported, falling back to jpg\n */\n this.posterUrl = `https://i.ytimg.com/vi/${this.videoId}/hqdefault.jpg`;\n // Warm the connection for the poster image\n LiteYTEmbed.addPrefetch('preload', this.posterUrl, 'image');\n // TODO: support dynamically setting the attribute via attributeChangedCallback\n }\n\n connectedCallback() {\n this.style.backgroundImage = `url(\"${this.posterUrl}\")`;\n\n const playBtn = document.createElement('div');\n playBtn.classList.add('lty-playbtn');\n this.append(playBtn);\n\n // On hover (or tap), warm up the TCP connections we're (likely) about to use.\n this.addEventListener('pointerover', LiteYTEmbed.warmConnections, {once: true});\n\n // Once the user clicks, add the real iframe and drop our play button\n // TODO: In the future we could be like amp-youtube and silently swap in the iframe during idle time\n // We'd want to only do this for in-viewport or near-viewport ones: https://github.com/ampproject/amphtml/pull/5003\n this.addEventListener('click', e => this.addIframe());\n }\n\n // // TODO: Support the the user changing the [videoid] attribute\n // attributeChangedCallback() {\n // }\n\n /**\n * Add a to the head\n */\n static addPrefetch(kind, url, as) {\n const linkElem = document.createElement('link');\n linkElem.rel = kind;\n linkElem.href = url;\n if (as) {\n linkElem.as = as;\n }\n linkElem.crossorigin = true;\n document.head.append(linkElem);\n }\n\n /**\n * Begin pre-connecting to warm up the iframe load\n * Since the embed's network requests load within its iframe,\n * preload/prefetch'ing them outside the iframe will only cause double-downloads.\n * So, the best we can do is warm up a few connections to origins that are in the critical path.\n *\n * Maybe `` would work, but it's unsupported: http://crbug.com/593267\n * But TBH, I don't think it'll happen soon with Site Isolation and split caches adding serious complexity.\n */\n static warmConnections() {\n if (LiteYTEmbed.preconnected) return;\n\n // The iframe document and most of its subresources come right off youtube.com\n LiteYTEmbed.addPrefetch('preconnect', 'https://www.youtube-nocookie.com');\n // The botguard script is fetched off from google.com\n LiteYTEmbed.addPrefetch('preconnect', 'https://www.google.com');\n\n // Not certain if these ad related domains are in the critical path. Could verify with domain-specific throttling.\n LiteYTEmbed.addPrefetch('preconnect', 'https://googleads.g.doubleclick.net');\n LiteYTEmbed.addPrefetch('preconnect', 'https://static.doubleclick.net');\n\n LiteYTEmbed.preconnected = true;\n }\n\n addIframe(){\n const iframeHTML = `\n`;\n this.insertAdjacentHTML('beforeend', iframeHTML);\n this.classList.add('lyt-activated');\n }\n}\n// Register custome element\ncustomElements.define('lite-youtube', LiteYTEmbed);\n"],"sourceRoot":""}