@@ -1611,221 +1611,7 @@ text-align:center;
16111611}
16121612
16131613window . customElements . define ( 'k-control-volume' , CKControlVolume ) ;
1614- class CustomVideoElement extends HTMLElement {
1615- constructor ( ) {
1616- super ( ) ;
1617- let shadow = this . attachShadow ( { mode :'open' } ) ;
1618- shadow . innerHTML = '<style>:host{all:initial;display:inline-block;box-sizing:border-box;position:relative;width:300px;height:150px;}video{position:absolute;width:100%;height:100%;}</style><video crossorigin></video>' ;
1619-
1620- const nativeEl = this . nativeEl = this . shadowRoot . querySelector ( 'video' ) ;
1621-
1622- // Initialize all the attribute properties
1623- Array . prototype . forEach . call ( this . attributes , attrNode => {
1624- this . attributeChangedCallback ( attrNode . name , null , attrNode . value ) ;
1625- } ) ;
1626-
1627- // Neither Chrome or Firefox support setting the muted attribute
1628- // after using document.createElement.
1629- // One way to get around this would be to build the native tag as a string.
1630- // But just fixing it manually for now.
1631- // Apparently this may also be an issue with <input checked> for buttons
1632- if ( nativeEl . defaultMuted ) {
1633- nativeEl . muted = true ;
1634- }
1635-
1636- this . shadowRoot . appendChild ( nativeEl ) ;
1637-
1638- this . querySelectorAll ( ':scope > track' ) . forEach ( ( track ) => {
1639- this . nativeEl . appendChild ( track . cloneNode ( ) ) ;
1640- } ) ;
1641-
1642- // Watch for child adds/removes and update the native element if necessary
1643- const mutationCallback = ( mutationsList , observer ) => {
1644- for ( let mutation of mutationsList ) {
1645- if ( mutation . type === 'childList' ) {
1646-
1647- // Child being removed
1648- mutation . removedNodes . forEach ( node => {
1649- this . nativeEl . removeChild ( this . nativeEl . querySelector ( `track[src="${ node . src } "]` ) ) ;
1650- } ) ;
1651-
1652- mutation . addedNodes . forEach ( node => {
1653- this . nativeEl . appendChild ( node . cloneNode ( ) ) ;
1654- } ) ;
1655- }
1656- }
1657- } ;
1658-
1659- const observer = new MutationObserver ( mutationCallback ) ;
1660- observer . observe ( this , { childList : true , subtree : true } ) ;
1661- }
1662-
1663- // observedAttributes is required to trigger attributeChangedCallback
1664- // for any attributes on the custom element.
1665- // Attributes need to be the lowercase word, e.g. crossorigin, not crossOrigin
1666- static get observedAttributes ( ) {
1667- let attrs = [ ] ;
1668-
1669- // Instead of manually creating a list of all observed attributes,
1670- // observe any getter/setter prop name (lowercased)
1671- Object . getOwnPropertyNames ( this . prototype ) . forEach ( propName => {
1672- let isFunc = false ;
1673-
1674- // Non-func properties throw errors because it's not an instance
1675- try {
1676- if ( typeof this . prototype [ propName ] === 'function' ) {
1677- isFunc = true ;
1678- }
1679- } catch ( e ) { }
1680-
1681- // Exclude functions and constants
1682- if ( ! isFunc && propName !== propName . toUpperCase ( ) ) {
1683- attrs . push ( propName . toLowerCase ( ) ) ;
1684- }
1685- } ) ;
1686-
1687- // Include any attributes from the super class (recursive)
1688- const supAttrs = Object . getPrototypeOf ( this ) . observedAttributes ;
1689-
1690- if ( supAttrs ) {
1691- attrs = attrs . concat ( supAttrs ) ;
1692- }
1693-
1694- return attrs ;
1695- }
1696-
1697- // We need to handle sub-class custom attributes differently from
1698- // attrs meant to be passed to the internal native el.
1699- attributeChangedCallback ( attrName , oldValue , newValue ) {
1700- // Find the matching prop for custom attributes
1701- const ownProps = Object . getOwnPropertyNames ( Object . getPrototypeOf ( this ) ) ;
1702- const propName = arrayFindAnyCase ( ownProps , attrName ) ;
1703-
1704- // Check if this is the original custom native elemnt or a subclass
1705- const isBaseElement =
1706- Object . getPrototypeOf ( this . constructor )
1707- . toString ( )
1708- . indexOf ( 'function HTMLElement' ) === 0 ;
1709-
1710- // If this is a subclass custom attribute we want to set the
1711- // matching property on the subclass
1712- if ( propName && ! isBaseElement ) {
1713- // Boolean props should never start as null
1714- if ( typeof this [ propName ] == 'boolean' ) {
1715- // null is returned when attributes are removed i.e. boolean attrs
1716- if ( newValue === null ) {
1717- this [ propName ] = false ;
1718- } else {
1719- // The new value might be an empty string, which is still true
1720- // for boolean attributes
1721- this [ propName ] = true ;
1722- }
1723- } else {
1724- this [ propName ] = newValue ;
1725- }
1726- } else {
1727- // When this is the original Custom Element, or the subclass doesn't
1728- // have a matching prop, pass it through.
1729- if ( newValue === null ) {
1730- this . nativeEl . removeAttribute ( attrName ) ;
1731- } else {
1732- // Ignore a few that don't need to be passed through just in case
1733- // it creates unexpected behavior.
1734- if ( [ 'id' , 'class' ] . indexOf ( attrName ) === - 1 ) {
1735- this . nativeEl . setAttribute ( attrName , newValue ) ;
1736- }
1737- }
1738- }
1739- }
1740- connectedCallback ( ) {
1741- }
1742- }
1743-
1744- // Map all native element properties to the custom element
1745- // so that they're applied to the native element.
1746- // Skipping HTMLElement because of things like "attachShadow"
1747- // causing issues. Most of those props still need to apply to
1748- // the custom element.
1749- // But includign EventTarget props because most events emit from
1750- // the native element.
1751- let nativeElProps = [ ] ;
1752-
1753- // Can't check typeof directly on element prototypes without
1754- // throwing Illegal Invocation errors, so creating an element
1755- // to check on instead.
1756- const nativeElTest = document . createElement ( 'video' ) ;
1757-
1758- // Deprecated props throw warnings if used, so exclude them
1759- const deprecatedProps = [
1760- 'webkitDisplayingFullscreen' ,
1761- 'webkitSupportsFullscreen' ,
1762- ] ;
1763-
1764- // Walk the prototype chain up to HTMLElement.
1765- // This will grab all super class props in between.
1766- // i.e. VideoElement and MediaElement
1767- for (
1768- let proto = Object . getPrototypeOf ( nativeElTest ) ;
1769- proto && proto !== HTMLElement . prototype ;
1770- proto = Object . getPrototypeOf ( proto )
1771- ) {
1772- Object . keys ( proto ) . forEach ( key => {
1773- if ( deprecatedProps . indexOf ( key ) === - 1 ) {
1774- nativeElProps . push ( key ) ;
1775- }
1776- } ) ;
1777- }
1778-
1779- // For the video element we also want to pass through all event listeners
1780- // because all the important events happen there.
1781- nativeElProps = nativeElProps . concat ( Object . keys ( EventTarget . prototype ) ) ;
1782-
1783- // Passthrough native el functions from the custom el to the native el
1784- nativeElProps . forEach ( prop => {
1785- const type = typeof nativeElTest [ prop ] ;
1786-
1787- if ( type == 'function' ) {
1788- // Function
1789- CustomVideoElement . prototype [ prop ] = function ( ) {
1790- return this . nativeEl [ prop ] . apply ( this . nativeEl , arguments ) ;
1791- } ;
1792- } else {
1793- // Getter
1794- let config = {
1795- get ( ) {
1796- return this . nativeEl [ prop ] ;
1797- } ,
1798- } ;
1799-
1800- if ( prop !== prop . toUpperCase ( ) ) {
1801- // Setter (not a CONSTANT)
1802- config . set = function ( val ) {
1803- this . nativeEl [ prop ] = val ;
1804- } ;
1805- }
1806-
1807- Object . defineProperty ( CustomVideoElement . prototype , prop , config ) ;
1808- }
1809- } ) ;
1810-
1811- function arrayFindAnyCase ( arr , word ) {
1812- let found = null ;
1813-
1814- arr . forEach ( item => {
1815- if ( item . toLowerCase ( ) == word . toLowerCase ( ) ) {
1816- found = item ;
1817- }
1818- } ) ;
1819-
1820- return found ;
1821- }
1822-
1823- if ( ! window . customElements . get ( 'custom-video' ) ) {
1824- window . customElements . define ( 'custom-video' , CustomVideoElement ) ;
1825- window . CustomVideoElement = CustomVideoElement ;
1826- }
1827-
1828- class CKVideo extends CustomVideoElement {
1614+ class CKVideo extends HTMLVideoElement {
18291615 static get observedAttributes ( ) {
18301616 return [ 'src' ] ;
18311617 }
@@ -1938,7 +1724,7 @@ class CKVideo extends CustomVideoElement{
19381724 }
19391725 attributeChangedCallback ( name , oldValue , newValue ) {
19401726 if ( this . do_not_attr_callback ) return ;
1941- if ( name == "src" ) {
1727+ if ( name = "src" ) {
19421728 let utc_from_in_msec = this . getAttribute ( 'time' ) === null ? undefined : parseInt ( this . getAttribute ( 'time' ) ) ;
19431729 let duration_msec = this . getAttribute ( 'msec' ) === null ? undefined : parseInt ( this . getAttribute ( 'msec' ) ) ;
19441730 let off = this . getAttribute ( 'msec' ) === null ? undefined : parseInt ( this . getAttribute ( 'off' ) ) ;
@@ -2315,7 +2101,7 @@ class CKVideo extends CustomVideoElement{
23152101 }
23162102}
23172103
2318- window . customElements . define ( 'k-video' , CKVideo ) ;
2104+ window . customElements . define ( 'k-video' , CKVideo , { extends : 'video' } ) ;
23192105class CKVideoReverse extends CKVideo {
23202106 constructor ( ) {
23212107 super ( ) ;
@@ -2501,7 +2287,7 @@ class CKVideoReverse extends CKVideo{
25012287 }
25022288}
25032289
2504- window . customElements . define ( 'k-video-reverse' , CKVideoReverse ) ;
2290+ window . customElements . define ( 'k-video-reverse' , CKVideoReverse , { extends : 'video' } ) ;
25052291class CRedux {
25062292 constructor ( element ) {
25072293 let self = this ;
@@ -2725,9 +2511,9 @@ class CKVideoSet extends HTMLElement{
27252511 video_tag = 'k-video' ;
27262512 }
27272513
2728- let pb = '<' + video_tag + ' crossorigin="anonymous" preload norepeat pos="0"></' + video_tag + ' >';
2729- for ( let i = 0 ; i < this . LEFT_BUFFER_SIZE ; i ++ ) pb = '<' + video_tag + ' crossorigin="anonymous" preload norepeat pos="-'+ ( i + 1 ) + '"></' + video_tag + ' >' + pb ;
2730- for ( let i = 0 ; i < this . RIGHT_BUFFER_SIZE ; i ++ ) pb += '<' + video_tag + ' crossorigin="anonymous" preload norepeat pos="'+ ( i + 1 ) + '"></' + video_tag + ' >';
2514+ let pb = '<video crossorigin="anonymous" preload norepeat is="' + video_tag + '" pos="0"></video >';
2515+ for ( let i = 0 ; i < this . LEFT_BUFFER_SIZE ; i ++ ) pb = '<video crossorigin="anonymous" preload norepeat is="' + video_tag + '" pos="-'+ ( i + 1 ) + '"></video >' + pb ;
2516+ for ( let i = 0 ; i < this . RIGHT_BUFFER_SIZE ; i ++ ) pb += '<video crossorigin="anonymous" preload norepeat is="' + video_tag + '" pos="'+ ( i + 1 ) + '"></video >' ;
27312517 this . shadow . innerHTML = '<style>' + this . getCss ( ) + '</style><iframe></iframe>' + ( this . getAttribute ( 'debuginfo' ) !== null ?'<div class="debuginfo"></div>' :'' ) + '<div class="wplayers"><div class="players">' + pb + '</div></div>' ;
27322518 this . wplayers_layer = this . shadow . querySelector ( '.wplayers' ) ;
27332519 this . players_layer = this . shadow . querySelector ( '.players' ) ;
@@ -2884,7 +2670,7 @@ class CKVideoSet extends HTMLElement{
28842670 } , { once :false } ) ;
28852671 }
28862672
2887- for ( let s of this . shadow . querySelectorAll ( '.players > * ' ) ) {
2673+ for ( let s of this . shadow . querySelectorAll ( 'video ' ) ) {
28882674 s . setSourceForTimePromise = setSourceForTimePromise ;
28892675 s . setTimeWithSourcePromise = setTimeWithSourcePromise ;
28902676 s . updateState = updateState ;
@@ -2926,11 +2712,10 @@ if (time<1000000) debugger;
29262712 }
29272713 setListiners ( player ) {
29282714 let self = this ;
2929- let pl = player ;
29302715 this . onTimeUpdateEvent = function ( ) {
29312716// self.clearWait();
2932- if ( ! self . shadow || ! pl . isLoaded ( ) ) return ;
2933- if ( pl . isPlaying ( ) && pl . playbackRate < 0 ) self . setStatus ( 'playing' ) ;
2717+ if ( ! self . shadow || ! this . isLoaded ( ) ) return ;
2718+ if ( this . isPlaying ( ) && this . playbackRate < 0 ) self . setStatus ( 'playing' ) ;
29342719 const player = self . shadow . querySelector ( '[pos="0"]' ) ;
29352720 if ( ! player || player . isEmpty ( ) ) return ;
29362721 let time = player . currentUtcTime ;
@@ -3266,7 +3051,7 @@ let a=e;
32663051 for ( let i = - self . LEFT_BUFFER_SIZE ; i <= self . RIGHT_BUFFER_SIZE ; i ++ ) {
32673052 let p = self . shadow . querySelector ( '[pos="' + i + '"]' ) ;
32683053 p . setSourcePromise ( ) . catch ( function ( ) { } ) ;
3269- p . poster = '' ;
3054+ p . poster = undefined ;
32703055 p . removeAttribute ( 'poster' ) ;
32713056 p . load ( ) ;
32723057 }
@@ -3467,7 +3252,7 @@ if (last_right<1000000) debugger;
34673252iframe{position: absolute;left: 0;right: 0;top: 0;bottom: 0;width: 100%;height: 100%;border: 0;opacity: 0;z-index: -1000;}
34683253.wplayers{width:100%;height:100%;position:relative;display:flex;}
34693254.players{max-width:100%;max-height:100%;position:relative;margin: auto auto;width: 100%;height: 100%;}
3470- .players>* {position:absolute;width:100%;height:100%;left:0;}
3255+ video {position:absolute;width:100%;height:100%;left:0;}
34713256.posters_info{display: flex;display: flex;flex-direction: row;justify-content: space-between;align-items: baseline;}
34723257.posters_info div:first-child,.posters_info div:last-child{font-size:80%;color: gray;}
34733258.posters_info div:last-child{text-align:right;}
@@ -3481,7 +3266,7 @@ iframe{position: absolute;left: 0;right: 0;top: 0;bottom: 0;width: 100%;height:
34813266.cachetable .error{background:#ff5050;}
34823267.cachetable .ready{background:#50ff50;}
34833268.cachetable .wait{background:#ffff50;}
3484- .players>* :not([pos="0"]),.players>* [status="error"]{visibility:hidden;}
3269+ video :not([pos="0"]),video [status="error"]{visibility:hidden;}
34853270.debuginfo{font-size:12px;position:absolute;background:#ffffffc0;padding:10px;z-index:10000;font-family:monospace;display:none;}
34863271.cachetable > div:hover{border:1px solid blue;}
34873272` ;
0 commit comments