media-chrome
Advanced tools
Comparing version 0.0.9 to 0.0.10
@@ -1,1 +0,1 @@ | ||
function e(e,n){window.customElements.get(e)||(window.customElements.define(e,n),window[n.name]=n)}class n extends HTMLElement{constructor(){super(),this._media=null}static get observedAttributes(){return["media"].concat(super.observedAttributes||[])}attributeChangedCallback(e,n,t){if("media"!=e)"boolean"==typeof this[e]?this[e]=null!==t:this[e]=t;else{if(null===t)return void(this.media=null);let e=document.querySelector(t);if(!e||!e.play)throw new Error("Supplied media attribute does not appear to match a media element.");this.media=e}}set media(e){e!==this._media&&(this._media&&this.mediaUnsetCallback(this._media),this._media=e,this.shadowRoot.querySelectorAll("*").forEach(t=>{t instanceof n&&(t.media=e)}),this.mediaSetCallback(e))}get media(){return this._media}connectedCallback(){}mediaSetCallback(){}mediaUnsetCallback(){}get mediaChrome(){return this.media.closest("media-chrome")}}e("media-chrome-element",n);const t=document.createElement("template");t.innerHTML='\n<style>\n :host {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n box-sizing: border-box;\n background-color: transparent;\n\n /* Default width and height can be overridden externally */\n height: 44px;\n width: 44px;\n\n /* Vertically center any text */\n font-size: 14px;\n line-height: 1;\n font-weight: bold;\n\n /* Min icon size is 24x24 */\n min-height: 24px;\n min-width: 24px;\n\n transition: background-color 0.15s linear;\n }\n\n :host(:focus, :focus-within) {\n outline: 2px solid rgba(0,150,255, 0.33);\n outline-offset: -2px;\n }\n\n :host(:hover) {\n background: rgba(255,255,255, 0.10);\n }\n\n button {\n width: 100%;\n height: 100%;\n vertical-align: middle;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: none;\n background: transparent;\n color: #ffffff;\n font-family: sans-serif;\n font-size: 14px;\n line-height: 24px;\n font-weight: bold;\n font-family: Arial, sans-serif;\n cursor: pointer;\n text-align: center;\n -webkit-appearance: none;\n -moz-appearance: none;\n }\n\n button:hover {}\n button:focus {\n outline: 0;\n }\n button:active {}\n\n svg {\n width: var(--media-button-icon-width);\n height: var(--media-button-icon-height);\n transform: var(--media-button-icon-transform);\n transition: var(--media-button-icon-transition);\n }\n\n svg .icon {\n fill: var(--media-icon-color, #eee);\n }\n</style>\n<button id="icon-container">\n <slot></slot>\n</button>\n';class i extends n{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(t.content.cloneNode(!0)),this.iconContainer=this.shadowRoot.querySelector("#icon-container"),this.addEventListener("click",e=>{this.onClick(e)})}onClick(){}set icon(e){this.iconContainer.innerHTML=e}}e("media-chrome-button",i);const a=document.createElement("template");a.innerHTML='\n<style>\n :host {\n position: relative;\n display: block;\n vertical-align: middle;\n box-sizing: border-box;\n background-color: #333;\n\n /* Default width and height can be overridden externally */\n height: 30px;\n\n /* Vertically center any text */\n font-size: 14px;\n line-height: 24px;\n\n /* Min icon size is 24x24 */\n min-height: 24px;\n min-width: 100px;\n\n padding: 3px 10px 3px 30px;\n }\n\n :host(:focus, :focus-within) {\n outline: 2px solid rgba(0,150,255, 0.33);\n outline-offset: -2px;\n }\n\n :host(:hover) {\n background: rgba(255,255,255, 0.10);\n }\n</style>\n\n<div id="labelContainer">\n <slot></slot>\n</div>\n<div id="contentContainer">\n <slot name="content"></slot>\n</div>\n';class o extends n{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(a.content.cloneNode(!0)),this.contentConatiner=this.shadowRoot.querySelector("#contentContainer"),this.addEventListener("click",e=>{this.onClick(e)})}onClick(){}}e("media-chrome-menuitem",o);const s=document.createElement("template");s.innerHTML='\n<style>\n #menuPositioner {\n position: absolute;\n display: flex;\n\n border: 1px solid #f00;\n\n /* Align menu top and centered */\n top: 0;\n align-items: center;\n justify-content: center;\n width: 100%;\n }\n\n #menuContainer {\n display: none;\n position: absolute;\n bottom: 0;\n align: center;\n margin-bottom: 20px;\n\n border: 1px solid #999;\n background-color: #111;\n }\n\n slot[name=menu] {\n\n }\n</style>\n\n<div id="menuPositioner">\n <div id="menuContainer">\n <slot name="menu"></slot>\n </div>\n</div>\n';e("media-chrome-menu-button",class extends i{constructor(){super(),this.shadowRoot.prepend(s.content.cloneNode(!0)),this.menuContainer=this.shadowRoot.querySelector("#menuContainer"),this.attributes.expanded&&(this.menuContainer.style.display="flex")}onClick(e){this.attributes.expanded?(this.removeAttribute("expanded"),this.menuContainer.style.display="none"):(this.setAttribute("expanded","expanded"),this.menuContainer.style.display="flex")}mediaSetCallback(e){}});const r=document.createElement("template");r.innerHTML='\n<style>\n :host {\n background-position: right 9px center;\n background-repeat: no-repeat;\n background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTAwJSIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgMzIgMzIiIHdpZHRoPSIxMDAlIj48cGF0aCBkPSJtIDEyLjU5LDIwLjM0IDQuNTgsLTQuNTkgLTQuNTgsLTQuNTkgMS40MSwtMS40MSA2LDYgLTYsNiB6IiBmaWxsPSIjZmZmIiAvPjwvc3ZnPg==)\n }\n\n ::slotted([slot=menu]) {\n position: absolute;\n display: block;\n left: 0;\n top: 0;\n width: 100%;\n border: 1px solid #00f;\n }\n</style>\n\n<div id="menuContainer">\n <slot name="menu"></slot>\n</div>\n';e("media-chrome-submenu-menuitem",class extends o{constructor(){super(),this.shadowRoot.appendChild(r.content.cloneNode(!0)),this.menu=this.querySelector("[slot=menu]"),this.menu.style.display="none"}onClick(){"block"==this.menu.style.display?this.menu.style.display="none":this.menu.style.display="block"}});const d=document.createElement("template");d.innerHTML="\n <style>\n :host {\n display: block;\n position: relative;\n width: 100%;\n border: 1px solid #f00;\n background-color: #000;\n }\n </style>\n <slot></slot>\n";e("media-chrome-menu",class extends n{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(d.content.cloneNode(!0))}mediaSetCallback(e){}});const l=document.createElement("template");l.innerHTML="\n <style>\n :host {\n display: block;\n position: absolute;\n width: 300px;\n height: 200px;\n padding: 10px;\n border: 1px solid #333;\n color: #fff;\n background-color: #000;\n }\n </style>\n <slot></slot>\n";function c(e,n){e=e<0?0:e;let t=Math.floor(e%60),i=Math.floor(e/60%60),a=Math.floor(e/3600);const o=Math.floor(n/60%60),s=Math.floor(n/3600);return(isNaN(e)||e===1/0)&&(a=i=t="-"),a=a>0||s>0?a+":":"",i=((a||o>=10)&&i<10?"0"+i:i)+":",t=t<10?"0"+t:t,a+i+t}e("media-chrome-popup",class extends n{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(l.content.cloneNode(!0))}mediaSetCallback(e){}mediaUnsetCallback(){}});const h=document.createElement("template");h.innerHTML='\n <style>\n :host {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n\n background-color: transparent;\n\n /* Default width and height can be overridden externally */\n height: 44px;\n\n box-sizing: border-box;\n padding: 0 5px;\n\n /* Min icon size is 24x24 */\n min-height: 24px;\n min-width: 24px;\n\n /* Vertically center any text */\n font-size: 16px;\n line-height: 24px;\n font-family: sans-serif;\n text-align: center;\n color: #ffffff;\n }\n\n #container {}\n </style>\n <div id="container"></div>\n';e("media-current-time-display",class extends n{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(h.content.cloneNode(!0)),this.container=this.shadowRoot.querySelector("#container"),this.update(6e3)}update(e){this.container.innerHTML=c(e)}mediaSetCallback(e){e.addEventListener("timeupdate",n=>{this.update(e.currentTime)}),this.update(e.currentTime)}mediaUnsetCallback(){this.update(0)}});const m=document.createElement("template");m.innerHTML='\n <style>\n :host {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n\n background-color: transparent;\n\n /* Default width and height can be overridden externally */\n height: 44px;\n\n box-sizing: border-box;\n padding: 0 5px;\n\n /* Min icon size is 24x24 */\n min-height: 24px;\n min-width: 24px;\n\n /* Vertically center any text */\n font-size: 16px;\n line-height: 24px;\n font-family: sans-serif;\n text-align: center;\n color: #ffffff;\n }\n\n #container {}\n </style>\n <div id="container"></div>\n';e("media-duration-display",class extends n{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(m.content.cloneNode(!0)),this.container=this.shadowRoot.querySelector("#container"),this.update(0)}update(e){this.container.innerHTML=c(e)}mediaSetCallback(e){e.addEventListener("durationchange",n=>{this.update(e.duration)}),this.update(e.duration)}mediaUnsetCallback(){this.update(0)}});e("media-forward-button",class extends i{constructor(){super(),this.icon='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><defs><path class="icon" id="a" d="M24 24H0V0h24v24z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path class="icon" d="M9.6 13.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.9-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5zM4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8z" clip-path="url(#b)"/></svg>'}onClick(e){const n=this.media;n.currentTime=n.currentTime+30}});const u='\n<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n <path d="M0 0h24v24H0z" fill="none"/>\n <path class="icon" d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>\n</svg>\n',p={enter:"requestFullscreen",exit:"exitFullscreen",event:"fullscreenchange",element:"fullscreenElement",error:"fullscreenerror"};void 0===document.fullscreenElement&&(p.enter="webkitRequestFullScreen",p.exit=null!=document.webkitExitFullscreen?"webkitExitFullscreen":"webkitCancelFullScreen",p.event="webkitfullscreenchange",p.element="webkitFullscreenElement",p.error="webkitfullscreenerror");e("media-fullscreen-button",class extends i{constructor(){super(),this.icon=u,document.addEventListener(p.event,()=>{this.mediaChrome==document[p.element]?this.icon='\n<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n <path d="M0 0h24v24H0z" fill="none"/>\n <path class="icon" d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/>\n</svg>\n':this.icon=u})}onClick(){this.mediaChrome==document[p.element]?document[p.exit]():(document.pictureInPictureElement&&document.exitPictureInPicture(),this.mediaChrome[p.enter]())}});const g='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/><path d="M0 0h24v24H0z" fill="none"/></svg>';e("media-mute-button",class extends i{constructor(){super(),this.icon=g}onClick(e){const n=this.media;n.muted=!n.muted,n.muted||0!==n.volume||(n.volume=.25)}update(){const e=this.media;e.muted||0===e.volume?this.icon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/><path d="M0 0h24v24H0z" fill="none"/></svg>':e.volume<.5?this.icon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>':this.icon=g}mediaSetCallback(e){e.addEventListener("volumechange",this.update.bind(this)),this.update()}});e("media-pip-button",class extends i{constructor(){super(),this.icon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z"/><path d="M0 0h24v24H0z" fill="none"/></svg>',this.addEventListener("click",e=>{const n=this.media;document.pictureInPictureElement?document.exitPictureInPicture():(this.mediaChrome==document.fullscreenElement&&document.exitFullscreen(),n.requestPictureInPicture())})}});const b='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/></svg>';e("media-play-button",class extends i{constructor(){super(),this.icon=b,this._playing=!1}static get observedAttributes(){return["playing"].concat(super.observedAttributes||[])}get playing(){return this._playing}set playing(e){this._playing=!!e,this.icon=e?'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/><path d="M0 0h24v24H0z" fill="none"/></svg>':b}onClick(e){const n=this.media;if(!n)throw new Error("No media was found and an alternative onClick handler was not set.");n.paused?n.play():n.pause()}mediaSetCallback(){this.media&&(this.media.addEventListener("play",()=>{this.playing=!0}),this.media.addEventListener("pause",()=>{this.playing=!1}))}});const v=document.createElement("template"),w="\n height: var(--thumb-height);\n width: var(--media-range-thumb-width, 10px);\n border: var(--media-range-thumb-border, none);\n border-radius: var(--media-range-thumb-border-radius, 10px);\n background: var(--media-range-thumb-background, #fff);\n box-shadow: var(--media-range-thumb-box-shadow, 1px 1px 1px transparent);\n cursor: pointer;\n",f="\n width: 100%;\n min-width: 40px;\n height: var(--track-height);\n border: var(--media-range-track-border, none);\n border-radius: var(--media-range-track-border-radius, 0);\n background: var(--media-range-track-background-internal, --media-range-track-background, #eee);\n\n box-shadow: var(--media-range-track-box-shadow, none);\n transition: var(--media-range-track-transition, none);\n cursor: pointer;\n";v.innerHTML=`\n <style>\n :host {\n --thumb-height: var(--media-range-thumb-height, 10px);\n --track-height: var(--media-range-track-height, 4px);\n\n position: relative;\n display: inline-block;\n vertical-align: middle;\n box-sizing: border-box;\n background-color: transparent;\n transition: background-color 0.15s linear;\n height: 44px;\n width: 100px;\n min-height: 24px;\n font-size: 16px;\n line-height: 24px;\n padding: 0 10px;\n }\n\n :host(:focus, :focus-within) {\n outline: 2px solid rgba(0,150,255, 0.33);\n outline-offset: -2px;\n }\n\n :host(:hover) {\n background: rgba(255,255,255, 0.10);\n }\n\n input[type=range] {\n /* Reset */\n -webkit-appearance: none; /* Hides the slider so that custom slider can be made */\n background: transparent; /* Otherwise white in Chrome */\n\n /* Fill host with the range */\n height: 100%;\n width: 100%; /* Specific width is required for Firefox. */\n\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n\n /* Special styling for WebKit/Blink */\n input[type=range]::-webkit-slider-thumb {\n -webkit-appearance: none;\n ${w}\n /* You need to specify a margin in Chrome, but in Firefox and IE it is automatic */\n margin-top: calc(calc(0px - var(--thumb-height) + var(--track-height)) / 2);\n transition: margin .2s ease;\n }\n input[type=range]::-moz-range-thumb { ${w} }\n\n input[type=range]::-webkit-slider-runnable-track { ${f} }\n input[type=range]::-moz-range-track { ${f} }\n input[type=range]::-ms-track {\n /* Reset */\n width: 100%;\n cursor: pointer;\n /* Hides the slider so custom styles can be added */\n background: transparent;\n border-color: transparent;\n color: transparent;\n\n ${f}\n }\n\n /* Eventually want to move towards different styles for focus-visible\n https://github.com/WICG/focus-visible/blob/master/src/focus-visible.js\n Youtube appears to do this by de-focusing a button after a button click */\n input[type=range]:focus {\n outline: 0;\n }\n input[type=range]:focus::-webkit-slider-runnable-track {\n outline: 0;\n }\n\n input[type=range]:disabled::-webkit-slider-thumb {\n background-color: #777;\n }\n\n input[type=range]:disabled::-webkit-slider-runnable-track {\n background-color: #777;\n }\n\n </style>\n <input id="range" type="range" min="0" max="1000" step="1" value="0">\n`;class x extends n{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(v.content.cloneNode(!0)),this.range=this.shadowRoot.querySelector("#range"),this.range.addEventListener("input",this.updateBar.bind(this))}connectedCallback(){this.updateBar()}updateBar(){const e=this.getBarColors();let n="linear-gradient(to right, ",t=0;e.forEach(e=>{e[1]<t||(n+=`${e[0]} ${t}%, ${e[0]} ${e[1]}%,`,t=e[1])}),n=n.slice(0,n.length-1)+")",this.style.setProperty("--media-range-track-background-internal",n)}getBarColors(){this.range;return[["var(--media-range-bar-color, #fff)",this.range.value/1e3*100],["var(--media-range-track-background, #333)",100]]}}e("media-chrome-range",x);const y=document.createElement("template");y.innerHTML='\n <style>\n :host {\n box-sizing: border-box;\n background-color: #000;\n width: 284px;\n height: 160px;\n overflow: hidden;\n }\n\n img {\n position: absolute;\n left: 0;\n top: 0;\n }\n </style>\n <img crossorigin loading="eager" decoding="async" />\n';class k extends n{static get observedAttributes(){return["time"].concat(super.observedAttributes||[])}constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(y.content.cloneNode(!0))}set time(e){if(this.media&&this.media.textTracks&&this.media.textTracks.length){let n=Array.prototype.find.call(this.media.textTracks,e=>"thumbnails"==e.label);if(!n)return;let t=Array.prototype.find.call(n.cues,n=>n.startTime>=e);if(t){const e=new URL(t.text),[n,i,a,o]=e.hash.split("=")[1].split(","),s=this.shadowRoot.querySelector("img"),r=e.origin+e.pathname,d=this.offsetWidth/a,l=()=>{s.style.width=`${d*s.naturalWidth}px`,s.style.height=`${d*s.naturalHeight}px`};s.src!==r&&(s.onload=l,s.src=r,l()),l(),s.style.left=`-${d*n}px`,s.style.top=`-${d*i}px`}}}get time(){return parseFloat(this.getAttribute("time"))}mediaSetCallback(e){const n=e&&e.textTracks;n&&n.addEventListener&&(this._trackChangeHandler=e=>{for(let e=0;e<n.length;e++){"thumbnails"===n[e].label&&(this.time||(this.time=0))}},n.addEventListener("addtrack",this._trackChangeHandler,!1),this._trackChangeHandler())}mediaUnsetCallback(e){const n=e&&e.textTracks;n&&n.removeEventListener&&n.removeEventListener("addtrack",this._trackChangeHandler)}}window.customElements.get("media-thumbnail-preview")||(window.customElements.define("media-thumbnail-preview",k),window.MediaThumbnailPreviewElement=k);const C=document.createElement("template");C.innerHTML='\n <style>\n #thumbnailContainer {\n display: none;\n position: absolute;\n top: 0;\n }\n\n media-thumbnail-preview {\n position: absolute;\n bottom: 10px;\n border: 2px solid #fff;\n border-radius: 2px;\n background-color: #000;\n width: 160px;\n height: 90px;\n\n /* Negative offset of half to center on the handle */\n margin-left: -80px;\n }\n\n /* Can\'t get this working. Trying a downward triangle. */\n /* media-thumbnail-preview::after {\n content: "";\n display: block;\n width: 300px;\n height: 300px;\n margin: 100px;\n background-color: #ff0;\n } */\n\n :host(:hover) #thumbnailContainer.enabled {\n display: block;\n animation: fadeIn ease 0.5s;\n }\n\n @keyframes fadeIn {\n 0% {\n /* transform-origin: bottom center; */\n /* transform: scale(0.7); */\n margin-top: 10px;\n opacity: 0;\n }\n 100% {\n /* transform-origin: bottom center; */\n /* transform: scale(1); */\n margin-top: 0;\n opacity: 1;\n }\n }\n </style>\n <div id="thumbnailContainer">\n <media-thumbnail-preview></media-thumbnail-preview>\n </div>\n';e("media-progress-range",class extends x{static get observedAttributes(){return["thumbnails"].concat(super.observedAttributes||[])}constructor(){super(),this.shadowRoot.appendChild(C.content.cloneNode(!0)),this.setMediaTimeWithRange=()=>{const e=this.media,n=this.range;(e.readyState>0||void 0===e.readyState)&&(e.currentTime=Math.round(n.value/1e3*e.duration))},this.range.addEventListener("input",this.setMediaTimeWithRange),this.updateRangeWithMediaTime=()=>{const e=this.media;this.range.value=Math.round(e.currentTime/e.duration*1e3),this.updateBar()},this.playIfNotReady=e=>{this.range.removeEventListener("change",this.playIfNotReady),this.media.play().then(this.setMediaTimeWithRange)}}mediaSetCallback(e){super.mediaSetCallback(e);this.range;if(e.addEventListener("timeupdate",this.updateRangeWithMediaTime),void 0!==e.readyState&&e.readyState,e.addEventListener("progress",this.updateBar.bind(this)),e.textTracks&&e.textTracks.length){Array.prototype.find.call(e.textTracks,e=>"thumbnails"==e.label)?this.enableThumbnails():this.thumbnailPreview.style.display="none"}}mediaUnsetCallback(e){super.mediaUnsetCallback(e),e.removeEventListener("timeupdate",this.updateRangeWithMediaTime),this.range.removeEventListener("change",this.playIfNotReady)}getBarColors(){const e=this.media;let n=super.getBarColors();if(!e||!e.buffered||!e.buffered.length||e.duration<=0)return n;const t=e.buffered,i=t.end(t.length-1)/e.duration*100;return n.splice(1,0,["var(--media-progress-buffered-color, #777)",i]),n}enableThumbnails(){let e;this.thumbnailPreview=this.shadowRoot.querySelector("media-thumbnail-preview"),this.shadowRoot.querySelector("#thumbnailContainer").classList.add("enabled");const n=()=>{e=e=>{if(!(this.media&&this.media.duration))return;const n=this.range.getBoundingClientRect();let t=(e.clientX-n.left)/n.width;t=Math.max(0,Math.min(1,t));const i=n.left-this.getBoundingClientRect().left+t*n.width;this.thumbnailPreview.style.left=`${i}px`,this.thumbnailPreview.time=t*this.media.duration},window.addEventListener("mousemove",e,!1)};let t=!1;this.addEventListener("mousemove",i=>{if(!t&&this.media&&this.media.duration){t=!0,this.thumbnailPreview.style.display="block",n();let i=n=>{n.target==this||this.contains(n.target)||(this.thumbnailPreview.style.display="none",window.removeEventListener("mousemove",i),t=!1,window.removeEventListener("mousemove",e))};window.addEventListener("mousemove",i,!1)}this.media&&this.media.duration||(this.thumbnailPreview.style.display="none")},!1)}disableThumbnails(){thumbnailContainer.classList.remove("enabled")}});e("media-replay-button",class extends i{constructor(){super(),this.icon='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><defs><path class="icon" id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path class="icon" d="M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-2.4 8.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.8-.8v-.5c0-.1-.1-.2-.1-.3s-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z" clip-path="url(#b)"/></svg>'}onClick(e){const n=this.media;n.currentTime=n.currentTime-30}});const L=document.createElement("template");L.innerHTML='\n <style>\n :host {\n display: block;\n position: absolute;\n width: 300px;\n height: auto;\n right: 5px;\n bottom: 45px;\n padding: 10px;\n border: 1px solid #333;\n color: #ccc;\n background-color: #000;\n }\n </style>\n <slot></slot>\n\n \x3c!-- This is too much for a menu... --\x3e\n\n <media-chrome-panel>\n <media-chrome-menu>\n <media-chrome-submenu-menuitem label="Playback speed" value="1.2">\n </media-chrome-submenu-menuitem>\n <media-chrome-menuitem>Hello1</media-chrome-menuitem>\n <media-chrome-menuitem>Hello1</media-chrome-menuitem>\n <media-chrome-menuitem>Hello1</media-chrome-menuitem>\n <media-chrome-menuitem>Hello1</media-chrome-menuitem>\n </media-chrome-menu>\n <media-chrome-menu slot="menu">\n <media-chrome-menuitem>Normal</media-chrome-menuitem>\n <media-chrome-menuitem>1.5</media-chrome-menuitem>\n </media-chrome-menu>\n';e("media-settings-popup",class extends n{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(L.content.cloneNode(!0))}mediaSetCallback(e){}mediaUnsetCallback(){}});e("media-volume-range",class extends x{constructor(){super(),this.range.addEventListener("input",()=>{const e=this.media;if(!e)return;const n=this.range.value/1e3;e.volume=n,n>0&&e.muted&&(e.muted=!1)}),this.range.addEventListener("mousedown",()=>{const e=this.media&&this.media.volume;e>0&&(this._lastNonZeroVolume=e)}),this.range.addEventListener("change",()=>{const e=this.media;if(e){0==e.volume&&(e.muted=!0,e.volume=this._lastNonZeroVolume||1);try{window.localStorage.setItem("media-chrome-pref-volume",e.volume.toString())}catch(e){}}})}mediaSetCallback(e){this._handleVolumeChange=this._updateRange.bind(this),e.addEventListener("volumechange",this._handleVolumeChange);try{const n=window.localStorage.getItem("media-chrome-pref-volume");null!==n&&(e.volume=n)}catch(e){}this._updateRange()}mediaUnsetCallback(e){e.removeEventListener("volumechange",this._handleVolumeChange)}_updateRange(){const e=this.media,n=this.range;e.muted?n.value=0:n.value=Math.round(1e3*e.volume),this.updateBar()}});const M=document.createElement("template");M.innerHTML="\n <style>\n :host {\n /* Need position to display above video for some reason */\n position: relative;\n box-sizing: border-box;\n display: flex;\n\n /* All putting the progress range at full width on other lines */\n flex-wrap: wrap;\n\n width: 100%;\n color: var(--media-icon-color, #eee);\n\n background-color: var(--media-control-bar-background, rgba(20,20,30, 0.7));\n }\n\n ::slotted(*), :host > * {\n /* position: relative; */\n }\n\n media-progress-range,\n ::slotted(media-progress-range) {\n flex-grow: 1;\n }\n </style>\n\n <slot></slot>\n";const E=document.createElement("template");E.innerHTML="\n <media-play-button>Play</media-play-button>\n <media-mute-button>Mute</media-mute-button>\n <media-volume-range>Volume</media-volume-range>\n <media-progress-range>Progress</media-progress-range>\n <media-pip-button>PIP</media-pip-button>\n <media-fullscreen-button>Fullscreen</media-fullscreen-button>\n";e("media-control-bar",class extends n{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(M.content.cloneNode(!0))}connectedCallback(){this.attributes.defaultControls&&this.shadowRoot.appendChild(E.content.cloneNode(!0))}});const z=[1,1.25,1.5,1.75,2];e("media-playback-rate-button",class extends i{constructor(){super(),this._rates=z}static get observedAttributes(){return["rates"].concat(super.observedAttributes||[])}set rates(e){e?("string"==typeof e&&(e=e.split(/,\s?/)),this._rates=e):this._rates=z}get rates(){return this._rates}onClick(e){const n=this.media;if(!n)return;const t=n.playbackRate;let i=this.rates.find(e=>e>t);i||(i=this.rates[0]),n.playbackRate=i}mediaSetCallback(e){e&&(this._rateChangeHandler=()=>{const n=e.playbackRate.toString().substring(0,4);this.shadowRoot.querySelector("button").innerHTML=`${n}x`},e.addEventListener("ratechange",this._rateChangeHandler),this._rateChangeHandler())}mediaUnsetCallback(e){e&&e.removeEventListener("ratechange",this._rateChangeHandler)}});const T=document.createElement("template");T.innerHTML='\n <style>\n :host {\n box-sizing: border-box;\n position: relative;\n display: flex;\n width: 720px;\n height: 480px;\n background-color: #000;\n flex-direction: column-reverse;\n }\n\n :host(:-webkit-full-screen) {\n /* Needs to use !important otherwise easy to break */\n width: 100% !important;\n height: 100% !important;\n }\n\n ::slotted([slot=media]) {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: #000;\n }\n\n #container ::slotted(*) {\n opacity: 1;\n transition: opacity 0.25s;\n visibility: visible;\n }\n\n /* Hide controls when inactive and not paused */\n #container.inactive:not(.paused) ::slotted(*) {\n opacity: 0;\n transition: opacity 1s;\n }\n </style>\n <slot name="media"></slot>\n <div id="container">\n <slot></slot>\n <slot name="controls"></slot>\n </div>\n';const H=document.createElement("template");H.innerHTML="\n <media-control-bar>\n <media-play-button>Play</media-play-button>\n <media-mute-button>Mute</media-mute-button>\n <media-volume-range>Volume</media-volume-range>\n <media-progress-range>Progress</media-progress-range>\n <media-pip-button>PIP</media-pip-button>\n <media-fullscreen-button>Fullscreen</media-fullscreen-button>\n </media-control-bar>\n";class S extends HTMLElement{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(T.content.cloneNode(!0)),this.container=this.shadowRoot.getElementById("container"),this._media=null;new MutationObserver((function(e,t){for(let t of e)"childList"===t.type&&(t.removedNodes.forEach(e=>{e.media===this.media&&(e.media=null)}),t.addedNodes.forEach(e=>{e instanceof n&&!e.media&&(e.media=this.media)}))})).observe(this,{childList:!0,subtree:!0})}get media(){return this._media}set media(e){if(this._media=e,e){this.addEventListener("click",e=>{const n=this.media;"media"==e.target.slot&&(n.paused?n.play():n.pause())}),this.container.classList.add("paused"),e.addEventListener("play",()=>{this.container.classList.remove("paused")}),e.addEventListener("pause",()=>{this.container.classList.add("paused")});const n=e.nodeName.toLowerCase();"audio"==n||"video"==n?t.call(this,e):window.customElements.whenDefined(n).then(()=>{t.call(this,e)})}function t(e){this.querySelectorAll("*").forEach(e=>{e instanceof n&&(e.media=this.media)}),this.shadowRoot.querySelectorAll("*").forEach(e=>{e instanceof n&&(e.media=this.media)})}}connectedCallback(){new MutationObserver((e,n)=>{}).observe(this,{childList:!0}),this.attributes.defaultControls&&this.container.appendChild(H.content.cloneNode(!0));let e=this.querySelector("[slot=media]");e&&(this.media=e);const n=()=>{this.container.classList.remove("inactive"),window.clearTimeout(this.inactiveTimeout),this.inactiveTimeout=window.setTimeout(()=>{this.container.classList.add("inactive")},2e3)};this.addEventListener("keyup",e=>{n()}),this.addEventListener("mousemove",e=>{e.target!==this&&(this.container.classList.remove("inactive"),window.clearTimeout(this.inactiveTimeout),e.target===this.media&&n())}),this.addEventListener("mouseout",e=>{this.container.classList.add("inactive")})}}e("media-chrome",S); | ||
function e(e,t){window.customElements.get(e)||(window.customElements.define(e,t),window[t.name]=t)}class t extends HTMLElement{constructor(){super(),this._media=null}static get observedAttributes(){return["media"].concat(super.observedAttributes||[])}attributeChangedCallback(e,t,n){if("media"!=e)"boolean"==typeof this[e]?this[e]=null!==n:this[e]=n;else{if(null===n)return void(this.media=null);let e=document.querySelector(n);if(!e||!e.play)throw new Error("Supplied media attribute does not appear to match a media element.");this.media=e}}set media(e){e!==this._media&&(this._media&&this.mediaUnsetCallback(this._media),this._media=e,this.shadowRoot.querySelectorAll("*").forEach(n=>{n instanceof t&&(n.media=e)}),e&&this.mediaSetCallback(e))}get media(){return this._media}connectedCallback(){}mediaSetCallback(){}mediaUnsetCallback(){}get mediaChrome(){return this.media.closest("media-chrome")}}e("media-chrome-html-element",t);const n=document.createElement("template");n.innerHTML='\n<style>\n :host {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n box-sizing: border-box;\n background-color: transparent;\n\n /* Default width and height can be overridden externally */\n height: 44px;\n width: 44px;\n\n /* Vertically center any text */\n font-size: 14px;\n line-height: 1;\n font-weight: bold;\n\n /* Min icon size is 24x24 */\n min-height: 24px;\n min-width: 24px;\n\n transition: background-color 0.15s linear;\n }\n\n /*\n Only show outline when keyboard focusing.\n https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo\n */\n :host-context(.media-focus-visible):host(:focus, :focus-within) {\n box-shadow: inset 0 0 0 2px rgba(27, 127, 204, 0.8);\n }\n\n :host(:hover) {\n background: rgba(255,255,255, 0.10);\n }\n\n button {\n width: 100%;\n height: 100%;\n vertical-align: middle;\n border: none;\n margin: 0;\n padding: 0;\n text-decoration: none;\n background: transparent;\n color: #ffffff;\n font-family: sans-serif;\n font-size: 14px;\n line-height: 24px;\n font-weight: bold;\n font-family: Arial, sans-serif;\n cursor: pointer;\n text-align: center;\n -webkit-appearance: none;\n -moz-appearance: none;\n }\n\n button:hover {}\n button:focus {\n outline: 0;\n }\n button:active {}\n\n svg {\n width: var(--media-button-icon-width);\n height: var(--media-button-icon-height);\n transform: var(--media-button-icon-transform);\n transition: var(--media-button-icon-transition);\n }\n\n svg .icon {\n fill: var(--media-icon-color, #eee);\n }\n</style>\n<button id="container">\n <slot></slot>\n</button>\n';class i extends t{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(n.content.cloneNode(!0)),this.container=this.shadowRoot.querySelector("#container"),this.addEventListener("click",e=>{this.onClick(e)})}onClick(){}set icon(e){this.container.innerHTML=e}}e("media-chrome-button",i);const a='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/></svg>';e("media-play-button",class extends i{constructor(){super(),this.icon=a,this._playing=!1}static get observedAttributes(){return["playing"].concat(super.observedAttributes||[])}get playing(){return this._playing}set playing(e){this._playing=!!e,this.icon=e?'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/><path d="M0 0h24v24H0z" fill="none"/></svg>':a}onClick(e){const t=this.media;if(!t)throw new Error("No media was found and an alternative onClick handler was not set.");t.paused?t.play():t.pause()}mediaSetCallback(e){e.addEventListener("play",()=>{this.playing=!0}),e.addEventListener("pause",()=>{this.playing=!1})}});e("media-forward-button",class extends i{constructor(){super(),this.icon='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><defs><path class="icon" id="a" d="M24 24H0V0h24v24z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path class="icon" d="M9.6 13.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.9-.8v-.5s-.1-.2-.1-.3-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5zM4 13c0 4.4 3.6 8 8 8s8-3.6 8-8h-2c0 3.3-2.7 6-6 6s-6-2.7-6-6 2.7-6 6-6v4l5-5-5-5v4c-4.4 0-8 3.6-8 8z" clip-path="url(#b)"/></svg>'}onClick(e){const t=this.media;t.currentTime=t.currentTime+30}});e("media-replay-button",class extends i{constructor(){super(),this.icon='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24" viewBox="0 0 24 24"><defs><path class="icon" id="a" d="M0 0h24v24H0V0z"/></defs><clipPath id="b"><use xlink:href="#a" overflow="visible"/></clipPath><path class="icon" d="M12 5V1L7 6l5 5V7c3.3 0 6 2.7 6 6s-2.7 6-6 6-6-2.7-6-6H4c0 4.4 3.6 8 8 8s8-3.6 8-8-3.6-8-8-8zm-2.4 8.5h.4c.2 0 .4-.1.5-.2s.2-.2.2-.4v-.2s-.1-.1-.1-.2-.1-.1-.2-.1h-.5s-.1.1-.2.1-.1.1-.1.2v.2h-1c0-.2 0-.3.1-.5s.2-.3.3-.4.3-.2.4-.2.4-.1.5-.1c.2 0 .4 0 .6.1s.3.1.5.2.2.2.3.4.1.3.1.5v.3s-.1.2-.1.3-.1.2-.2.2-.2.1-.3.2c.2.1.4.2.5.4s.2.4.2.6c0 .2 0 .4-.1.5s-.2.3-.3.4-.3.2-.5.2-.4.1-.6.1c-.2 0-.4 0-.5-.1s-.3-.1-.5-.2-.2-.2-.3-.4-.1-.4-.1-.6h.8v.2s.1.1.1.2.1.1.2.1h.5s.1-.1.2-.1.1-.1.1-.2v-.5s-.1-.1-.1-.2-.1-.1-.2-.1h-.6v-.7zm5.7.7c0 .3 0 .6-.1.8l-.3.6s-.3.3-.5.3-.4.1-.6.1-.4 0-.6-.1-.3-.2-.5-.3-.2-.3-.3-.6-.1-.5-.1-.8v-.7c0-.3 0-.6.1-.8l.3-.6s.3-.3.5-.3.4-.1.6-.1.4 0 .6.1.3.2.5.3.2.3.3.6.1.5.1.8v.7zm-.8-.8v-.5c0-.1-.1-.2-.1-.3s-.1-.1-.2-.2-.2-.1-.3-.1-.2 0-.3.1l-.2.2s-.1.2-.1.3v2s.1.2.1.3.1.1.2.2.2.1.3.1.2 0 .3-.1l.2-.2s.1-.2.1-.3v-1.5z" clip-path="url(#b)"/></svg>'}onClick(e){const t=this.media;t.currentTime=t.currentTime-30}});const s=document.createElement("template");s.innerHTML='\n <style>\n :host {\n box-sizing: border-box;\n background-color: #000;\n width: 284px;\n height: 160px;\n overflow: hidden;\n }\n\n img {\n position: absolute;\n left: 0;\n top: 0;\n }\n </style>\n <img crossorigin loading="eager" decoding="async" />\n';class o extends t{static get observedAttributes(){return["time"].concat(super.observedAttributes||[])}constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(s.content.cloneNode(!0))}set time(e){if(this.media&&this.media.textTracks&&this.media.textTracks.length){let t=Array.prototype.find.call(this.media.textTracks,e=>"thumbnails"==e.label);if(!t)return;let n=Array.prototype.find.call(t.cues,t=>t.startTime>=e);if(n){const e=new URL(n.text),[t,i,a,s]=e.hash.split("=")[1].split(","),o=this.shadowRoot.querySelector("img"),r=e.origin+e.pathname,d=this.offsetWidth/a,l=()=>{o.style.width=`${d*o.naturalWidth}px`,o.style.height=`${d*o.naturalHeight}px`};o.src!==r&&(o.onload=l,o.src=r,l()),l(),o.style.left=`-${d*t}px`,o.style.top=`-${d*i}px`}}}get time(){return parseFloat(this.getAttribute("time"))}mediaSetCallback(e){const t=e&&e.textTracks;t&&t.addEventListener&&(this._trackChangeHandler=e=>{for(let e=0;e<t.length;e++){"thumbnails"===t[e].label&&(this.time||(this.time=0))}},t.addEventListener("addtrack",this._trackChangeHandler,!1),this._trackChangeHandler())}mediaUnsetCallback(e){const t=e&&e.textTracks;t&&t.removeEventListener&&t.removeEventListener("addtrack",this._trackChangeHandler)}}window.customElements.get("media-thumbnail-preview")||(window.customElements.define("media-thumbnail-preview",o),window.MediaThumbnailPreviewElement=o);const r=document.createElement("template"),d="\n height: var(--thumb-height);\n width: var(--media-range-thumb-width, 10px);\n border: var(--media-range-thumb-border, none);\n border-radius: var(--media-range-thumb-border-radius, 10px);\n background: var(--media-range-thumb-background, #fff);\n box-shadow: var(--media-range-thumb-box-shadow, 1px 1px 1px transparent);\n cursor: pointer;\n transition: var(--media-range-thumb-transition, none);\n transform: var(--media-range-thumb-transform, none);\n opacity: var(--media-range-thumb-opacity, 1);\n",l="\n width: var(--media-range-track-width, 100%);\n min-width: 40px;\n height: var(--track-height);\n border: var(--media-range-track-border, none);\n border-radius: var(--media-range-track-border-radius, 0);\n background: var(--media-range-track-background-internal, --media-range-track-background, #eee);\n\n box-shadow: var(--media-range-track-box-shadow, none);\n transition: var(--media-range-track-transition, none);\n cursor: pointer;\n";r.innerHTML=`\n <style>\n :host {\n --thumb-height: var(--media-range-thumb-height, 10px);\n --track-height: var(--media-range-track-height, 4px);\n\n position: relative;\n display: inline-block;\n vertical-align: middle;\n box-sizing: border-box;\n background-color: transparent;\n transition: background-color 0.15s linear;\n height: 44px;\n width: 100px;\n min-height: 24px;\n font-size: 16px;\n line-height: 24px;\n padding: 0 10px;\n }\n\n /*\n Only show outline when keyboard focusing.\n https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo\n */\n :host-context(.media-focus-visible):host(:focus, :focus-within) {\n box-shadow: inset 0 0 0 2px rgba(27, 127, 204, 0.8);\n }\n\n :host(:hover) {\n background: rgba(255,255,255, 0.10);\n }\n\n input[type=range] {\n /* Reset */\n -webkit-appearance: none; /* Hides the slider so that custom slider can be made */\n background: transparent; /* Otherwise white in Chrome */\n\n /* Fill host with the range */\n height: 100%;\n width: var(--media-range-track-width, 100%); /* Specific width is required for Firefox. */\n\n box-sizing: border-box;\n padding: 0;\n margin: 0;\n }\n\n /* Special styling for WebKit/Blink */\n input[type=range]::-webkit-slider-thumb {\n -webkit-appearance: none;\n ${d}\n /* You need to specify a margin in Chrome, but in Firefox and IE it is automatic */\n margin-top: calc(calc(0px - var(--thumb-height) + var(--track-height)) / 2);\n }\n input[type=range]::-moz-range-thumb { ${d} }\n\n input[type=range]::-webkit-slider-runnable-track { ${l} }\n input[type=range]::-moz-range-track { ${l} }\n input[type=range]::-ms-track {\n /* Reset */\n width: 100%;\n cursor: pointer;\n /* Hides the slider so custom styles can be added */\n background: transparent;\n border-color: transparent;\n color: transparent;\n\n ${l}\n }\n\n /* Eventually want to move towards different styles for focus-visible\n https://github.com/WICG/focus-visible/blob/master/src/focus-visible.js\n Youtube appears to do this by de-focusing a button after a button click */\n input[type=range]:focus {\n outline: 0;\n }\n input[type=range]:focus::-webkit-slider-runnable-track {\n outline: 0;\n }\n\n input[type=range]:disabled::-webkit-slider-thumb {\n background-color: #777;\n }\n\n input[type=range]:disabled::-webkit-slider-runnable-track {\n background-color: #777;\n }\n\n </style>\n <input id="range" type="range" min="0" max="1000" step="1" value="0">\n`;class h extends t{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(r.content.cloneNode(!0)),this.range=this.shadowRoot.querySelector("#range"),this.range.addEventListener("input",this.updateBar.bind(this))}connectedCallback(){this.updateBar()}updateBar(){const e=this.getBarColors();let t="linear-gradient(to right, ",n=0;e.forEach(e=>{e[1]<n||(t+=`${e[0]} ${n}%, ${e[0]} ${e[1]}%,`,n=e[1])}),t=t.slice(0,t.length-1)+")",this.style.setProperty("--media-range-track-background-internal",t)}getBarColors(){this.range;return[["var(--media-range-bar-color, #fff)",this.range.value/1e3*100],["var(--media-range-track-background, #333)",100]]}}e("media-chrome-range",h);const c=document.createElement("template");c.innerHTML='\n <style>\n #thumbnailContainer {\n display: none;\n position: absolute;\n top: 0;\n }\n\n media-thumbnail-preview {\n position: absolute;\n bottom: 10px;\n border: 2px solid #fff;\n border-radius: 2px;\n background-color: #000;\n width: 160px;\n height: 90px;\n\n /* Negative offset of half to center on the handle */\n margin-left: -80px;\n }\n\n /* Can\'t get this working. Trying a downward triangle. */\n /* media-thumbnail-preview::after {\n content: "";\n display: block;\n width: 300px;\n height: 300px;\n margin: 100px;\n background-color: #ff0;\n } */\n\n :host(:hover) #thumbnailContainer.enabled {\n display: block;\n animation: fadeIn ease 0.5s;\n }\n\n @keyframes fadeIn {\n 0% {\n /* transform-origin: bottom center; */\n /* transform: scale(0.7); */\n margin-top: 10px;\n opacity: 0;\n }\n 100% {\n /* transform-origin: bottom center; */\n /* transform: scale(1); */\n margin-top: 0;\n opacity: 1;\n }\n }\n </style>\n <div id="thumbnailContainer">\n <media-thumbnail-preview></media-thumbnail-preview>\n </div>\n';e("media-progress-range",class extends h{static get observedAttributes(){return["thumbnails"].concat(super.observedAttributes||[])}constructor(){super(),this.shadowRoot.appendChild(c.content.cloneNode(!0)),this.setMediaTimeWithRange=()=>{const e=this.media,t=this.range;(e.readyState>0||void 0===e.readyState)&&(e.currentTime=Math.round(t.value/1e3*e.duration))},this.range.addEventListener("input",this.setMediaTimeWithRange),this.updateRangeWithMediaTime=()=>{const e=this.media;this.range.value=Math.round(e.currentTime/e.duration*1e3),this.updateBar()},this.playIfNotReady=e=>{this.range.removeEventListener("change",this.playIfNotReady),this.media.play().then(this.setMediaTimeWithRange)}}mediaSetCallback(e){super.mediaSetCallback(e);this.range;if(e.addEventListener("timeupdate",this.updateRangeWithMediaTime),void 0!==e.readyState&&e.readyState,e.addEventListener("progress",this.updateBar.bind(this)),e.textTracks&&e.textTracks.length){Array.prototype.find.call(e.textTracks,e=>"thumbnails"==e.label)?this.enableThumbnails():this.thumbnailPreview.style.display="none"}}mediaUnsetCallback(e){super.mediaUnsetCallback(e),e.removeEventListener("timeupdate",this.updateRangeWithMediaTime),this.range.removeEventListener("change",this.playIfNotReady)}getBarColors(){const e=this.media;let t=super.getBarColors();if(!e||!e.buffered||!e.buffered.length||e.duration<=0)return t;const n=e.buffered,i=n.end(n.length-1)/e.duration*100;return t.splice(1,0,["var(--media-progress-buffered-color, #777)",i]),t}enableThumbnails(){let e;this.thumbnailPreview=this.shadowRoot.querySelector("media-thumbnail-preview"),this.shadowRoot.querySelector("#thumbnailContainer").classList.add("enabled");const t=()=>{e=e=>{if(!(this.media&&this.media.duration))return;const t=this.range.getBoundingClientRect();let n=(e.clientX-t.left)/t.width;n=Math.max(0,Math.min(1,n));const i=t.left-this.getBoundingClientRect().left+n*t.width;this.thumbnailPreview.style.left=`${i}px`,this.thumbnailPreview.time=n*this.media.duration},window.addEventListener("mousemove",e,!1)};let n=!1;this.addEventListener("mousemove",i=>{if(!n&&this.media&&this.media.duration){n=!0,this.thumbnailPreview.style.display="block",t();let i=t=>{t.target==this||this.contains(t.target)||(this.thumbnailPreview.style.display="none",window.removeEventListener("mousemove",i),n=!1,window.removeEventListener("mousemove",e))};window.addEventListener("mousemove",i,!1)}this.media&&this.media.duration||(this.thumbnailPreview.style.display="none")},!1)}disableThumbnails(){thumbnailContainer.classList.remove("enabled")}});const m='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/><path d="M0 0h24v24H0z" fill="none"/></svg>';e("media-mute-button",class extends i{constructor(){super(),this.icon=m}onClick(e){const t=this.media;t.muted=!t.muted,t.muted||0!==t.volume||(t.volume=.25)}update(){const e=this.media;e.muted||0===e.volume?this.icon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/><path d="M0 0h24v24H0z" fill="none"/></svg>':e.volume<.5?this.icon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M18.5 12c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM5 9v6h4l5 5V4L9 9H5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>':this.icon=m}mediaSetCallback(e){e.addEventListener("volumechange",this.update.bind(this)),this.update()}});function u(e,t){e=e<0?0:e;let n=Math.floor(e%60),i=Math.floor(e/60%60),a=Math.floor(e/3600);const s=Math.floor(t/60%60),o=Math.floor(t/3600);return(isNaN(e)||e===1/0)&&(a=i=n="-"),a=a>0||o>0?a+":":"",i=((a||s>=10)&&i<10?"0"+i:i)+":",n=n<10?"0"+n:n,a+i+n}e("media-volume-range",class extends h{constructor(){super(),this.range.addEventListener("input",()=>{const e=this.media;if(!e)return;const t=this.range.value/1e3;e.volume=t,t>0&&e.muted&&(e.muted=!1)}),this.range.addEventListener("mousedown",()=>{const e=this.media&&this.media.volume;e>0&&(this._lastNonZeroVolume=e)}),this.range.addEventListener("change",()=>{const e=this.media;if(e){0==e.volume&&(e.muted=!0,e.volume=this._lastNonZeroVolume||1);try{window.localStorage.setItem("media-chrome-pref-volume",e.volume.toString())}catch(e){}}})}mediaSetCallback(e){this._handleVolumeChange=this._updateRange.bind(this),e.addEventListener("volumechange",this._handleVolumeChange);try{const t=window.localStorage.getItem("media-chrome-pref-volume");null!==t&&(e.volume=t)}catch(e){}this._updateRange()}mediaUnsetCallback(e){e.removeEventListener("volumechange",this._handleVolumeChange)}_updateRange(){const e=this.media,t=this.range;e.muted?t.value=0:t.value=Math.round(1e3*e.volume),this.updateBar()}});const p=document.createElement("template");p.innerHTML='\n <style>\n :host {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n\n background-color: transparent;\n\n /* Default width and height can be overridden externally */\n height: 44px;\n\n box-sizing: border-box;\n padding: 0 5px;\n\n /* Min icon size is 24x24 */\n min-height: 24px;\n min-width: 24px;\n\n /* Vertically center any text */\n font-size: 16px;\n line-height: 24px;\n font-family: sans-serif;\n text-align: center;\n color: #ffffff;\n }\n\n #container {}\n </style>\n <div id="container"></div>\n';e("media-current-time-display",class extends t{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(p.content.cloneNode(!0)),this.container=this.shadowRoot.querySelector("#container"),this.update(6e3)}update(e){this.container.innerHTML=u(e)}mediaSetCallback(e){e.addEventListener("timeupdate",t=>{this.update(e.currentTime)}),this.update(e.currentTime)}mediaUnsetCallback(){this.update(0)}});const g=document.createElement("template");g.innerHTML='\n <style>\n :host {\n display: inline-flex;\n justify-content: center;\n align-items: center;\n\n background-color: transparent;\n\n /* Default width and height can be overridden externally */\n height: 44px;\n\n box-sizing: border-box;\n padding: 0 5px;\n\n /* Min icon size is 24x24 */\n min-height: 24px;\n min-width: 24px;\n\n /* Vertically center any text */\n font-size: 16px;\n line-height: 24px;\n font-family: sans-serif;\n text-align: center;\n color: #ffffff;\n }\n\n #container {}\n </style>\n <div id="container"></div>\n';e("media-duration-display",class extends t{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(g.content.cloneNode(!0)),this.container=this.shadowRoot.querySelector("#container"),this.update(0)}update(e){this.container.innerHTML=u(e)}mediaSetCallback(e){e.addEventListener("durationchange",t=>{this.update(e.duration)}),this.update(e.duration)}mediaUnsetCallback(){this.update(0)}});const v=[1,1.25,1.5,1.75,2];e("media-playback-rate-button",class extends i{constructor(){super(),this._rates=v}static get observedAttributes(){return["rates"].concat(super.observedAttributes||[])}set rates(e){e?("string"==typeof e&&(e=e.split(/,\s?/)),this._rates=e):this._rates=v}get rates(){return this._rates}onClick(e){const t=this.media;if(!t)return;const n=t.playbackRate;let i=this.rates.find(e=>e>n);i||(i=this.rates[0]),t.playbackRate=i}mediaSetCallback(e){this._rateChangeHandler=()=>{const t=e.playbackRate.toString().substring(0,4);this.shadowRoot.querySelector("button").innerHTML=`${t}x`},e.addEventListener("ratechange",this._rateChangeHandler),this._rateChangeHandler()}mediaUnsetCallback(e){e&&e.removeEventListener("ratechange",this._rateChangeHandler)}});const b='\n<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n <path d="M0 0h24v24H0z" fill="none"/>\n <path class="icon" d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/>\n</svg>\n',w={enter:"requestFullscreen",exit:"exitFullscreen",event:"fullscreenchange",element:"fullscreenElement",error:"fullscreenerror"};void 0===document.fullscreenElement&&(w.enter="webkitRequestFullScreen",w.exit=null!=document.webkitExitFullscreen?"webkitExitFullscreen":"webkitCancelFullScreen",w.event="webkitfullscreenchange",w.element="webkitFullscreenElement",w.error="webkitfullscreenerror");e("media-fullscreen-button",class extends i{constructor(){super(),this.icon=b,document.addEventListener(w.event,()=>{this.mediaChrome==document[w.element]?this.icon='\n<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">\n <path d="M0 0h24v24H0z" fill="none"/>\n <path class="icon" d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/>\n</svg>\n':this.icon=b})}onClick(){this.mediaChrome.getRootNode()[w.element]==this.mediaChrome?document[w.exit]():(document.pictureInPictureElement&&document.exitPictureInPicture(),this.mediaChrome[w.enter]())}});e("media-pip-button",class extends i{constructor(){super(),this.icon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path class="icon" d="M19 7h-8v6h8V7zm2-4H3c-1.1 0-2 .9-2 2v14c0 1.1.9 1.98 2 1.98h18c1.1 0 2-.88 2-1.98V5c0-1.1-.9-2-2-2zm0 16.01H3V4.98h18v14.03z"/><path d="M0 0h24v24H0z" fill="none"/></svg>',this.addEventListener("click",e=>{const t=this.media;document.pictureInPictureElement?document.exitPictureInPicture():(this.mediaChrome==document.fullscreenElement&&document.exitFullscreen(),t.requestPictureInPicture())})}});const f=document.createElement("template");f.innerHTML="\n <style>\n :host {\n\n }\n </style>\n\n <slot></slot>\n";e("media-title-bar",class extends t{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(f.content.cloneNode(!0))}});const x=document.createElement("template");x.innerHTML="\n <style>\n :host {\n /* Need position to display above video for some reason */\n position: relative;\n box-sizing: border-box;\n display: flex;\n\n /* All putting the progress range at full width on other lines */\n flex-wrap: wrap;\n\n width: 100%;\n color: var(--media-icon-color, #eee);\n\n background-color: var(--media-control-bar-background, rgba(20,20,30, 0.7));\n }\n\n ::slotted(*), :host > * {\n /* position: relative; */\n }\n\n media-progress-range,\n ::slotted(media-progress-range) {\n flex-grow: 1;\n }\n </style>\n\n <slot></slot>\n";e("media-control-bar",class extends t{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(x.content.cloneNode(!0))}connectedCallback(){}});const y=document.createElement("template");y.innerHTML='\n <style>\n :host {\n box-sizing: border-box;\n position: relative;\n display: flex;\n width: 720px;\n height: 480px;\n background-color: #000;\n\n /* Position controls at the bottom */\n flex-direction: column-reverse;\n }\n\n :host(:-webkit-full-screen) {\n /* Needs to use !important otherwise easy to break */\n width: 100% !important;\n height: 100% !important;\n }\n\n ::slotted([slot=media]) {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: #000;\n }\n\n #container ::slotted(*) {\n opacity: 1;\n transition: opacity 0.25s;\n visibility: visible;\n }\n\n /* Hide controls when inactive and not paused */\n #container.inactive:not(.paused) ::slotted(*) {\n opacity: 0;\n transition: opacity 1s;\n }\n\n </style>\n <slot name="media"></slot>\n <div id="container">\n <slot></slot>\n </div>\n';class k extends HTMLElement{constructor(){super();this.attachShadow({mode:"open"});this.shadowRoot.appendChild(y.content.cloneNode(!0)),this.container=this.shadowRoot.getElementById("container"),this._media=null;new MutationObserver((function(e,n){for(let n of e)"childList"===n.type&&(n.removedNodes.forEach(e=>{e.media===this.media&&(e.media=null)}),n.addedNodes.forEach(e=>{e instanceof t&&!e.media&&(e.media=this.media)}))})).observe(this,{childList:!0,subtree:!0})}get media(){return this._media}set media(e){if(this._media=e,e){this.addEventListener("click",e=>{const t=this.media;"media"==e.target.slot&&(t.paused?t.play():t.pause())}),e.paused&&this.container.classList.add("paused"),e.addEventListener("play",()=>{this.container.classList.remove("paused")}),e.addEventListener("pause",()=>{this.container.classList.add("paused")});const t=e.nodeName.toLowerCase();"audio"==t||"video"==t?n.call(this,e):window.customElements.whenDefined(t).then(()=>{n.call(this,e)})}function n(e){this.querySelectorAll("*").forEach(e=>{e instanceof t&&(e.media=this.media)}),this.shadowRoot.querySelectorAll("*").forEach(e=>{e instanceof t&&(e.media=this.media)})}}connectedCallback(){new MutationObserver((e,t)=>{}).observe(this,{childList:!0});let e=this.querySelector("[slot=media]");e&&(this.media=e);const t=()=>{this.container.classList.remove("inactive"),window.clearTimeout(this.inactiveTimeout),this.inactiveTimeout=window.setTimeout(()=>{this.container.classList.add("inactive")},2e3)};this.addEventListener("keyup",e=>{t()}),this.addEventListener("keyup",e=>{this.container.classList.add("media-focus-visible")}),this.addEventListener("mouseup",e=>{this.container.classList.remove("media-focus-visible")}),this.addEventListener("mousemove",e=>{e.target!==this&&(this.container.classList.remove("inactive"),window.clearTimeout(this.inactiveTimeout),e.target===this.media&&t())}),this.addEventListener("mouseout",e=>{this.container.classList.add("inactive")})}}e("media-chrome",k); |
{ | ||
"name": "media-chrome", | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"description": "Custom elements (web components) for making audio and video player controls that look great in your website or app.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -165,3 +165,3 @@ # `<media-chrome>` | ||
```html | ||
<media-chrome defaultControls> | ||
<media-chrome> | ||
<youtube-video | ||
@@ -168,0 +168,0 @@ slot="media" |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
40005
101
1