embetter 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,7 +52,7 @@ For the best experience, include an `<a><img>` inside the element. This serves a
52
52
  <!-- YouTube -->
53
53
  <embetter-media youtube-id="l9XdkPsaynk">
54
54
  <a href="https://www.youtube.com/watch?v=l9XdkPsaynk">
55
- <img src="http://img.youtube.com/vi/l9XdkPsaynk/0.jpg" />
55
+ <img src="https://img.youtube.com/vi/l9XdkPsaynk/maxresdefault.jpg" />
56
56
  </a>
57
57
  </embetter-media>
58
58
 
@@ -45,12 +45,11 @@ let m = (
45
45
  }
46
46
 
47
47
  :host([youtube-id]) {
48
- padding-bottom: 56.25%;
49
- height: 0;
48
+ aspect-ratio: 16 / 9;
49
+ }
50
50
 
51
- img {
52
- margin: -9.4% 0;
53
- }
51
+ :host([youtube-id]) img[src$="/0.jpg"] {
52
+ margin: -9.4% 0;
54
53
  }
55
54
 
56
55
  :host([soundcloud-id]),
@@ -149,7 +148,7 @@ class p {
149
148
  return `<iframe class="video" enablejsapi="1" width="${t.w}" height="${t.h}" src="https://www.youtube.com/embed/${t.id}?rel=0&suggestedQuality=hd720&enablejsapi=1${i}${e}" frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowfullscreen allow=autoplay></iframe>`;
150
149
  }
151
150
  static thumbnail(t) {
152
- return "http://img.youtube.com/vi/" + t + "/0.jpg";
151
+ return "https://img.youtube.com/vi/" + t + "/maxresdefault.jpg";
153
152
  }
154
153
  static link(t) {
155
154
  return "https://www.youtube.com/watch?v=" + t;
@@ -193,7 +192,7 @@ class b {
193
192
  }
194
193
  }
195
194
  }
196
- class g {
195
+ class A {
197
196
  static type = "soundcloud";
198
197
  static dataAttribute = "soundcloud-id";
199
198
  static regex = /(?:https?:\/\/)?(?:w{3}\.)?(?:soundcloud\.com|snd\.sc)\/([a-zA-Z0-9_-]*(?:\/sets)?(?:\/groups)?\/[a-zA-Z0-9_-]*)/;
@@ -221,34 +220,7 @@ class g {
221
220
  }
222
221
  }
223
222
  }
224
- class A {
225
- static type = "instagram";
226
- static dataAttribute = "instagram-id";
227
- static regex = /(?:https?:\/\/)?(?:w{3}\.)?(?:instagram\.com|instagr\.am)\/(p|reel|tv)\/([a-zA-Z0-9-_]+)/i;
228
- static normalizePath(t) {
229
- if (!t) return "p/";
230
- const i = String(t).replace(/^\/+|\/+$/g, "");
231
- return /^(p|reel|tv)\/[a-zA-Z0-9-_]+$/i.test(i) ? i : `p/${i}`;
232
- }
233
- static embed(t) {
234
- const i = this.normalizePath(t.id), e = t.captioned === !1 ? "" : "captioned/";
235
- return `<iframe width="100%" height="100%" scrolling="no" frameborder="0" src="https://www.instagram.com/${i}/embed/${e}?cr=1&v=14" allowfullscreen></iframe>`;
236
- }
237
- static thumbnail(t) {
238
- return "";
239
- }
240
- static link(t) {
241
- return `https://www.instagram.com/${this.normalizePath(t)}/`;
242
- }
243
- static buildFromText(t, i) {
244
- const e = t.match(this.regex);
245
- if (e && e[2]) {
246
- const a = `${e[1]}/${e[2]}`, s = this.link(a);
247
- i(a, s, "");
248
- }
249
- }
250
- }
251
- class f {
223
+ class g {
252
224
  static type = "dailymotion";
253
225
  static dataAttribute = "dailymotion-id";
254
226
  static regex = /(?:https?:\/\/)?(?:w{3}\.)?dailymotion\.com\/video\/([a-zA-Z0-9-_]*)/;
@@ -271,7 +243,7 @@ class f {
271
243
  }
272
244
  }
273
245
  }
274
- class y {
246
+ class f {
275
247
  static type = "mixcloud";
276
248
  static dataAttribute = "mixcloud-id";
277
249
  static regex = /(?:https?:\/\/)?(?:w{3}\.)?(?:mixcloud\.com)\/(.*\/.*)/;
@@ -299,7 +271,7 @@ class y {
299
271
  }
300
272
  }
301
273
  }
302
- class w {
274
+ class y {
303
275
  static type = "codepen";
304
276
  static dataAttribute = "codepen-id";
305
277
  static regex = /(?:https?:\/\/)?(?:w{3}\.)?(?:codepen\.io)\/([a-zA-Z0-9_\-%]*\/[a-zA-Z0-9_\-%]*\/[a-zA-Z0-9_\-%]*)/;
@@ -322,7 +294,7 @@ class w {
322
294
  }
323
295
  }
324
296
  }
325
- class v {
297
+ class w {
326
298
  static type = "bandcamp";
327
299
  static dataAttribute = "bandcamp-id";
328
300
  static regex = /(?:https?:\/\/)?(?:w{3}\.)?([a-zA-Z0-9_\-]*\.bandcamp\.com\/(?:album|track)\/[a-zA-Z0-9_\-%]*)/;
@@ -348,7 +320,7 @@ class v {
348
320
  }
349
321
  }
350
322
  }
351
- class $ {
323
+ class v {
352
324
  static type = "giphy";
353
325
  static dataAttribute = "giphy-id";
354
326
  static regex = /(?:https?:\/\/)?(?:w{3}\.)?giphy\.com\/gifs\/([a-zA-Z0-9_\-%]*)/;
@@ -364,8 +336,8 @@ class $ {
364
336
  static buildFromText(t, i) {
365
337
  const e = t.split("/"), a = e[e.length - 1], s = a.split("-"), r = s[s.length - 1];
366
338
  if (r) {
367
- const o = this.link(a), l = this.thumbnail(r);
368
- i(r, o, l);
339
+ const o = this.link(a), n = this.thumbnail(r);
340
+ i(r, o, n);
369
341
  }
370
342
  }
371
343
  }
@@ -391,7 +363,7 @@ class k {
391
363
  }
392
364
  }
393
365
  }
394
- class x {
366
+ class $ {
395
367
  static type = "gif";
396
368
  static dataAttribute = "gif-url";
397
369
  static regex = /(?:https?:\/\/)?(?:w{3}\.)?(.+\.gif)(?:\/|$|\s|\?|#)/;
@@ -412,34 +384,20 @@ class x {
412
384
  }
413
385
  }
414
386
  }
415
- const d = [
416
- p,
417
- b,
418
- g,
419
- A,
420
- f,
421
- y,
422
- w,
423
- v,
424
- $,
425
- // Shadertoy,
426
- // Kuula,
427
- k,
428
- x
429
- ];
387
+ const d = [k, $, p, b, A, g, f, y, w, v];
430
388
  class c extends HTMLElement {
431
389
  defaultThumbnail = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAArwAAAGcAQMAAAABMOGrAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURQAAAKd6PdoAAAA6SURBVHja7cGBAAAAAMOg+VPf4ARVAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAN488AAGP4e1mAAAAAElFTkSuQmCC";
432
390
  static EMBETTER_ACTIVATED = "embetter-activated";
433
391
  connectedCallback() {
434
- this.shadow = this.attachShadow({ mode: "open" }), this.el = this.shadow, this.initComponent(), this.render(), this.checkThumbnail(), this.addListeners(), this.setupMobileObserver();
392
+ setTimeout(() => {
393
+ this.isConnected && (this.shadow || (this.initialHTML = this.innerHTML, this.innerHTML = "", this.shadow = this.attachShadow({ mode: "open" }), this.el = this.shadow ?? this, this.initComponent(), this.render(), this.getElements(), this.checkThumbnail()), this.addListeners());
394
+ }, 0);
435
395
  }
436
396
  disconnectedCallback() {
437
397
  this.unembedMedia(), this.removeAttribute("ready"), this.playButton && this.playButton.removeEventListener("click", this.clickListener), document.removeEventListener(c.EMBETTER_ACTIVATED, this.embedListener), this.observer && (this.observer.disconnect(), this.observer = null);
438
398
  }
439
399
  initComponent() {
440
- this.markup = "embetter-media component not initialized properly.", this.loops = this.hasAttribute("loops"), this.muted = this.hasAttribute("muted"), this.posterURL = null;
441
- const t = this.querySelector("img");
442
- t && t.src && (this.posterURL = t.src), this.innerHTML = "", this.findAndActivateService();
400
+ this.markup = "embetter-media component not initialized properly.", this.loops = this.hasAttribute("loops"), this.muted = this.hasAttribute("muted"), this.findAndActivateService();
443
401
  }
444
402
  getElements() {
445
403
  this.thumbnail = this.el.querySelector("img");
@@ -457,26 +415,25 @@ class c extends HTMLElement {
457
415
  for (let t of d) {
458
416
  let i = t.dataAttribute;
459
417
  if (this.hasAttribute(i)) {
460
- this.service = t, this.serviceType = t.type, this.serviceId = this.getAttribute(i);
461
- let e = this.posterURL || t.thumbnail(this.serviceId);
462
- if (this.markup = this.playerHTML(t.link(this.serviceId), e), t.getData) {
463
- const a = t.link(this.serviceId);
464
- t.getData(a).then((s) => {
465
- const r = typeof s == "string" ? s : s?.thumbnail;
466
- !e && !this.posterURL && r && this.thumbnail && (this.thumbnail.src = r);
467
- });
468
- }
418
+ this.service = t, this.serviceType = t.type, this.serviceId = this.getAttribute(i), this.markup = this.playerHTML(t.link(this.serviceId));
469
419
  break;
470
420
  }
471
421
  }
472
422
  }
423
+ onReady() {
424
+ this.removeAttribute("loading"), this.setAttribute("ready", "");
425
+ }
473
426
  checkThumbnail() {
474
- this.thumbnail && (this.setAttribute("loading", ""), this.thumbnail.onload = () => {
475
- this.removeAttribute("loading"), this.setAttribute("ready", "");
427
+ this.thumbnail && (this.setAttribute("loading", ""), this.thumbnail.complete ? this.onReady() : (this.thumbnail.onload = () => {
428
+ this.onReady();
476
429
  }, this.thumbnail.onerror = () => {
477
- this.thumbnail.src = this.defaultThumbnail, this.removeAttribute("loading"), this.setAttribute("ready", "");
478
- }, setTimeout(() => {
479
- this.thumbnail.height < 50 && (this.thumbnail.src = this.defaultThumbnail), this.removeAttribute("loading"), this.setAttribute("ready", "");
430
+ if (this.thumbnail.src.includes("/maxresdefault.jpg")) {
431
+ this.thumbnail.src = this.thumbnail.src.replace("/maxresdefault.jpg", "/0.jpg");
432
+ return;
433
+ }
434
+ this.thumbnail.src = this.defaultThumbnail, this.onReady();
435
+ }), setTimeout(() => {
436
+ this.thumbnail.height < 50 && (this.thumbnail.src = this.defaultThumbnail), this.onReady();
480
437
  }, 4e3));
481
438
  }
482
439
  setupMobileObserver() {
@@ -526,15 +483,13 @@ class c extends HTMLElement {
526
483
  }
527
484
  return `<embetter-media ${t}="${i}">${s}</embetter-media>`;
528
485
  }
529
- playerHTML(t, i) {
486
+ playerHTML(t) {
530
487
  return (
531
488
  /* html */
532
489
  `
533
- <a href="${t}">
534
- <img src="${i}" />
535
- <div class="embetter-loading"></div>
536
- <div class="embetter-play-button"></div>
537
- </a>
490
+ ${this.initialHTML}
491
+ <div class="embetter-loading"></div>
492
+ <div class="embetter-play-button"></div>
538
493
  `
539
494
  );
540
495
  }
@@ -548,7 +503,7 @@ class c extends HTMLElement {
548
503
  this.el.innerHTML = `
549
504
  ${this.html()}
550
505
  <style>${this.css()}</style>
551
- `, this.getElements();
506
+ `;
552
507
  }
553
508
  static register() {
554
509
  customElements.define("embetter-media", c);
@@ -560,8 +515,8 @@ class c extends HTMLElement {
560
515
  if (e.hasAttribute(s)) {
561
516
  const r = e.getAttribute(s), o = document.createElement("embetter-media");
562
517
  o.setAttribute(a.dataAttribute, r);
563
- const l = e.querySelector("a");
564
- l && o.appendChild(l.cloneNode(!0)), e.hasAttribute("data-loops") && o.setAttribute("loops", ""), e.hasAttribute("data-muted") && o.setAttribute("muted", ""), e.replaceWith(o);
518
+ const n = e.querySelector("a");
519
+ n && o.appendChild(n.cloneNode(!0)), e.hasAttribute("data-loops") && o.setAttribute("loops", ""), e.hasAttribute("data-muted") && o.setAttribute("muted", ""), e.replaceWith(o);
565
520
  break;
566
521
  }
567
522
  }
@@ -572,7 +527,7 @@ class c extends HTMLElement {
572
527
  const a = d[e];
573
528
  if (t.match(a.regex) != null) {
574
529
  a.buildFromText(t, (s, r, o) => {
575
- const l = (h) => {
530
+ const n = (h) => {
576
531
  let u = c.componentHTML(
577
532
  a.dataAttribute,
578
533
  s,
@@ -584,11 +539,11 @@ class c extends HTMLElement {
584
539
  if (!o && a.getData && r) {
585
540
  a.getData(r).then((h) => {
586
541
  const u = typeof h == "string" ? h : h?.thumbnail;
587
- l(u || o);
588
- }).catch(() => l(o));
542
+ n(u || o);
543
+ }).catch(() => n(o));
589
544
  return;
590
545
  }
591
- l(o);
546
+ n(o);
592
547
  });
593
548
  break;
594
549
  }
@@ -43,12 +43,11 @@
43
43
  }
44
44
 
45
45
  :host([youtube-id]) {
46
- padding-bottom: 56.25%;
47
- height: 0;
46
+ aspect-ratio: 16 / 9;
47
+ }
48
48
 
49
- img {
50
- margin: -9.4% 0;
51
- }
49
+ :host([youtube-id]) img[src$="/0.jpg"] {
50
+ margin: -9.4% 0;
52
51
  }
53
52
 
54
53
  :host([soundcloud-id]),
@@ -136,13 +135,11 @@
136
135
  to { transform: rotate(360deg); }
137
136
  }
138
137
 
139
- `;class d{static type="youtube";static dataAttribute="youtube-id";static regex=/(?:.+?)?(?:youtube\.com\/v\/|watch\/|\?v=|\&v=|youtu\.be\/|\/v=|^youtu\.be\/)([a-zA-Z0-9_-]{11})+/;static embed(t){const i=t.autoplay===!0?"&autoplay=1":"",e=t.loops===!0?`&loop=1&playlist=${t.id}`:"";return`<iframe class="video" enablejsapi="1" width="${t.w}" height="${t.h}" src="https://www.youtube.com/embed/${t.id}?rel=0&suggestedQuality=hd720&enablejsapi=1${i}${e}" frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return"http://img.youtube.com/vi/"+t+"/0.jpg"}static link(t){return"https://www.youtube.com/watch?v="+t}static buildFromText(t,i){const e=t.match(this.regex)[1];if(e!=null){const a=this.link(e),s=this.thumbnail(e);i(e,a,s)}}}class b{static type="vimeo";static dataAttribute="vimeo-id";static regex=/(?:vimeo\.com\/(?:video\/)?|player\.vimeo\.com\/video\/)(\d+)/i;static embed(t){const i=t.autoplay===!0?"&autoplay=1":"",e=t.loops===!0?"&loop=1":"";return`<iframe id="${t.id}" src="https://player.vimeo.com/video/${t.id}?title=0&byline=0&portrait=0&color=ffffff&api=1&player_id=${t.id}${i}${e}" width="${t.w}" height="${t.h}" frameborder="0" scrolling="no" webkitallowfullscreen mozallowfullscreen allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return""}static link(t){return"https://vimeo.com/"+t}static getData(t){return new Promise((i,e)=>{const a=`https://vimeo.com/api/v2/video/${t}.json`;fetch(a).then(s=>s.json()).then(s=>i(s[0].thumbnail_large)).catch(()=>i(""))})}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.link(a);this.getData(a).then(r=>{i(a,s,r)})}}}class g{static type="soundcloud";static dataAttribute="soundcloud-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(?:soundcloud\.com|snd\.sc)\/([a-zA-Z0-9_-]*(?:\/sets)?(?:\/groups)?\/[a-zA-Z0-9_-]*)/;static embed(t){const i=t.autoplay===!0?"&auto_play=true":"";return`<iframe width="100%" height="600" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=${encodeURIComponent(`https://soundcloud.com/${t.id}`)}${i}&hide_related=false&color=373737&show_comments=false&show_user=true&show_reposts=false&visual=true" allow="autoplay"></iframe>`}static thumbnail(t){return""}static link(t){return`https://soundcloud.com/${t}`}static getData(t){const i=`/api/soundcloud?url=${encodeURIComponent(t)}&format=json`;return fetch(i).then(e=>e.json()).then(e=>e.thumbnail_url||"").catch(()=>"")}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.link(a);this.getData(s).then(r=>{i(a,s,r)})}}}class A{static type="instagram";static dataAttribute="instagram-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(?:instagram\.com|instagr\.am)\/(p|reel|tv)\/([a-zA-Z0-9-_]+)/i;static normalizePath(t){if(!t)return"p/";const i=String(t).replace(/^\/+|\/+$/g,"");return/^(p|reel|tv)\/[a-zA-Z0-9-_]+$/i.test(i)?i:`p/${i}`}static embed(t){const i=this.normalizePath(t.id),e=t.captioned===!1?"":"captioned/";return`<iframe width="100%" height="100%" scrolling="no" frameborder="0" src="https://www.instagram.com/${i}/embed/${e}?cr=1&v=14" allowfullscreen></iframe>`}static thumbnail(t){return""}static link(t){return`https://www.instagram.com/${this.normalizePath(t)}/`}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[2]){const a=`${e[1]}/${e[2]}`,s=this.link(a);i(a,s,"")}}}class f{static type="dailymotion";static dataAttribute="dailymotion-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?dailymotion\.com\/video\/([a-zA-Z0-9-_]*)/;static embed(t){const i=t.autoplay===!0?"?autoPlay=1":"";return`<iframe class="video" width="${t.w}" height="${t.h}" src="https://www.dailymotion.com/embed/video/${t.id}${i}" frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return`https://www.dailymotion.com/thumbnail/video/${t}`}static link(t){return`https://www.dailymotion.com/video/${t}`}static buildFromText(t,i){t=t.split("_")[0];const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.link(a),r=this.thumbnail(a);i(a,s,r)}}}class y{static type="mixcloud";static dataAttribute="mixcloud-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(?:mixcloud\.com)\/(.*\/.*)/;static embed(t){const i=t.autoplay===!0?"&autoplay=true":"";return`<iframe width="660" height="180" src="https://www.mixcloud.com/widget/iframe/?feed=${encodeURIComponent("https://www.mixcloud.com/"+t.id)}&replace=0&hide_cover=1&stylecolor=ffffff&embed_type=widget_standard${i}" frameborder="0" scrolling="no"></iframe>`}static thumbnail(t){return""}static link(t){return`https://www.mixcloud.com/${t}`}static getData(t){const i=`/api/mixcloud/?url=${encodeURIComponent(t)}&format=json`;return fetch(i).then(e=>e.json()).then(e=>e.image||"").catch(()=>"")}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.link(a);this.getData(s).then(r=>{i(a,s,r)})}}}class w{static type="codepen";static dataAttribute="codepen-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(?:codepen\.io)\/([a-zA-Z0-9_\-%]*\/[a-zA-Z0-9_\-%]*\/[a-zA-Z0-9_\-%]*)/;static embed(t){const i=t.id.replace("/pen/","/embed/"),e=i.split("/")[0],a=i.split("/")[2];return`<iframe src="https://codepen.io/${i}?height=${t.h}&theme-id=0&slug-hash=${a}&default-tab=result&user=${e}" frameborder="0" scrolling="no" allowtransparency="true" allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return`https://codepen.io/${t}/image/large.png`}static link(t){return`https://codepen.io/${t.replace("/embed/","/pen/")}`}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){let a=e[1].replace("/embed/","/pen/");const s=this.link(a),r=this.thumbnail(a);i(a,s,r)}}}class v{static type="bandcamp";static dataAttribute="bandcamp-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?([a-zA-Z0-9_\-]*\.bandcamp\.com\/(?:album|track)\/[a-zA-Z0-9_\-%]*)/;static embed(t){return`<iframe src="https://bandcamp.com/EmbeddedPlayer/${t.id}/size=large/bgcol=ffffff/linkcol=333333/tracklist=true/artwork=small/transparent=true/" frameborder="0" scrolling="no" allowtransparency="true" allowfullscreen seamless></iframe>`}static thumbnail(t){return""}static link(t){return t.match(/^(album|track)=/)?"":`https://${t}`}static getData(t){return fetch(`/api/bandcamp?url=${encodeURIComponent(t)}`).then(i=>i.json()).catch(()=>({id:null,thumbnail:null}))}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const s=`https://${e[1]}`;this.getData(s).then(r=>{r.id&&i(r.id,s,r.thumbnail||"")})}}}class ${static type="giphy";static dataAttribute="giphy-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?giphy\.com\/gifs\/([a-zA-Z0-9_\-%]*)/;static embed(t){return`<iframe width="${t.w}" height="${t.h}" src="https://giphy.com/embed/${t.id}/twitter/iframe" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return`https://media.giphy.com/media/${t}/giphy_s.gif`}static link(t){return`https://giphy.com/gifs/${t}`}static buildFromText(t,i){const e=t.split("/"),a=e[e.length-1],s=a.split("-"),r=s[s.length-1];if(r){const o=this.link(a),c=this.thumbnail(r);i(r,o,c)}}}class k{static type="video";static dataAttribute="video-url";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(.+\.(?:mp4|mov|m4v))(?:\/|$|\s|\?|#)/;static embed(t){const i=t.autoplay===!0?' autoplay="true"':"",e=t.loops===!0?' loop="true"':"",a=t.muted===!0?" muted":"";return`<video src="${t.id}" width="${t.w}" height="${t.h}"${i}${e}${a} controls playsinline webkitallowfullscreen mozallowfullscreen allowfullscreen></video>`}static thumbnail(t){return t.replace(".mp4","-poster.jpg").replace(".mov","-poster.jpg").replace(".m4v","-poster.jpg")}static link(t){return t}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.thumbnail(a);i(a,a,s)}}}class x{static type="gif";static dataAttribute="gif-url";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(.+\.gif)(?:\/|$|\s|\?|#)/;static embed(t){return`<img class="gif" src="${t.id}" width="${t.w}" height="${t.h}">`}static thumbnail(t){return t.replace(".gif","-poster.jpg")}static link(t){return t}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.thumbnail(a);i(a,a,s)}}}const m=[d,b,g,A,f,y,w,v,$,k,x];class l extends HTMLElement{defaultThumbnail="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAArwAAAGcAQMAAAABMOGrAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURQAAAKd6PdoAAAA6SURBVHja7cGBAAAAAMOg+VPf4ARVAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAN488AAGP4e1mAAAAAElFTkSuQmCC";static EMBETTER_ACTIVATED="embetter-activated";connectedCallback(){this.shadow=this.attachShadow({mode:"open"}),this.el=this.shadow,this.initComponent(),this.render(),this.checkThumbnail(),this.addListeners(),this.setupMobileObserver()}disconnectedCallback(){this.unembedMedia(),this.removeAttribute("ready"),this.playButton&&this.playButton.removeEventListener("click",this.clickListener),document.removeEventListener(l.EMBETTER_ACTIVATED,this.embedListener),this.observer&&(this.observer.disconnect(),this.observer=null)}initComponent(){this.markup="embetter-media component not initialized properly.",this.loops=this.hasAttribute("loops"),this.muted=this.hasAttribute("muted"),this.posterURL=null;const t=this.querySelector("img");t&&t.src&&(this.posterURL=t.src),this.innerHTML="",this.findAndActivateService()}getElements(){this.thumbnail=this.el.querySelector("img")}addListeners(){this.clickListener=this.onClick.bind(this),this.playButton=this.el.querySelector(".embetter-play-button"),this.playButton&&this.playButton.addEventListener("click",this.clickListener),this.embedListener=this.onEmbedActivated.bind(this),document.addEventListener(l.EMBETTER_ACTIVATED,this.embedListener)}onClick(t){t.preventDefault(),this.embedMedia()}onEmbedActivated(t){t.detail!==this&&this.unembedMedia()}findAndActivateService(){for(let t of m){let i=t.dataAttribute;if(this.hasAttribute(i)){this.service=t,this.serviceType=t.type,this.serviceId=this.getAttribute(i);let e=this.posterURL||t.thumbnail(this.serviceId);if(this.markup=this.playerHTML(t.link(this.serviceId),e),t.getData){const a=t.link(this.serviceId);t.getData(a).then(s=>{const r=typeof s=="string"?s:s?.thumbnail;!e&&!this.posterURL&&r&&this.thumbnail&&(this.thumbnail.src=r)})}break}}}checkThumbnail(){this.thumbnail&&(this.setAttribute("loading",""),this.thumbnail.onload=()=>{this.removeAttribute("loading"),this.setAttribute("ready","")},this.thumbnail.onerror=()=>{this.thumbnail.src=this.defaultThumbnail,this.removeAttribute("loading"),this.setAttribute("ready","")},setTimeout(()=>{this.thumbnail.height<50&&(this.thumbnail.src=this.defaultThumbnail),this.removeAttribute("loading"),this.setAttribute("ready","")},4e3))}setupMobileObserver(){this.isMobile()&&(this.observer=new IntersectionObserver(t=>{t.forEach(i=>{i.isIntersecting?this.embedMedia(!1):this.unembedMedia()})},{threshold:.3}),this.observer.observe(this))}embedMedia(t){if(document.dispatchEvent(new CustomEvent(l.EMBETTER_ACTIVATED,{bubbles:!0,composed:!0,detail:this})),this.hasAttribute("playing"))return;t===void 0&&(t=this.hasAttribute("autoplay")?this.getAttribute("autoplay")!=="false":!0);let i=this.service.embed({id:this.serviceId,w:this.thumbnail&&this.thumbnail.width||"100%",h:this.thumbnail&&this.thumbnail.height||"100%",autoplay:t,loops:this.loops,muted:this.muted||t});this.playerEl=l.stringToDomElement(i),this.el.appendChild(this.playerEl),this.setAttribute("playing","")}unembedMedia(){this.playerEl!=null&&this.playerEl.parentNode!=null&&this.playerEl.parentNode.removeChild(this.playerEl),this.removeAttribute("playing")}isMobile(){return/iphone|ipad|ipod|android/i.test(navigator.userAgent)}static stringToDomElement(t){var i=document.createElement("div");return i.innerHTML=t,i.firstChild}static componentHTML(t,i,e=null,a=null){let s="";if(a||e){const r=a||"#",o=e?`<img src="${e}">`:"";s=`<a href="${r}">${o}</a>`}return`<embetter-media ${t}="${i}">${s}</embetter-media>`}playerHTML(t,i){return`
140
- <a href="${t}">
141
- <img src="${i}" />
142
- <div class="embetter-loading"></div>
143
- <div class="embetter-play-button"></div>
144
- </a>
138
+ `;class d{static type="youtube";static dataAttribute="youtube-id";static regex=/(?:.+?)?(?:youtube\.com\/v\/|watch\/|\?v=|\&v=|youtu\.be\/|\/v=|^youtu\.be\/)([a-zA-Z0-9_-]{11})+/;static embed(t){const i=t.autoplay===!0?"&autoplay=1":"",e=t.loops===!0?`&loop=1&playlist=${t.id}`:"";return`<iframe class="video" enablejsapi="1" width="${t.w}" height="${t.h}" src="https://www.youtube.com/embed/${t.id}?rel=0&suggestedQuality=hd720&enablejsapi=1${i}${e}" frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return"https://img.youtube.com/vi/"+t+"/maxresdefault.jpg"}static link(t){return"https://www.youtube.com/watch?v="+t}static buildFromText(t,i){const e=t.match(this.regex)[1];if(e!=null){const a=this.link(e),s=this.thumbnail(e);i(e,a,s)}}}class b{static type="vimeo";static dataAttribute="vimeo-id";static regex=/(?:vimeo\.com\/(?:video\/)?|player\.vimeo\.com\/video\/)(\d+)/i;static embed(t){const i=t.autoplay===!0?"&autoplay=1":"",e=t.loops===!0?"&loop=1":"";return`<iframe id="${t.id}" src="https://player.vimeo.com/video/${t.id}?title=0&byline=0&portrait=0&color=ffffff&api=1&player_id=${t.id}${i}${e}" width="${t.w}" height="${t.h}" frameborder="0" scrolling="no" webkitallowfullscreen mozallowfullscreen allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return""}static link(t){return"https://vimeo.com/"+t}static getData(t){return new Promise((i,e)=>{const a=`https://vimeo.com/api/v2/video/${t}.json`;fetch(a).then(s=>s.json()).then(s=>i(s[0].thumbnail_large)).catch(()=>i(""))})}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.link(a);this.getData(a).then(r=>{i(a,s,r)})}}}class A{static type="soundcloud";static dataAttribute="soundcloud-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(?:soundcloud\.com|snd\.sc)\/([a-zA-Z0-9_-]*(?:\/sets)?(?:\/groups)?\/[a-zA-Z0-9_-]*)/;static embed(t){const i=t.autoplay===!0?"&auto_play=true":"";return`<iframe width="100%" height="600" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=${encodeURIComponent(`https://soundcloud.com/${t.id}`)}${i}&hide_related=false&color=373737&show_comments=false&show_user=true&show_reposts=false&visual=true" allow="autoplay"></iframe>`}static thumbnail(t){return""}static link(t){return`https://soundcloud.com/${t}`}static getData(t){const i=`/api/soundcloud?url=${encodeURIComponent(t)}&format=json`;return fetch(i).then(e=>e.json()).then(e=>e.thumbnail_url||"").catch(()=>"")}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.link(a);this.getData(s).then(r=>{i(a,s,r)})}}}class f{static type="dailymotion";static dataAttribute="dailymotion-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?dailymotion\.com\/video\/([a-zA-Z0-9-_]*)/;static embed(t){const i=t.autoplay===!0?"?autoPlay=1":"";return`<iframe class="video" width="${t.w}" height="${t.h}" src="https://www.dailymotion.com/embed/video/${t.id}${i}" frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return`https://www.dailymotion.com/thumbnail/video/${t}`}static link(t){return`https://www.dailymotion.com/video/${t}`}static buildFromText(t,i){t=t.split("_")[0];const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.link(a),r=this.thumbnail(a);i(a,s,r)}}}class g{static type="mixcloud";static dataAttribute="mixcloud-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(?:mixcloud\.com)\/(.*\/.*)/;static embed(t){const i=t.autoplay===!0?"&autoplay=true":"";return`<iframe width="660" height="180" src="https://www.mixcloud.com/widget/iframe/?feed=${encodeURIComponent("https://www.mixcloud.com/"+t.id)}&replace=0&hide_cover=1&stylecolor=ffffff&embed_type=widget_standard${i}" frameborder="0" scrolling="no"></iframe>`}static thumbnail(t){return""}static link(t){return`https://www.mixcloud.com/${t}`}static getData(t){const i=`/api/mixcloud/?url=${encodeURIComponent(t)}&format=json`;return fetch(i).then(e=>e.json()).then(e=>e.image||"").catch(()=>"")}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.link(a);this.getData(s).then(r=>{i(a,s,r)})}}}class y{static type="codepen";static dataAttribute="codepen-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(?:codepen\.io)\/([a-zA-Z0-9_\-%]*\/[a-zA-Z0-9_\-%]*\/[a-zA-Z0-9_\-%]*)/;static embed(t){const i=t.id.replace("/pen/","/embed/"),e=i.split("/")[0],a=i.split("/")[2];return`<iframe src="https://codepen.io/${i}?height=${t.h}&theme-id=0&slug-hash=${a}&default-tab=result&user=${e}" frameborder="0" scrolling="no" allowtransparency="true" allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return`https://codepen.io/${t}/image/large.png`}static link(t){return`https://codepen.io/${t.replace("/embed/","/pen/")}`}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){let a=e[1].replace("/embed/","/pen/");const s=this.link(a),r=this.thumbnail(a);i(a,s,r)}}}class w{static type="bandcamp";static dataAttribute="bandcamp-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?([a-zA-Z0-9_\-]*\.bandcamp\.com\/(?:album|track)\/[a-zA-Z0-9_\-%]*)/;static embed(t){return`<iframe src="https://bandcamp.com/EmbeddedPlayer/${t.id}/size=large/bgcol=ffffff/linkcol=333333/tracklist=true/artwork=small/transparent=true/" frameborder="0" scrolling="no" allowtransparency="true" allowfullscreen seamless></iframe>`}static thumbnail(t){return""}static link(t){return t.match(/^(album|track)=/)?"":`https://${t}`}static getData(t){return fetch(`/api/bandcamp?url=${encodeURIComponent(t)}`).then(i=>i.json()).catch(()=>({id:null,thumbnail:null}))}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const s=`https://${e[1]}`;this.getData(s).then(r=>{r.id&&i(r.id,s,r.thumbnail||"")})}}}class v{static type="giphy";static dataAttribute="giphy-id";static regex=/(?:https?:\/\/)?(?:w{3}\.)?giphy\.com\/gifs\/([a-zA-Z0-9_\-%]*)/;static embed(t){return`<iframe width="${t.w}" height="${t.h}" src="https://giphy.com/embed/${t.id}/twitter/iframe" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowfullscreen allow=autoplay></iframe>`}static thumbnail(t){return`https://media.giphy.com/media/${t}/giphy_s.gif`}static link(t){return`https://giphy.com/gifs/${t}`}static buildFromText(t,i){const e=t.split("/"),a=e[e.length-1],s=a.split("-"),r=s[s.length-1];if(r){const o=this.link(a),c=this.thumbnail(r);i(r,o,c)}}}class k{static type="video";static dataAttribute="video-url";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(.+\.(?:mp4|mov|m4v))(?:\/|$|\s|\?|#)/;static embed(t){const i=t.autoplay===!0?' autoplay="true"':"",e=t.loops===!0?' loop="true"':"",a=t.muted===!0?" muted":"";return`<video src="${t.id}" width="${t.w}" height="${t.h}"${i}${e}${a} controls playsinline webkitallowfullscreen mozallowfullscreen allowfullscreen></video>`}static thumbnail(t){return t.replace(".mp4","-poster.jpg").replace(".mov","-poster.jpg").replace(".m4v","-poster.jpg")}static link(t){return t}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.thumbnail(a);i(a,a,s)}}}class x{static type="gif";static dataAttribute="gif-url";static regex=/(?:https?:\/\/)?(?:w{3}\.)?(.+\.gif)(?:\/|$|\s|\?|#)/;static embed(t){return`<img class="gif" src="${t.id}" width="${t.w}" height="${t.h}">`}static thumbnail(t){return t.replace(".gif","-poster.jpg")}static link(t){return t}static buildFromText(t,i){const e=t.match(this.regex);if(e&&e[1]){const a=e[1],s=this.thumbnail(a);i(a,a,s)}}}const m=[k,x,d,b,A,f,g,y,w,v];class n extends HTMLElement{defaultThumbnail="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAArwAAAGcAQMAAAABMOGrAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURQAAAKd6PdoAAAA6SURBVHja7cGBAAAAAMOg+VPf4ARVAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAN488AAGP4e1mAAAAAElFTkSuQmCC";static EMBETTER_ACTIVATED="embetter-activated";connectedCallback(){setTimeout(()=>{this.isConnected&&(this.shadow||(this.initialHTML=this.innerHTML,this.innerHTML="",this.shadow=this.attachShadow({mode:"open"}),this.el=this.shadow??this,this.initComponent(),this.render(),this.getElements(),this.checkThumbnail()),this.addListeners())},0)}disconnectedCallback(){this.unembedMedia(),this.removeAttribute("ready"),this.playButton&&this.playButton.removeEventListener("click",this.clickListener),document.removeEventListener(n.EMBETTER_ACTIVATED,this.embedListener),this.observer&&(this.observer.disconnect(),this.observer=null)}initComponent(){this.markup="embetter-media component not initialized properly.",this.loops=this.hasAttribute("loops"),this.muted=this.hasAttribute("muted"),this.findAndActivateService()}getElements(){this.thumbnail=this.el.querySelector("img")}addListeners(){this.clickListener=this.onClick.bind(this),this.playButton=this.el.querySelector(".embetter-play-button"),this.playButton&&this.playButton.addEventListener("click",this.clickListener),this.embedListener=this.onEmbedActivated.bind(this),document.addEventListener(n.EMBETTER_ACTIVATED,this.embedListener)}onClick(t){t.preventDefault(),this.embedMedia()}onEmbedActivated(t){t.detail!==this&&this.unembedMedia()}findAndActivateService(){for(let t of m){let i=t.dataAttribute;if(this.hasAttribute(i)){this.service=t,this.serviceType=t.type,this.serviceId=this.getAttribute(i),this.markup=this.playerHTML(t.link(this.serviceId));break}}}onReady(){this.removeAttribute("loading"),this.setAttribute("ready","")}checkThumbnail(){this.thumbnail&&(this.setAttribute("loading",""),this.thumbnail.complete?this.onReady():(this.thumbnail.onload=()=>{this.onReady()},this.thumbnail.onerror=()=>{if(this.thumbnail.src.includes("/maxresdefault.jpg")){this.thumbnail.src=this.thumbnail.src.replace("/maxresdefault.jpg","/0.jpg");return}this.thumbnail.src=this.defaultThumbnail,this.onReady()}),setTimeout(()=>{this.thumbnail.height<50&&(this.thumbnail.src=this.defaultThumbnail),this.onReady()},4e3))}setupMobileObserver(){this.isMobile()&&(this.observer=new IntersectionObserver(t=>{t.forEach(i=>{i.isIntersecting?this.embedMedia(!1):this.unembedMedia()})},{threshold:.3}),this.observer.observe(this))}embedMedia(t){if(document.dispatchEvent(new CustomEvent(n.EMBETTER_ACTIVATED,{bubbles:!0,composed:!0,detail:this})),this.hasAttribute("playing"))return;t===void 0&&(t=this.hasAttribute("autoplay")?this.getAttribute("autoplay")!=="false":!0);let i=this.service.embed({id:this.serviceId,w:this.thumbnail&&this.thumbnail.width||"100%",h:this.thumbnail&&this.thumbnail.height||"100%",autoplay:t,loops:this.loops,muted:this.muted||t});this.playerEl=n.stringToDomElement(i),this.el.appendChild(this.playerEl),this.setAttribute("playing","")}unembedMedia(){this.playerEl!=null&&this.playerEl.parentNode!=null&&this.playerEl.parentNode.removeChild(this.playerEl),this.removeAttribute("playing")}isMobile(){return/iphone|ipad|ipod|android/i.test(navigator.userAgent)}static stringToDomElement(t){var i=document.createElement("div");return i.innerHTML=t,i.firstChild}static componentHTML(t,i,e=null,a=null){let s="";if(a||e){const r=a||"#",o=e?`<img src="${e}">`:"";s=`<a href="${r}">${o}</a>`}return`<embetter-media ${t}="${i}">${s}</embetter-media>`}playerHTML(t){return`
139
+ ${this.initialHTML}
140
+ <div class="embetter-loading"></div>
141
+ <div class="embetter-play-button"></div>
145
142
  `}css(){return h}html(){return this.markup}render(){this.el.innerHTML=`
146
143
  ${this.html()}
147
144
  <style>${this.css()}</style>
148
- `,this.getElements()}static register(){customElements.define("embetter-media",l)}static upgradeLegacyEmbeds(t=document){t.querySelectorAll(".embetter").forEach(e=>{for(const a of m){const s=`data-${a.dataAttribute}`;if(e.hasAttribute(s)){const r=e.getAttribute(s),o=document.createElement("embetter-media");o.setAttribute(a.dataAttribute,r);const c=e.querySelector("a");c&&o.appendChild(c.cloneNode(!0)),e.hasAttribute("data-loops")&&o.setAttribute("loops",""),e.hasAttribute("data-muted")&&o.setAttribute("muted",""),e.replaceWith(o);break}}})}static componentMarkupFromURL(t,i){for(let e=0;e<m.length;e++){const a=m[e];if(t.match(a.regex)!=null){a.buildFromText(t,(s,r,o)=>{const c=u=>{let p=l.componentHTML(a.dataAttribute,s,u,r);i(p,a)};if(!o&&a.getData&&r){a.getData(r).then(u=>{const p=typeof u=="string"?u:u?.thumbnail;c(p||o)}).catch(()=>c(o));return}c(o)});break}}}}return l.register(),l}));
145
+ `}static register(){customElements.define("embetter-media",n)}static upgradeLegacyEmbeds(t=document){t.querySelectorAll(".embetter").forEach(e=>{for(const a of m){const s=`data-${a.dataAttribute}`;if(e.hasAttribute(s)){const r=e.getAttribute(s),o=document.createElement("embetter-media");o.setAttribute(a.dataAttribute,r);const c=e.querySelector("a");c&&o.appendChild(c.cloneNode(!0)),e.hasAttribute("data-loops")&&o.setAttribute("loops",""),e.hasAttribute("data-muted")&&o.setAttribute("muted",""),e.replaceWith(o);break}}})}static componentMarkupFromURL(t,i){for(let e=0;e<m.length;e++){const a=m[e];if(t.match(a.regex)!=null){a.buildFromText(t,(s,r,o)=>{const c=u=>{let p=n.componentHTML(a.dataAttribute,s,u,r);i(p,a)};if(!o&&a.getData&&r){a.getData(r).then(u=>{const p=typeof u=="string"?u:u?.thumbnail;c(p||o)}).catch(()=>c(o));return}c(o)});break}}}}return n.register(),n}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "embetter",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "type": "module",
5
5
  "description": "Lazy-loading iframe embed web component",
6
6
  "main": "dist/embetter-media.umd.js",