2018-12-31 01:03:07 +01:00
import Debug from '../../conf/Debug' ;
import VideoData from './VideoData' ;
import RescanReason from './enums/RescanReason' ;
2019-03-10 23:27:50 +01:00
import AspectRatio from '../../../common/enums/aspect-ratio.enum' ;
2018-12-31 01:03:07 +01:00
2017-12-30 02:58:24 +01:00
if ( Debug . debug )
console . log ( "Loading: PageInfo.js" ) ;
2019-02-19 21:10:49 +01:00
2018-05-13 13:49:25 +02:00
class PageInfo {
2019-07-03 21:55:08 +02:00
constructor ( comms , settings , extensionMode , readOnly = false ) {
2018-05-13 13:49:25 +02:00
this . hasVideos = false ;
this . siteDisabled = false ;
this . videos = [ ] ;
2018-08-05 23:48:56 +02:00
this . settings = settings ;
2018-12-02 23:51:34 +01:00
this . actionHandlerInitQueue = [ ] ;
2018-05-13 13:49:25 +02:00
2018-05-21 22:43:56 +02:00
this . lastUrl = window . location . href ;
2018-11-02 02:52:01 +01:00
this . extensionMode = extensionMode ;
2019-07-03 21:03:12 +02:00
this . readOnly = readOnly ;
2018-05-13 13:49:25 +02:00
2019-07-03 21:03:12 +02:00
if ( comms ) {
2018-05-26 23:08:49 +02:00
this . comms = comms ;
2018-08-30 00:56:15 +02:00
}
2019-07-07 21:13:28 +02:00
// request inject css immediately
try {
const playerStyleString = this . settings . active . sites [ window . location . host ] . css . replace ( '\\n' , '' ) ;
this . comms . sendMessage ( {
cmd : 'inject-css' ,
cssString : playerStyleString
} ) ;
} catch ( e ) {
// do nothing. It's ok if there's no special settings for the player element
}
2018-11-07 00:03:06 +01:00
this . rescan ( RescanReason . PERIODIC ) ;
this . scheduleUrlCheck ( ) ;
2018-09-21 00:26:08 +02:00
this . currentZoomScale = 1 ;
2018-05-13 21:05:11 +02:00
}
2019-08-23 02:25:48 +02:00
injectCss ( cssString ) {
this . comms . sendMessage ( {
cmd : 'inject-css' ,
cssString : cssString
} ) ;
}
ejectCss ( cssString ) {
this . comms . sendMessage ( {
cmd : 'eject-css' ,
cssString : cssString
} ) ;
}
2018-08-30 00:56:15 +02:00
destroy ( ) {
2018-09-23 19:46:40 +02:00
if ( Debug . debug || Debug . init ) {
2018-08-30 00:56:15 +02:00
console . log ( "[PageInfo::destroy] destroying all videos!" )
}
2018-08-30 23:03:47 +02:00
if ( this . rescanTimer ) {
clearTimeout ( this . rescanTimer ) ;
}
2018-08-30 00:56:15 +02:00
for ( var video of this . videos ) {
2018-11-09 00:57:05 +01:00
this . comms . unregisterVideo ( video . id )
2018-08-30 00:56:15 +02:00
video . destroy ( ) ;
}
2019-06-14 02:15:24 +02:00
try {
playerStyleString = this . settings . active . sites [ window . location . host ] . css ;
if ( playerStyleString ) {
this . comms . sendMessage ( {
cmd : 'remove-css' ,
cssString : playerStyleString
} ) ;
}
} catch ( e ) {
// do nothing. It's ok if there's no special settings for the player element
}
2018-08-30 00:56:15 +02:00
}
2018-06-15 00:33:10 +02:00
2018-08-22 23:46:59 +02:00
reset ( ) {
2018-08-23 01:04:37 +02:00
for ( var video of this . videos ) {
2018-06-15 00:33:10 +02:00
video . destroy ( ) ;
}
this . rescan ( RescanReason . MANUAL ) ;
}
2018-12-02 23:51:34 +01:00
initMouseActionHandler ( videoData ) {
if ( this . actionHandler ) {
this . actionHandler . registerHandleMouse ( videoData ) ;
} else {
this . actionHandlerInitQueue . push ( videoData ) ;
}
}
setActionHandler ( actionHandler ) {
this . actionHandler = actionHandler ;
for ( var item of this . actionHandlerInitQueue ) {
this . actionHandler . registerHandleMouse ( item ) ;
}
this . actionHandlerInitQueue = [ ] ;
}
2019-06-10 23:45:15 +02:00
getVideos ( host ) {
if ( this . settings . active . sites [ host ]
&& this . settings . active . sites [ host ] . DOM
&& this . settings . active . sites [ host ] . DOM . video
&& this . settings . active . sites [ host ] . DOM . video . manual
&& this . settings . active . sites [ host ] . DOM . video . querySelector ) {
const videos = document . querySelectorAll ( this . settings . active . sites [ host ] . DOM . video . querySelector ) ;
if ( videos . length ) {
return videos ;
}
}
return document . getElementsByTagName ( 'video' ) ;
}
2019-07-03 21:55:08 +02:00
hasVideo ( ) {
return this . readOnly ? this . hasVideos : this . videos . length ;
}
2018-05-21 22:43:56 +02:00
rescan ( rescanReason ) {
2018-11-07 00:03:06 +01:00
const oldVideoCount = this . videos . length ;
2018-05-16 23:26:47 +02:00
try {
2019-06-10 23:45:15 +02:00
var vids = this . getVideos ( window . location . host ) ;
2018-05-13 13:49:25 +02:00
2018-05-13 21:05:11 +02:00
if ( ! vids || vids . length == 0 ) {
2018-05-13 13:49:25 +02:00
this . hasVideos = false ;
2018-05-16 23:26:47 +02:00
2018-05-21 22:43:56 +02:00
if ( rescanReason == RescanReason . PERIODIC ) {
2019-06-14 21:53:48 +02:00
if ( Debug . debug && Debug . videoRescan && Debug . periodic ) {
console . log ( "[PageInfo::rescan] Scheduling normal rescan:" )
}
2018-05-21 22:43:56 +02:00
this . scheduleRescan ( RescanReason . PERIODIC ) ;
}
2018-05-13 13:49:25 +02:00
return ;
}
// add new videos
2018-05-21 22:43:56 +02:00
this . hasVideos = false ;
var videoExists = false ;
var video , v ;
for ( video of vids ) {
// če najdemo samo en video z višino in širino, to pomeni, da imamo na strani veljavne videe
// če trenutni video nima definiranih teh vrednostih, preskočimo vse nadaljnja preverjanja
// <===[:::::::]===>
// if we find even a single video with width and height, that means the page has valid videos
// if video lacks either of the two properties, we skip all further checks cos pointless
if ( video . offsetWidth && video . offsetHeight ) {
this . hasVideos = true ;
2019-07-03 21:55:08 +02:00
if ( this . readOnly ) {
// in lite mode, we're done. This is all the info we want, but we want to actually start doing
// things that interfere with the website. We still want to be runnig a rescan, tho.
if ( rescanReason == RescanReason . PERIODIC ) {
this . scheduleRescan ( RescanReason . PERIODIC ) ;
}
return ;
}
2018-05-21 22:43:56 +02:00
} else {
continue ;
2018-05-20 23:17:09 +02:00
}
2018-05-21 22:43:56 +02:00
videoExists = false ;
2018-05-19 22:20:35 +02:00
2018-05-21 22:43:56 +02:00
for ( v of this . videos ) {
if ( v . destroyed ) {
continue ; //TODO: if destroyed video is same as current video, copy aspect ratio settings to current video
}
2018-05-20 23:17:09 +02:00
2018-05-21 22:43:56 +02:00
if ( v . video == video ) {
videoExists = true ;
break ;
}
}
2018-05-20 23:17:09 +02:00
2018-05-21 22:43:56 +02:00
if ( videoExists ) {
continue ;
} else {
2019-05-07 23:40:13 +02:00
if ( Debug . debug && Debug . periodic && Debug . videoRescan ) {
2018-11-07 00:03:06 +01:00
console . log ( "[PageInfo::rescan] found new video candidate:" , video , "NOTE:: Video initialization starts here:\n--------------------------------\n" )
2018-05-22 00:19:50 +02:00
}
2019-07-03 21:55:08 +02:00
2018-09-21 00:26:08 +02:00
v = new VideoData ( video , this . settings , this ) ;
2018-05-22 00:19:50 +02:00
// console.log("[PageInfo::rescan] v is:", v)
2018-05-21 22:43:56 +02:00
v . initArDetection ( ) ;
this . videos . push ( v ) ;
2018-05-22 00:19:50 +02:00
if ( Debug . debug && Debug . periodic && Debug . videoRescan ) {
2018-11-07 00:03:06 +01:00
console . log ( "[PageInfo::rescan] END VIDEO INITIALIZATION\n\n\n-------------------------------------\nvideos[] is now this:" , this . videos , "\n\n\n\n\n\n\n\n" )
2018-05-22 00:19:50 +02:00
}
2018-05-21 22:43:56 +02:00
}
2018-05-16 23:26:47 +02:00
}
2018-05-21 22:43:56 +02:00
this . removeDestroyed ( ) ;
2018-11-07 00:03:06 +01:00
// če smo ostali brez videev, potem odregistriraj stran.
// če nismo ostali brez videev, potem registriraj stran.
//
// if we're left withotu videos on the current page, we unregister the page.
// if we have videos, we call register.
// if(Debug.debug) {
// console.log("[PageInfo::rescan] Comms:", this.comms, "\nvideos.length:", this.videos.length, "\nold video count:", oldVideoCount)
// }
if ( this . comms ) {
if ( this . videos . length != oldVideoCount ) { // only if number of videos changed, tho
if ( this . videos . length > 0 ) {
this . comms . registerVideo ( { host : window . location . host , location : window . location } ) ;
} else {
this . comms . unregisterVideo ( { host : window . location . host , location : window . location } ) ;
}
}
}
2019-05-07 23:40:13 +02:00
} catch ( e ) {
// če pride do zajeba, potem lahko domnevamo da na strani ni nobenega videa. Uničimo vse objekte videoData
// da preprečimo večkratno inicializacijo. Če smo se z našim ugibom zmotili, potem se bodo vsi videi ponovno
// našli ob naslednjem preiskovanju
//
// if we encounter a fuckup, we can assume that no videos were found on the page. We destroy all videoData
// objects to prevent multiple initalization (which happened, but I don't know why). No biggie if we destroyed
// videoData objects in error — they'll be back in the next rescan
if ( Debug . debug ) {
console . log ( "rescan error: — destroying all videoData objects" , e ) ;
}
for ( const v of this . videos ) {
v . destroy ( ) ;
}
return ;
2018-05-13 13:49:25 +02:00
}
2018-05-21 22:43:56 +02:00
if ( rescanReason == RescanReason . PERIODIC ) {
this . scheduleRescan ( RescanReason . PERIODIC ) ;
}
2018-05-16 23:26:47 +02:00
}
2018-05-21 22:43:56 +02:00
removeDestroyed ( ) {
this . videos = this . videos . filter ( vid => vid . destroyed === false ) ;
}
scheduleRescan ( rescanReason ) {
if ( rescanReason != RescanReason . PERIODIC ) {
this . rescan ( rescanReason ) ;
return ;
}
2018-05-16 23:26:47 +02:00
try {
2018-05-21 22:43:56 +02:00
if ( this . rescanTimer ) {
clearTimeout ( this . rescanTimer ) ;
}
var ths = this ;
2019-06-14 21:53:48 +02:00
this . rescanTimer = setTimeout ( function ( rescanReason ) {
2018-05-21 22:43:56 +02:00
ths . rescanTimer = null ;
2019-06-14 21:53:48 +02:00
ths . rescan ( rescanReason ) ;
2018-05-21 22:43:56 +02:00
ths = null ;
2019-06-14 21:53:48 +02:00
} , this . settings . active . pageInfo . timeouts . rescan , RescanReason . PERIODIC )
2018-05-21 22:43:56 +02:00
} catch ( e ) {
if ( Debug . debug ) {
console . log ( "[PageInfo::scheduleRescan] scheduling rescan failed. Here's why:" , e )
}
}
}
scheduleUrlCheck ( ) {
try {
if ( this . urlCheckTimer ) {
clearTimeout ( this . urlCheckTimer ) ;
2018-05-16 23:26:47 +02:00
}
var ths = this ;
2018-05-21 22:43:56 +02:00
2018-05-16 23:26:47 +02:00
this . rescanTimer = setTimeout ( function ( ) {
ths . rescanTimer = null ;
2018-05-21 22:43:56 +02:00
ths . ghettoUrlCheck ( ) ;
2018-05-16 23:26:47 +02:00
ths = null ;
2018-08-30 00:56:15 +02:00
} , this . settings . active . pageInfo . timeouts . urlCheck )
2019-06-14 21:53:48 +02:00
} catch ( e ) {
2018-05-21 22:43:56 +02:00
if ( Debug . debug ) {
2019-06-14 21:53:48 +02:00
console . error ( "[PageInfo::scheduleUrlCheck] scheduling URL check failed. Here's why:" , e )
2018-05-21 22:43:56 +02:00
}
}
}
ghettoUrlCheck ( ) {
if ( this . lastUrl != window . location . href ) {
2019-06-14 21:53:48 +02:00
if ( Debug . debug && Debug . periodic ) {
2018-05-21 22:43:56 +02:00
console . log ( "[PageInfo::ghettoUrlCheck] URL has changed. Triggering a rescan!" ) ;
}
this . rescan ( RescanReason . URL _CHANGE ) ;
this . lastUrl = window . location . href ;
}
2018-07-12 23:27:10 +02:00
this . scheduleUrlCheck ( ) ;
2018-05-13 13:49:25 +02:00
}
2018-11-21 21:58:13 +01:00
initArDetection ( playingOnly ) {
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( vd . isPlaying ( ) ) {
vd . initArDetection ( ) ;
}
}
return ;
} else {
for ( var vd of this . videos ) {
vd . initArDetection ( ) ;
}
2018-05-13 21:05:11 +02:00
}
}
2018-05-13 13:49:25 +02:00
2018-05-23 23:57:51 +02:00
// to je treba klicat ob menjavi zavihkov
// these need to be called on tab switch
2018-11-21 21:58:13 +01:00
pauseProcessing ( playingOnly ) {
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( vd . isPlaying ( ) ) {
vd . pause ( ) ;
}
}
} else {
for ( var vd of this . videos ) {
vd . pause ( ) ;
}
2018-05-23 23:57:51 +02:00
}
}
2018-11-21 21:58:13 +01:00
resumeProcessing ( resumeAutoar = false , playingOnly = false ) {
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( vd . isPlaying ( ) ) {
vd . resume ( ) ;
if ( resumeAutoar ) {
vd . resumeAutoAr ( ) ;
}
}
}
} else {
for ( var vd of this . videos ) {
vd . resume ( ) ;
if ( resumeAutoar ) {
vd . resumeAutoAr ( ) ;
}
2018-05-23 23:57:51 +02:00
}
}
}
2018-05-24 20:50:37 +02:00
2018-11-21 21:58:13 +01:00
startArDetection ( playingOnly ) {
2018-11-18 18:44:44 +01:00
if ( Debug . debug ) {
console . log ( '[PageInfo::startArDetection()] starting automatic ar detection!' )
}
2018-11-21 21:58:13 +01:00
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( video . isPlaying ( ) ) {
vd . startArDetection ( ) ;
}
}
} else {
for ( var vd of this . videos ) {
vd . startArDetection ( ) ;
}
2018-05-24 20:50:37 +02:00
}
}
2018-11-21 21:58:13 +01:00
stopArDetection ( playingOnly ) {
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( vd . isPlaying ( ) ) {
vd . stopArDetection ( ) ;
}
}
} else {
for ( var vd of this . videos ) {
vd . stopArDetection ( ) ;
}
2018-05-24 20:50:37 +02:00
}
}
2018-11-21 21:58:13 +01:00
setAr ( ar , playingOnly ) {
2018-11-18 18:44:44 +01:00
if ( Debug . debug ) {
2018-11-21 21:58:13 +01:00
console . log ( '[PageInfo::setAr] aspect ratio:' , ar , "playing only?" , playingOnly )
2018-11-18 18:44:44 +01:00
}
2019-03-10 23:27:50 +01:00
if ( ar . type !== AspectRatio . Automatic ) {
2018-11-21 21:58:13 +01:00
this . stopArDetection ( playingOnly ) ;
2018-11-15 00:18:41 +01:00
} else {
2018-11-18 18:44:44 +01:00
if ( Debug . debug ) {
console . log ( '[PageInfo::setAr] aspect ratio is auto' ) ;
}
try {
for ( var vd of this . videos ) {
2018-11-21 21:58:13 +01:00
if ( ! playingOnly || vd . isPlaying ( ) ) {
vd . resetLastAr ( ) ;
}
2018-11-18 18:44:44 +01:00
}
} catch ( e ) {
console . log ( "???" , e ) ;
2018-11-15 00:18:41 +01:00
}
2018-11-21 21:58:13 +01:00
this . initArDetection ( playingOnly ) ;
this . startArDetection ( playingOnly ) ;
2018-11-15 00:18:41 +01:00
return ;
2018-05-27 01:29:02 +02:00
}
2018-09-14 00:10:57 +02:00
2018-05-13 21:05:11 +02:00
// TODO: find a way to only change aspect ratio for one video
2019-03-10 23:27:50 +01:00
if ( ar === AspectRatio . Reset ) {
2018-09-14 00:10:57 +02:00
for ( var vd of this . videos ) {
2018-11-21 21:58:13 +01:00
if ( ! playingOnly || vd . isPlaying ( ) ) {
vd . resetAr ( ) ;
}
2018-09-14 00:10:57 +02:00
}
} else {
for ( var vd of this . videos ) {
2018-11-21 21:58:13 +01:00
if ( ! playingOnly || vd . isPlaying ( ) ) {
vd . setAr ( ar )
}
2018-09-14 00:10:57 +02:00
}
2018-05-13 21:05:11 +02:00
}
}
2017-12-30 02:58:24 +01:00
2018-12-31 03:34:26 +01:00
setvideoAlignment ( videoAlignment , playingOnly ) {
2018-11-21 21:58:13 +01:00
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( vd . isPlaying ( ) ) {
2018-12-31 03:34:26 +01:00
vd . setvideoAlignment ( videoAlignment )
2018-11-21 21:58:13 +01:00
}
}
} else {
for ( var vd of this . videos ) {
2018-12-31 03:34:26 +01:00
vd . setvideoAlignment ( videoAlignment )
2018-11-21 21:58:13 +01:00
}
2018-09-23 02:39:27 +02:00
}
}
2018-11-21 21:58:13 +01:00
setPanMode ( mode , playingOnly ) {
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( vd . isPlaying ( ) ) {
vd . setPanMode ( mode ) ;
}
}
} else {
for ( var vd of this . videos ) {
vd . setPanMode ( mode ) ;
}
2018-09-13 23:47:20 +02:00
}
}
2018-11-21 21:58:13 +01:00
restoreAr ( playingOnly ) {
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( vd . isPlaying ( ) ) {
vd . restoreAr ( ) ;
}
}
} else {
for ( var vd of this . videos ) {
vd . restoreAr ( ) ;
}
2018-07-15 16:22:32 +02:00
}
}
2018-11-21 21:58:13 +01:00
setStretchMode ( sm , playingOnly ) {
2018-05-27 21:41:08 +02:00
// TODO: find a way to only change aspect ratio for one video
2018-11-21 21:58:13 +01:00
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( vd . isPlaying ( ) ) {
vd . setStretchMode ( sm )
}
}
} else {
for ( var vd of this . videos ) {
vd . setStretchMode ( sm )
}
2018-05-13 21:05:11 +02:00
}
}
2018-11-21 21:58:13 +01:00
setZoom ( zoomLevel , no _announce , playingOnly ) {
if ( playingOnly ) {
for ( var vd of this . videos ) {
if ( vd . isPlaying ( ) ) {
vd . setZoom ( zoomLevel , no _announce ) ;
}
}
} else {
for ( var vd of this . videos ) {
vd . setZoom ( zoomLevel , no _announce ) ;
}
2018-09-18 23:37:33 +02:00
}
}
2018-11-21 21:58:13 +01:00
zoomStep ( step , playingOnly ) {
2018-05-24 20:50:37 +02:00
for ( var vd of this . videos ) {
2018-11-21 21:58:13 +01:00
if ( ! playingOnly || vd . isPlaying ( ) ) {
vd . zoomStep ( step ) ;
}
2018-05-24 20:50:37 +02:00
}
}
2018-09-21 00:26:08 +02:00
2018-12-06 23:55:54 +01:00
markPlayer ( name , color ) {
for ( var vd of this . videos ) {
vd . markPlayer ( name , color ) ;
}
}
unmarkPlayer ( ) {
2018-12-09 01:37:19 +01:00
for ( var vd of this . videos ) {
2018-12-06 23:55:54 +01:00
vd . unmarkPlayer ( ) ;
}
}
2018-09-21 00:26:08 +02:00
announceZoom ( scale ) {
if ( this . announceZoomTimeout ) {
clearTimeout ( this . announceZoom ) ;
}
this . currentZoomScale = scale ;
const ths = this ;
this . announceZoomTimeout = setTimeout ( ( ) => ths . comms . announceZoom ( scale ) , this . settings . active . zoom . announceDebounce ) ;
}
2019-02-16 01:19:29 +01:00
setManualTick ( manualTick ) {
for ( var vd of this . videos ) {
vd . setManualTick ( ) ;
}
}
tick ( ) {
for ( var vd of this . videos ) {
vd . tick ( ) ;
}
}
sendPerformanceUpdate ( performanceUpdate ) {
if ( this . comms ) {
this . comms . sendPerformanceUpdate ( performanceUpdate ) ;
}
}
2018-09-21 00:26:08 +02:00
requestCurrentZoom ( ) {
this . comms . announceZoom ( this . currentZoomScale ) ;
}
2019-06-02 23:54:32 +02:00
setKeyboardShortcutsEnabled ( state ) {
this . actionHandler . setKeybordLocal ( state ) ;
}
2018-05-13 21:05:11 +02:00
}
2018-05-21 22:43:56 +02:00
2018-12-31 01:03:07 +01:00
export default PageInfo ;