super-media-element
Advanced tools
Comparing version 0.0.1 to 0.1.0
@@ -1,27 +0,2 @@ | ||
(() => { | ||
var __accessCheck = (obj, member, msg) => { | ||
if (!member.has(obj)) | ||
throw TypeError("Cannot " + msg); | ||
}; | ||
var __privateGet = (obj, member, getter) => { | ||
__accessCheck(obj, member, "read from private field"); | ||
return getter ? getter.call(obj) : member.get(obj); | ||
}; | ||
var __privateAdd = (obj, member, value) => { | ||
if (member.has(obj)) | ||
throw TypeError("Cannot add the same private member more than once"); | ||
member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | ||
}; | ||
var __privateSet = (obj, member, value, setter) => { | ||
__accessCheck(obj, member, "write to private field"); | ||
setter ? setter.call(obj, value) : member.set(obj, value); | ||
return value; | ||
}; | ||
var __privateMethod = (obj, member, method) => { | ||
__accessCheck(obj, member, "access private method"); | ||
return method; | ||
}; | ||
// index.js | ||
var styles = ` | ||
var j=(a,s,o)=>{if(!s.has(a))throw TypeError("Cannot "+o)};var u=(a,s,o)=>(j(a,s,"read from private field"),o?o.call(a):s.get(a)),h=(a,s,o)=>{if(s.has(a))throw TypeError("Cannot add the same private member more than once");s instanceof WeakSet?s.add(a):s.set(a,o)},m=(a,s,o,p)=>(j(a,s,"write to private field"),p?p.call(a,o):s.set(a,o),o);var d=(a,s,o)=>(j(a,s,"access private method"),o);var F=` | ||
:host { | ||
@@ -41,216 +16,7 @@ display: inline-block; | ||
} | ||
`; | ||
var template = document.createElement("template"); | ||
template.innerHTML = ` | ||
`,k=document.createElement("template");k.innerHTML=` | ||
<style> | ||
${styles} | ||
${F} | ||
</style> | ||
<slot></slot> | ||
`; | ||
var SuperMediaMixin = (superclass, { tag, is }) => { | ||
var _a, _isDefined, _define, define_fn, _isInit, _loadComplete, _isLoaded, _standinEl, _initStandinEl, initStandinEl_fn, _initNativeEl, initNativeEl_fn, _init, init_fn, _forwardAttribute, forwardAttribute_fn; | ||
const nativeElTest = document.createElement(tag, { is }); | ||
const nativeElProps = getNativeElProps(nativeElTest); | ||
const AllEvents = [ | ||
...nativeElProps, | ||
...Object.getOwnPropertyNames(HTMLElement.prototype) | ||
].filter((name) => name.startsWith("on")).map((name) => name.slice(2)); | ||
return _a = class extends superclass { | ||
constructor() { | ||
super(); | ||
__privateAdd(this, _initStandinEl); | ||
__privateAdd(this, _initNativeEl); | ||
__privateAdd(this, _init); | ||
__privateAdd(this, _forwardAttribute); | ||
__privateAdd(this, _isInit, void 0); | ||
__privateAdd(this, _loadComplete, void 0); | ||
__privateAdd(this, _isLoaded, false); | ||
__privateAdd(this, _standinEl, void 0); | ||
if (!this.shadowRoot) { | ||
this.attachShadow({ mode: "open" }); | ||
this.shadowRoot.append(template.content.cloneNode(true)); | ||
} | ||
} | ||
static get observedAttributes() { | ||
var _a2; | ||
__privateMethod(_a2 = _a, _define, define_fn).call(_a2); | ||
let attrs = []; | ||
Object.getOwnPropertyNames(this.prototype).forEach((propName) => { | ||
let isFunc = false; | ||
try { | ||
if (typeof this.prototype[propName] === "function") | ||
isFunc = true; | ||
} catch (e) { | ||
} | ||
if (!isFunc && propName !== propName.toUpperCase()) { | ||
attrs.push(propName.toLowerCase()); | ||
} | ||
}); | ||
const supAttrs = Object.getPrototypeOf(this).observedAttributes; | ||
const natAttrs = Object.getPrototypeOf(nativeElTest).observedAttributes; | ||
return [...natAttrs != null ? natAttrs : [], ...attrs, ...supAttrs != null ? supAttrs : []]; | ||
} | ||
set loadComplete(promise) { | ||
__privateSet(this, _isLoaded, false); | ||
__privateSet(this, _loadComplete, promise); | ||
promise.then(() => { | ||
__privateSet(this, _isLoaded, true); | ||
}); | ||
} | ||
get loadComplete() { | ||
return __privateGet(this, _loadComplete); | ||
} | ||
get isLoaded() { | ||
return __privateGet(this, _isLoaded); | ||
} | ||
get nativeEl() { | ||
return this.shadowRoot.querySelector(tag); | ||
} | ||
async attributeChangedCallback(attrName, oldValue, newValue) { | ||
if (!__privateGet(this, _isInit)) { | ||
await __privateMethod(this, _init, init_fn).call(this); | ||
} | ||
__privateMethod(this, _forwardAttribute, forwardAttribute_fn).call(this, attrName, oldValue, newValue); | ||
} | ||
connectedCallback() { | ||
__privateMethod(this, _init, init_fn).call(this); | ||
} | ||
}, _isDefined = new WeakMap(), _define = new WeakSet(), define_fn = function() { | ||
if (__privateGet(this, _isDefined)) | ||
return; | ||
__privateSet(this, _isDefined, true); | ||
nativeElProps.forEach((prop) => { | ||
if (prop in this.prototype) | ||
return; | ||
const type = typeof nativeElTest[prop]; | ||
if (type == "function") { | ||
this.prototype[prop] = async function() { | ||
__privateMethod(this, _init, init_fn).call(this); | ||
if (this.loadComplete && !this.isLoaded) | ||
await this.loadComplete; | ||
return this.nativeEl[prop].apply(this.nativeEl, arguments); | ||
}; | ||
} else { | ||
let config = { | ||
get() { | ||
var _a2, _b; | ||
__privateMethod(this, _init, init_fn).call(this); | ||
return (_b = (_a2 = this.nativeEl) == null ? void 0 : _a2[prop]) != null ? _b : __privateGet(this, _standinEl)[prop]; | ||
} | ||
}; | ||
if (prop !== prop.toUpperCase()) { | ||
config.set = async function(val) { | ||
__privateMethod(this, _init, init_fn).call(this); | ||
if (this.loadComplete && !this.isLoaded) | ||
await this.loadComplete; | ||
this.nativeEl[prop] = val; | ||
}; | ||
} | ||
Object.defineProperty(this.prototype, prop, config); | ||
} | ||
}); | ||
}, _isInit = new WeakMap(), _loadComplete = new WeakMap(), _isLoaded = new WeakMap(), _standinEl = new WeakMap(), _initStandinEl = new WeakSet(), initStandinEl_fn = function() { | ||
const dummyEl = document.createElement(tag, { is }); | ||
[...this.attributes].forEach(({ name, value }) => { | ||
dummyEl.setAttribute(name, value); | ||
}); | ||
__privateSet(this, _standinEl, {}); | ||
getNativeElProps(dummyEl).forEach((name) => { | ||
__privateGet(this, _standinEl)[name] = dummyEl[name]; | ||
}); | ||
dummyEl.removeAttribute("src"); | ||
dummyEl.load(); | ||
}, _initNativeEl = new WeakSet(), initNativeEl_fn = async function() { | ||
if (this.loadComplete && !this.isLoaded) | ||
await this.loadComplete; | ||
if (!this.nativeEl) { | ||
this.shadowRoot.append(document.createElement(tag, { is })); | ||
} | ||
}, _init = new WeakSet(), init_fn = async function() { | ||
if (__privateGet(this, _isInit)) | ||
return; | ||
__privateSet(this, _isInit, true); | ||
__privateMethod(this, _initStandinEl, initStandinEl_fn).call(this); | ||
__privateMethod(this, _initNativeEl, initNativeEl_fn).call(this); | ||
const childMap = /* @__PURE__ */ new Map(); | ||
const slotEl = this.shadowRoot.querySelector("slot"); | ||
slotEl == null ? void 0 : slotEl.addEventListener("slotchange", () => { | ||
const removeNativeChildren = new Map(childMap); | ||
slotEl.assignedElements().filter((el) => ["track", "source"].includes(el.localName)).forEach(async (el) => { | ||
removeNativeChildren.delete(el); | ||
let clone = childMap.get(el); | ||
if (!clone) { | ||
clone = el.cloneNode(); | ||
childMap.set(el, clone); | ||
} | ||
if (this.loadComplete && !this.isLoaded) | ||
await this.loadComplete; | ||
this.nativeEl.append(clone); | ||
}); | ||
removeNativeChildren.forEach((el) => el.remove()); | ||
}); | ||
AllEvents.forEach((type) => { | ||
var _a2, _b; | ||
(_b = (_a2 = this.shadowRoot).addEventListener) == null ? void 0 : _b.call(_a2, type, (evt) => { | ||
if (evt.target !== this.nativeEl) { | ||
return; | ||
} | ||
if (!["Event", "CustomEvent"].includes(evt.constructor.name)) { | ||
return; | ||
} | ||
this.dispatchEvent(new CustomEvent(evt.type, { detail: evt.detail })); | ||
}, true); | ||
}); | ||
[...this.attributes].forEach((attrNode) => { | ||
__privateMethod(this, _forwardAttribute, forwardAttribute_fn).call(this, attrNode.name, null, attrNode.value); | ||
}); | ||
if (this.loadComplete && !this.isLoaded) | ||
await this.loadComplete; | ||
if (this.nativeEl.defaultMuted) { | ||
this.muted = true; | ||
} | ||
}, _forwardAttribute = new WeakSet(), forwardAttribute_fn = async function(attrName, oldValue, newValue) { | ||
if (this.loadComplete && !this.isLoaded) | ||
await this.loadComplete; | ||
const ownProps = Object.getOwnPropertyNames(Object.getPrototypeOf(this)); | ||
const propName = ownProps.find((name) => name.toLowerCase() === attrName.toLowerCase()); | ||
const isBaseElement = Object.getPrototypeOf(this.constructor).name === "HTMLElement"; | ||
if (propName && !isBaseElement) { | ||
if (typeof this[propName] == "boolean") { | ||
if (newValue === null) { | ||
this[propName] = false; | ||
} else { | ||
this[propName] = true; | ||
} | ||
} else { | ||
this[propName] = newValue; | ||
} | ||
} else { | ||
if (newValue === null) { | ||
this.nativeEl.removeAttribute(attrName); | ||
} else { | ||
if (["id", "class"].indexOf(attrName) === -1) { | ||
this.nativeEl.setAttribute(attrName, newValue); | ||
} | ||
} | ||
} | ||
}, __privateAdd(_a, _define), __privateAdd(_a, _isDefined, void 0), _a; | ||
}; | ||
function getNativeElProps(nativeElTest) { | ||
let nativeElProps = []; | ||
for (let proto = Object.getPrototypeOf(nativeElTest); proto && proto !== HTMLElement.prototype; proto = Object.getPrototypeOf(proto)) { | ||
nativeElProps.push(...Object.getOwnPropertyNames(proto)); | ||
} | ||
return nativeElProps; | ||
} | ||
var SuperVideoElement = SuperMediaMixin(HTMLElement, { tag: "video" }); | ||
if (!globalThis.customElements.get("super-video")) { | ||
globalThis.customElements.define("super-video", SuperVideoElement); | ||
globalThis.SuperVideoElement = SuperVideoElement; | ||
} | ||
var SuperAudioElement = SuperMediaMixin(HTMLElement, { tag: "audio" }); | ||
if (!globalThis.customElements.get("super-audio")) { | ||
globalThis.customElements.define("super-audio", SuperAudioElement); | ||
globalThis.SuperAudioElement = SuperAudioElement; | ||
} | ||
})(); | ||
`;var N=(a,{tag:s,is:o})=>{var f,v,L,q,E,w,y,b,P,U,M,B,c,g,C,S;let p=document.createElement(s,{is:o}),A=x(p),D=[...A,...Object.getOwnPropertyNames(HTMLElement.prototype)].filter(T=>T.startsWith("on")).map(T=>T.slice(2));return f=class extends a{constructor(){super();h(this,P);h(this,M);h(this,c);h(this,C);h(this,E,void 0);h(this,w,void 0);h(this,y,!1);h(this,b,void 0);this.shadowRoot||(this.attachShadow({mode:"open"}),this.shadowRoot.append(k.content.cloneNode(!0)))}static get observedAttributes(){var i;d(i=f,L,q).call(i);let t=[];Object.getOwnPropertyNames(this.prototype).forEach(n=>{let r=!1;try{typeof this.prototype[n]=="function"&&(r=!0)}catch{}!r&&n!==n.toUpperCase()&&t.push(n.toLowerCase())});let l=Object.getPrototypeOf(this).observedAttributes,e=Object.getPrototypeOf(p).observedAttributes;return[...e!=null?e:[],...t,...l!=null?l:[]]}set loadComplete(t){m(this,y,!1),m(this,w,t),t.then(()=>{m(this,y,!0)})}get loadComplete(){return u(this,w)}get isLoaded(){return u(this,y)}get nativeEl(){return this.shadowRoot.querySelector(s)}async attributeChangedCallback(t,l,e){u(this,E)||await d(this,c,g).call(this),d(this,C,S).call(this,t,l,e)}connectedCallback(){d(this,c,g).call(this)}},v=new WeakMap,L=new WeakSet,q=function(){u(this,v)||(m(this,v,!0),A.forEach(t=>{if(t in this.prototype)return;if(typeof p[t]=="function")this.prototype[t]=function(...e){d(this,c,g).call(this);let i=()=>this.call?this.call(t,...e):this.nativeEl[t].apply(this.nativeEl,e);return this.loadComplete&&!this.isLoaded?this.loadComplete.then(i):i()};else{let e={get(){var i,n,r,O;return d(this,c,g).call(this),(O=(r=(i=this.get)==null?void 0:i.call(this,t))!=null?r:(n=this.nativeEl)==null?void 0:n[t])!=null?O:u(this,b)[t]}};t!==t.toUpperCase()&&(e.set=async function(i){if(d(this,c,g).call(this),this.loadComplete&&!this.isLoaded&&await this.loadComplete,this.set){this.set(t,i);return}this.nativeEl[t]=i}),Object.defineProperty(this.prototype,t,e)}}))},E=new WeakMap,w=new WeakMap,y=new WeakMap,b=new WeakMap,P=new WeakSet,U=function(){let t=document.createElement(s,{is:o});[...this.attributes].forEach(({name:l,value:e})=>{t.setAttribute(l,e)}),m(this,b,{}),x(t).forEach(l=>{u(this,b)[l]=t[l]}),t.removeAttribute("src"),t.load()},M=new WeakSet,B=async function(){this.loadComplete&&!this.isLoaded&&await this.loadComplete,this.nativeEl||this.shadowRoot.append(document.createElement(s,{is:o}))},c=new WeakSet,g=async function(){if(u(this,E))return;m(this,E,!0),d(this,P,U).call(this),d(this,M,B).call(this);let t=new Map,l=this.shadowRoot.querySelector("slot");l==null||l.addEventListener("slotchange",()=>{let e=new Map(t);l.assignedElements().filter(i=>["track","source"].includes(i.localName)).forEach(async i=>{e.delete(i);let n=t.get(i);n||(n=i.cloneNode(),t.set(i,n)),this.loadComplete&&!this.isLoaded&&await this.loadComplete,this.nativeEl.append(n)}),e.forEach(i=>i.remove())}),D.forEach(e=>{var i,n;(n=(i=this.shadowRoot).addEventListener)==null||n.call(i,e,r=>{r.target===this.nativeEl&&(!["Event","CustomEvent"].includes(r.constructor.name)||this.dispatchEvent(new CustomEvent(r.type,{detail:r.detail})))},!0)}),[...this.attributes].forEach(e=>{d(this,C,S).call(this,e.name,null,e.value)}),this.loadComplete&&!this.isLoaded&&await this.loadComplete,this.nativeEl.defaultMuted&&(this.muted=!0)},C=new WeakSet,S=async function(t,l,e){this.loadComplete&&!this.isLoaded&&await this.loadComplete;let n=Object.getOwnPropertyNames(Object.getPrototypeOf(this)).find(O=>O.toLowerCase()===t.toLowerCase()),r=Object.getPrototypeOf(this.constructor).name==="HTMLElement";n&&!r?typeof this[n]=="boolean"?e===null?this[n]=!1:this[n]=!0:this[n]=e:e===null?this.nativeEl.removeAttribute(t):["id","class"].indexOf(t)===-1&&this.nativeEl.setAttribute(t,e)},h(f,L),h(f,v,void 0),f};function x(a){let s=[];for(let o=Object.getPrototypeOf(a);o&&o!==HTMLElement.prototype;o=Object.getPrototypeOf(o))s.push(...Object.getOwnPropertyNames(o));return s}var H=N(HTMLElement,{tag:"video"});globalThis.customElements.get("super-video")||(globalThis.customElements.define("super-video",H),globalThis.SuperVideoElement=H);var R=N(HTMLElement,{tag:"audio"});globalThis.customElements.get("super-audio")||(globalThis.customElements.define("super-audio",R),globalThis.SuperAudioElement=R);export{R as SuperAudioElement,N as SuperMediaMixin,H as SuperVideoElement}; |
25
index.js
@@ -99,6 +99,14 @@ /** | ||
// Function | ||
this.prototype[prop] = async function () { | ||
this.prototype[prop] = function (...args) { | ||
this.#init(); | ||
if (this.loadComplete && !this.isLoaded) await this.loadComplete; | ||
return this.nativeEl[prop].apply(this.nativeEl, arguments); | ||
const fn = () => { | ||
if (this.call) return this.call(prop, ...args); | ||
return this.nativeEl[prop].apply(this.nativeEl, args); | ||
}; | ||
if (this.loadComplete && !this.isLoaded) { | ||
return this.loadComplete.then(fn); | ||
} | ||
return fn(); | ||
}; | ||
@@ -110,3 +118,7 @@ } else { | ||
this.#init(); | ||
return this.nativeEl?.[prop] ?? this.#standinEl[prop]; | ||
return ( | ||
this.get?.(prop) ?? | ||
this.nativeEl?.[prop] ?? | ||
this.#standinEl[prop] | ||
); | ||
}, | ||
@@ -120,2 +132,6 @@ }; | ||
if (this.loadComplete && !this.isLoaded) await this.loadComplete; | ||
if (this.set) { | ||
this.set(prop, val); | ||
return; | ||
} | ||
this.nativeEl[prop] = val; | ||
@@ -180,2 +196,3 @@ }; | ||
// unload dummy video element | ||
dummyEl.removeAttribute('src'); | ||
@@ -182,0 +199,0 @@ dummyEl.load(); |
{ | ||
"name": "super-media-element", | ||
"version": "0.0.1", | ||
"version": "0.1.0", | ||
"description": "Helps you create a custom element w/ a HTMLMediaElement API.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -41,3 +41,3 @@ # Super Media Element | ||
// code to load a video element from a script | ||
// example: https://github.com/luwes/jwplayer-video-element/blob/2722f0a9bd907fc0245b1e824e8bcb266f20651a/src/jwplayer-video-element.js#L49-L69 | ||
// example: https://github.com/luwes/jwplayer-video-element/blob/main/src/jwplayer-video-element.js#L49-L69 | ||
@@ -44,0 +44,0 @@ this.loadResolve(); |
22629
362