2018-05-13 13:49:25 +02:00
if ( Debug . debug )
2018-05-13 15:22:28 +02:00
console . log ( "Loading: PlayerData.js" ) ;
2018-05-13 13:49:25 +02:00
/ * s p r e j m e < v i d e o > t a g ( e l e m e n t ) i n s e z n a m i m e n , k i s e l a h k o p o j a v i j o v r a z r e d i h o z . i d s t a r š e v .
// vrne dimenzije predvajalnika (širina, višina)
//
// Na youtube v theater mode je razširitev rahlo pokvarjena. Video tag ostane večji od predvajalnika, ko se zapusti
// celozaslonski način. Ta funkcija skuša to težavo rešiti tako, da poišče element predvajalnika, ki je zavit okoli videa.
//
// Funkcija izkorišča lastnost, da bi načeloma moral biti vsak zunanji element večji od notranjega. Najmanjši element od
// <video> značke pa do korena drevesa bi tako moral biti predvajalnik.
//
// Če je podan seznam imen, potem funkcija vrne dimenzije prvega elementa, ki v id oz. razredu vsebuje katerokoli ime iz seznama
//
// | EN |
//
// accepts <video> tag (element) and list of names that can appear in id or class
// returns player dimensions (width, height)
//
// Theater mode is mildly broken on youtube. <video> tag remains bigger than the player after leaving the fullscreen mode, and
// there's nothing we can do about that. This function aims to solve the problem by finding the player element that's wrapped around
// the <video> tag.
//
// In general, an outer tag should be bigger than the inner tag. Therefore the smallest element between <video> tag and the document
// root should be the player.
//
// If list of names is provided, the function returns dimensions of the first element that contains any name from the list in either
// id or class.
* /
class PlayerData {
constructor ( videoData ) {
this . videoData = videoData ;
this . video = videoData . video ;
this . element = undefined ;
this . dimensions = undefined ;
this . getPlayerDimensions ( ) ;
2018-05-16 20:26:55 +02:00
this . startChangeDetection ( ) ;
2018-05-13 13:49:25 +02:00
}
static isFullScreen ( ) {
return ( window . innerHeight == window . screen . height && window . innerWidth == window . screen . width ) ;
}
2018-05-23 23:57:51 +02:00
start ( ) {
this . startChangeDetection ( ) ;
}
stop ( ) {
this . halted = true ;
this . stopChangeDetection ( ) ;
2018-05-13 13:49:25 +02:00
}
2018-05-22 00:19:50 +02:00
destroy ( ) {
this . stopChangeDetection ( ) ;
}
2018-05-23 23:57:51 +02:00
startChangeDetection ( ) {
this . scheduleGhettoWatcher ( ) ;
}
stopChangeDetection ( ) {
clearTimeout ( this . watchTimeout ) ;
}
2018-05-20 23:31:05 +02:00
scheduleGhettoWatcher ( timeout , force _reset ) {
if ( ! timeout ) {
timeout = 100 ;
}
2018-05-23 23:57:51 +02:00
if ( this . halted ) {
return ;
}
2018-05-20 23:31:05 +02:00
// don't allow more than 1 instance
if ( this . watchTimeout ) {
clearTimeout ( this . watchTimeout ) ;
}
var ths = this ;
2018-05-20 23:17:09 +02:00
this . watchTimeout = setTimeout ( function ( ) {
2018-05-20 23:31:05 +02:00
ths . watchTimeout = null ;
try {
ths . ghettoWatcher ( ) ;
} catch ( e ) { console . log ( "[PlayerData::scheduleGhettoWatcher] Scheduling failed. Error:" , e ) }
ths = null ;
} ,
timeout
) ;
2018-05-20 23:17:09 +02:00
}
2018-05-13 13:49:25 +02:00
2018-05-20 23:17:09 +02:00
ghettoWatcher ( ) {
if ( this . checkPlayerSizeChange ( ) ) {
2018-05-13 13:49:25 +02:00
if ( Debug . debug ) {
console . log ( "[uw::ghettoOnChange] change detected" ) ;
}
2018-05-20 23:17:09 +02:00
this . getPlayerDimensions ( ) ;
if ( ! this . element ) {
2018-05-20 23:31:05 +02:00
this . scheduleGhettoWatcher ( ) ;
2018-05-13 13:49:25 +02:00
return ;
}
2018-05-20 23:17:09 +02:00
this . videoData . resizer . restore ( ) ; // note: this returns true if change goes through, false otherwise.
2018-05-20 23:31:05 +02:00
this . scheduleGhettoWatcher ( ) ;
2018-05-13 13:49:25 +02:00
return ;
}
// sem ter tja, checkPlayerSizeChange() ne zazna prehoda v celozaslonski način (in iz njega). Zato moramo
// uporabiti dodatne trike.
// sometimes, checkPlayerSizeChange might not detect a change to fullscreen. This means we need to
// trick it into doing that
2018-05-20 23:17:09 +02:00
if ( this . dimensions . fullscreen != PlayerData . isFullScreen ( ) ) {
2018-05-13 13:49:25 +02:00
if ( Debug . debug ) {
console . log ( "[PlayerData::ghettoWatcher] fullscreen switch detected (basic change detection failed)" ) ;
}
2018-05-20 23:17:09 +02:00
this . getPlayerDimensions ( ) ;
2018-05-13 13:49:25 +02:00
2018-05-20 23:17:09 +02:00
if ( ! this . element ) {
2018-05-20 23:31:05 +02:00
this . scheduleGhettoWatcher ( ) ;
2018-05-13 13:49:25 +02:00
return ;
}
2018-05-20 23:17:09 +02:00
this . videoData . resizer . restore ( ) ;
2018-05-13 13:49:25 +02:00
}
2018-05-20 23:31:05 +02:00
this . scheduleGhettoWatcher ( ) ;
2018-05-13 13:49:25 +02:00
}
getPlayerDimensions ( elementNames ) {
// element names — reserved for future use. If element names are provided, this function should return first element that
// has classname or id that matches at least one in the elementNames array.
2018-05-16 20:26:55 +02:00
var element = this . video . parentNode ;
2018-05-13 13:49:25 +02:00
if ( ! element ) {
if ( Debug . debug )
console . log ( "[PlayerDetect::_pd_getPlayerDimensions] element is not valid, doing nothing." , element )
this . element = undefined ;
this . dimensions = undefined ;
return ;
}
2018-05-14 20:39:15 +02:00
var isFullScreen = PlayerData . isFullScreen ( ) ;
2018-05-13 13:49:25 +02:00
var trustCandidateAfterGrows = 2 ; // if candidate_width or candidate_height increases in either dimensions this many
// times, we say we found our player. (This number ignores weird elements)
// in case our <video> is bigger than player in one dimension but smaller in the other
// if site is coded properly, player can't be wider than that
var candidate _width = Math . max ( element . offsetWidth , window . innerWidth ) ;
var candidate _height = Math . max ( element . offsetHeight , window . innerHeight ) ;
var playerCandidateNode = element ;
try {
var grows = trustCandidateAfterGrows ;
while ( element != undefined ) {
// odstranimo čudne elemente, ti bi pokvarili zadeve
// remove weird elements, those would break our stuff
if ( element . offsetWidth == 0 || element . offsetHeight == 0 ) {
element = element . parentNode ;
continue ;
}
if ( element . offsetHeight <= candidate _height &&
element . offsetWidth <= candidate _width ) {
// if we're in fullscreen, we only consider elements that are exactly as big as the monitor.
if ( ! isFullScreen ||
( element . offsetWidth == window . innerWidth && element . offsetHeight == window . innerHeight ) ) {
playerCandidateNode = element ;
candidate _width = element . offsetWidth ;
candidate _height = element . offsetHeight ;
grows = trustCandidateAfterGrows ;
if ( Debug . debug ) {
console . log ( "Found new candidate for player. Dimensions: w:" , candidate _width , "h:" , candidate _height , "node:" , playerCandidateNode ) ;
}
}
}
else if ( grows -- <= 0 ) {
if ( Debug . debug && Debug . playerDetect ) {
console . log ( "Current element grew in comparrison to the child. We probably found the player. breaking loop, returning current result" ) ;
}
break ;
}
element = element . parentNode ;
}
}
catch ( e ) {
console . log ( "pdeeee," , e ) ;
}
if ( isFullScreen && playerCandidateNode == element ) {
this . dimensions = {
width : window . innerWidth ,
height : window . innerHeight ,
fullscreen : true
}
this . element = element ;
} else {
this . dimensions = {
width : candidate _width ,
height : candidate _height ,
fullscreen : isFullScreen
} ;
this . element = playerCandidateNode ;
}
}
checkPlayerSizeChange ( ) {
if ( Debug . debug ) {
if ( this . element == undefined )
console . log ( "[PlayerDetect] player size changed. reason: player element undefined" ) ;
if ( this . dimensions . fullscreen ) {
2018-05-26 23:08:49 +02:00
if ( ! PlayerData . isFullScreen ( ) ) {
2018-05-13 13:49:25 +02:00
console . log ( "[PlayerDetect] player size changed. reason: exited fullscreen" ) ;
}
}
if ( ! this . element )
console . log ( "[PlayerDetect] player element isnt defined" ) ;
if ( this . element &&
( this . dimensions . width != this . element . offsetWidth ||
this . dimensions . height != this . element . offsetHeight )
) {
console . log ( "[PlayerDetect] player size changed. reason: dimension change. Old dimensions?" , this . dimensions . width , this . dimensions . height , "new dimensions:" , this . element . offsetWidth , this . element . offsetHeight ) ;
}
}
if ( this . element == undefined ) {
return true ;
} else if ( this . dimensions . width != this . element . offsetWidth || this . dimensions . height != this . element . offsetHeight ) {
return true ;
}
return false ;
}
}