diff --git a/.gitignore b/.gitignore index 429d71d2..ba72b6bc 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,8 @@ Thumbs.db # Folder config file Desktop.ini +.angulardoc.json + + +# VS Code +.vscode diff --git a/core.ts b/core.ts index 1b177cd7..21eb1679 100644 --- a/core.ts +++ b/core.ts @@ -3,11 +3,11 @@ export * from './src/core/core'; // CustomEvent polyfill for IE9/10/11 (function () { - if ( typeof window === "undefined" || typeof window['CustomEvent'] === "function" ) return false; + if ( typeof window === "undefined" || typeof window['CustomEvent'] === "function" ) { return false; } function CustomEvent ( event, params ) { params = params || { bubbles: false, cancelable: false, detail: undefined }; - var evt = document.createEvent( 'CustomEvent' ); + let evt = document.createEvent( 'CustomEvent' ); evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail ); return evt; } diff --git a/karma-test-shim.js b/karma-test-shim.js index 7ab39cdb..374f6d76 100644 --- a/karma-test-shim.js +++ b/karma-test-shim.js @@ -17,7 +17,7 @@ function isSpecFile(path) { } function isBuiltFile(path) { - var builtPath = '/base/src/'; + var builtPath = '/base/compiled/'; return isJsFile(path) && (path.substr(0, builtPath.length) == builtPath); } @@ -41,7 +41,6 @@ System.config( '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', - '@angular/http': 'npm:@angular/http/bundles/http.umd.js', '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', @@ -51,11 +50,10 @@ System.config( '@angular/compiler/testing': 'npm:@angular/compiler/bundles/compiler-testing.umd.js', '@angular/platform-browser/testing': 'npm:@angular/platform-browser/bundles/platform-browser-testing.umd.js', '@angular/platform-browser-dynamic/testing': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic-testing.umd.js', - '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js', '@angular/router/testing': 'npm:@angular/router/bundles/router-testing.umd.js', '@angular/forms/testing': 'npm:@angular/forms/bundles/forms-testing.umd.js', - 'app': 'base/src' + 'app': 'base/compiled/src' }, packages: { 'rxjs/operators': { defaultExtension: 'js', main: 'index' }, diff --git a/karma.conf.js b/karma.conf.js index 6cb7f0e2..2cb25f20 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -26,8 +26,9 @@ module.exports = function(config) { {pattern: 'karma-test-shim.js', included: true, watched: true}, + // Our built application code - {pattern: 'src/**/*.js', included: false, watched: true}, + {pattern: 'compiled/**/*.js', included: false, watched: true}, // paths loaded via Angular's component compiler // (these paths need to be rewritten, see proxies section) diff --git a/package.json b/package.json index 00fcad07..e5a3bbb1 100644 --- a/package.json +++ b/package.json @@ -7,70 +7,73 @@ "url": "https://github.com/videogular/videogular2" }, "peerDependencies": { - "@angular/core": "^7.1.0", + "@angular/core": "^8.0.0", "rxjs": "^6.3.0" }, "devDependencies": { - "@angular/animations": "^7.1.4", - "@angular/common": "^7.1.4", - "@angular/compiler": "^7.1.4", - "@angular/compiler-cli": "^7.0.4", - "@angular/core": "^7.1.4", - "@angular/http": "^7.1.4", - "@angular/platform-browser": "^7.1.4", - "@angular/platform-browser-dynamic": "^7.1.4", - "@angular/platform-server": "^7.1.4", + "@angular/animations": "^8.0.0", + "@angular/cli": "8.0.1", + "@angular/common": "^8.0.0", + "@angular/compiler": "^8.0.0", + "@angular/compiler-cli": "^8.0.0", + "@angular/core": "^8.0.0", + "@angular/platform-browser": "^8.0.0", + "@angular/platform-browser-dynamic": "^8.0.0", + "@angular/platform-server": "^8.0.0", "@types/bluebird": "^3.5.25", "@types/core-js": "0.9.46", "@types/jasmine": "^3.3.1", "@types/node": "10.12.12", - "codelyzer": "^4.5.0", + "codelyzer": "5.1.0", "commitizen": "2.9.6", "core-js": "^2.6.0", "cz-conventional-changelog": "2.0.0", "es-module-loader": "2.3.0", "http-server": "0.11.1", - "husky": "^1.3.0", + "husky": "^2.4.0", "jasmine-core": "^3.3.0", - "karma": "^3.1.3", + "karma": "^4.1.0", "karma-chrome-launcher": "^2.2.0", - "karma-firefox-launcher": "^1.1.0", "karma-coverage": "^1.1.2", + "karma-firefox-launcher": "^1.1.0", "karma-jasmine": "^2.0.1", "karma-spec-reporter": "^0.0.32", - "parallelshell": "2.0.0", + "npm-run-all": "4.1.5", "reflect-metadata": "^0.1.10", "remap-istanbul": "0.9.5", "rimraf": "2.6.1", - "rxjs": "^6.3.0", + "rxjs": "6.5.2", "semantic-release": "6.3.2", "systemjs": "^0.20.19", - "tslint": "^5.11.0", - "typescript": "~3.1.1", + "tslint": "5.17.0", + "typescript": "~3.4.5", "validate-commit-msg": "2.12.1", "watch": "1.0.2", - "zone.js": "^0.8.26" + "zone.js": "0.9.1" }, "scripts": { - "commitmsg": "validate-commit-msg", "prebuild": "npm run clean", "build": "ngc", "postbuild": "npm test", "build:travis": "ngc", "postbuild:travis": "npm run test", "clean": "rimraf -rf ./src/**/*.js && rimraf -rf ./src/**/*.d.ts && rimraf -rf ./compiled", - "precommit": "npm test", "commit": "git-cz", "coverage": "http-server -c-1 -o -s -p 9875 ./coverage", - "start": "parallelshell \"npm run watch:ts\" \"npm run start:coverage-server\"", + "start": "run-p \"watch:ts\" \"start:coverage-server\"", "start:coverage-server": "http-server -c-1 -o -p 9875 ./coverage", "test": "karma start karma.conf.js", "posttest": "remap-istanbul -i ./coverage/coverage-final.json -o coverage -t html", "report-coverage": "cat ./coverage/coverage-final.json | ./node_modules/.bin/remap-istanbul -o coverage-remapped.json", "semantic-release": "semantic-release pre && npm publish && semantic-release post", "watch:ts": "watch \"npm run build\" src", - "parallelshell": "parallelshell", - "lint": "tslint '**/*.ts' -e 'node_modules/**/*' -e 'compiled/**/**' --fix --noUnusedParameters --noUnusedLocals" + "lint": "tslint -p tsconfig.json -c tslint.json --fix" + }, + "husky": { + "hooks": { + "pre-commit": "npm test", + "commit-msg": "validate-commit-msg" + } }, "engines": { "node": ">=10.9.0 <11.0.0" diff --git a/src/buffering/vg-buffering.spec.ts b/src/buffering/vg-buffering.spec.ts index b8a91d47..7b2d6a29 100644 --- a/src/buffering/vg-buffering.spec.ts +++ b/src/buffering/vg-buffering.spec.ts @@ -1,47 +1,45 @@ -import {VgBuffering} from "./vg-buffering"; -import {VgAPI} from "../core/services/vg-api"; -import {IPlayable} from "../core/vg-media/i-playable"; -import {ElementRef} from "@angular/core"; -import { VgStates } from "../core/states/vg-states"; +import { VgBuffering } from './vg-buffering'; +import { VgAPI } from '../core/services/vg-api'; +import { ElementRef } from '@angular/core'; describe('Buffering', () => { - let vgBuffering:VgBuffering; - let ref:ElementRef; - let api:VgAPI; + let vgBuffering: VgBuffering; + let ref: ElementRef; + let api: VgAPI; - beforeEach(() => { - ref = { - nativeElement: { - getAttribute: (name) => { - return name; - } - } - }; + beforeEach(() => { + ref = { + nativeElement: { + getAttribute: (name) => { + return name; + } + } + }; - api = new VgAPI(); - vgBuffering = new VgBuffering(ref, api); - }); + api = new VgAPI(); + vgBuffering = new VgBuffering(ref, api); + }); - describe('onPlayerReady', ()=>{ - it('should subscribe to bufferDetected media events', ()=>{ - spyOn(api, 'getMediaById').and.returnValue({ - subscriptions: { - bufferDetected: {subscribe: jasmine.createSpy('bufferDetected') } - } - }); - vgBuffering.onPlayerReady(); - expect(vgBuffering.target.subscriptions.bufferDetected.subscribe).toHaveBeenCalled(); - }); + describe('onPlayerReady', () => { + it('should subscribe to bufferDetected media events', () => { + spyOn(api, 'getMediaById').and.returnValue({ + subscriptions: { + bufferDetected: { subscribe: jasmine.createSpy('bufferDetected') } + } + }); + vgBuffering.onPlayerReady(); + expect(vgBuffering.target.subscriptions.bufferDetected.subscribe).toHaveBeenCalled(); }); + }); - describe('isBuffering', ()=> { - it('should show if buffer is detected', () => { - vgBuffering.onUpdateBuffer(true); - expect(vgBuffering.isBuffering).toBe(true); - }); - it('should hide if buffer is not detected', () => { - vgBuffering.onUpdateBuffer(false); - expect(vgBuffering.isBuffering).toBe(false); - }); + describe('isBuffering', () => { + it('should show if buffer is detected', () => { + vgBuffering.onUpdateBuffer(true); + expect(vgBuffering.isBuffering).toBe(true); + }); + it('should hide if buffer is not detected', () => { + vgBuffering.onUpdateBuffer(false); + expect(vgBuffering.isBuffering).toBe(false); }); + }); }); diff --git a/src/buffering/vg-buffering.ts b/src/buffering/vg-buffering.ts index 1e1a3b4f..50cb1d4e 100644 --- a/src/buffering/vg-buffering.ts +++ b/src/buffering/vg-buffering.ts @@ -1,7 +1,6 @@ import { Component, ElementRef, HostBinding, Input, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core'; import { VgAPI } from '../core/services/vg-api'; import { IPlayable } from '../core/vg-media/i-playable'; -import { VgStates } from '../core/states/vg-states'; import { Subscription } from 'rxjs'; @Component({ @@ -106,13 +105,13 @@ export class VgBuffering implements OnInit, OnDestroy { elem: HTMLElement; target: IPlayable; - checkInterval: number = 50; - currentPlayPos: number = 0; - lastPlayPos: number = 0; + checkInterval = 50; + currentPlayPos = 0; + lastPlayPos = 0; subscriptions: Subscription[] = []; - @HostBinding('class.is-buffering') isBuffering: boolean = false; + @HostBinding('class.is-buffering') isBuffering = false; constructor(ref: ElementRef, public API: VgAPI) { this.elem = ref.nativeElement; diff --git a/src/controls/vg-controls.ts b/src/controls/vg-controls.ts index 13fc1f97..ff91169f 100644 --- a/src/controls/vg-controls.ts +++ b/src/controls/vg-controls.ts @@ -1,6 +1,5 @@ import { - Component, Input, OnInit, ElementRef, HostBinding, AfterViewInit, ViewEncapsulation, - EventEmitter, Output, OnDestroy + Component, Input, OnInit, ElementRef, HostBinding, AfterViewInit, ViewEncapsulation, OnDestroy } from '@angular/core'; import { Observable , Subscription } from 'rxjs'; import { VgAPI } from '../core/services/vg-api'; @@ -29,7 +28,7 @@ import {fromEvent} from 'rxjs'; transition: bottom 1s; } - vg-controls.hide { + vg-controls.hide { bottom: -50px; } `] @@ -38,21 +37,20 @@ export class VgControls implements OnInit, AfterViewInit, OnDestroy { elem: HTMLElement; target: any; - @HostBinding('style.pointer-events') isAdsPlaying: string = 'initial'; - @HostBinding('class.hide') hideControls: boolean = false; + @HostBinding('style.pointer-events') isAdsPlaying = 'initial'; + @HostBinding('class.hide') hideControls = false; @Input() vgFor: string; - @Input() vgAutohide: boolean = false; - @Input() vgAutohideTime: number = 3; + @Input() vgAutohide = false; + @Input() vgAutohideTime = 3; private timer: any; - private hideTimer: any; mouseMove$: Observable; touchStart$: Observable; subscriptions: Subscription[] = []; - + // @ts-ignore constructor(private API: VgAPI, private ref: ElementRef, private hidden: VgControlsHidden) { this.elem = ref.nativeElement; } diff --git a/src/controls/vg-fullscreen/vg-fullscreen.spec.ts b/src/controls/vg-fullscreen/vg-fullscreen.spec.ts index e61d36ae..64fbd731 100644 --- a/src/controls/vg-fullscreen/vg-fullscreen.spec.ts +++ b/src/controls/vg-fullscreen/vg-fullscreen.spec.ts @@ -1,56 +1,56 @@ -import {VgFullscreen} from "./vg-fullscreen"; -import {VgAPI} from "../../core/services/vg-api"; -import {ElementRef} from "@angular/core"; -import {VgFullscreenAPI} from "../../core/services/vg-fullscreen-api"; +import { VgFullscreen } from './vg-fullscreen'; +import { VgAPI } from '../../core/services/vg-api'; +import { ElementRef } from '@angular/core'; +import { VgFullscreenAPI } from '../../core/services/vg-fullscreen-api'; describe('Videogular Player', () => { - let fullscreen: VgFullscreen; - let ref:ElementRef; - let api:VgAPI; - let fsAPI:VgFullscreenAPI; - + let fullscreen: VgFullscreen; + let ref: ElementRef; + let api: VgAPI; + let fsAPI: VgFullscreenAPI; + + beforeEach(() => { + ref = { + nativeElement: { + getAttribute: (name) => { + return name; + } + } + }; + + api = new VgAPI(); + fsAPI = new VgFullscreenAPI(); + fullscreen = new VgFullscreen(ref, api, fsAPI); + }); + + it('Should get media by id on init', () => { + spyOn(api, 'getMediaById').and.callFake(() => {}); + + fullscreen.vgFor = 'test'; + fullscreen.onPlayerReady(); + + expect(api.getMediaById).toHaveBeenCalledWith('test'); + }); + + describe('onClick', () => { beforeEach(() => { - ref = { - nativeElement: { - getAttribute: (name) => { - return name; - } - } - }; - - api = new VgAPI(); - fsAPI = new VgFullscreenAPI(); - fullscreen = new VgFullscreen(ref, api, fsAPI); + spyOn(fsAPI, 'toggleFullscreen'); }); - it('Should get media by id on init', () => { - spyOn(api, 'getMediaById').and.callFake(() => { }); + it('Should call toggleFullscreen with null param if target is API', () => { + fullscreen.target = api; - fullscreen.vgFor = 'test'; - fullscreen.onPlayerReady(); + fullscreen.onClick(); - expect(api.getMediaById).toHaveBeenCalledWith('test'); + expect(fsAPI.toggleFullscreen).toHaveBeenCalledWith(null); }); - describe('onClick', () => { - beforeEach(() => { - spyOn(fsAPI, 'toggleFullscreen'); - }); - - it('Should call toggleFullscreen with null param if target is API', () => { - fullscreen.target = api; - - fullscreen.onClick(); - - expect(fsAPI.toggleFullscreen).toHaveBeenCalledWith(null); - }); - - it('Should call toggleFullscreen with target param if target', () => { - fullscreen.target = 'test'; + it('Should call toggleFullscreen with target param if target', () => { + fullscreen.target = 'test'; - fullscreen.onClick(); + fullscreen.onClick(); - expect(fsAPI.toggleFullscreen).toHaveBeenCalledWith('test'); - }); + expect(fsAPI.toggleFullscreen).toHaveBeenCalledWith('test'); }); + }); }); diff --git a/src/controls/vg-fullscreen/vg-fullscreen.ts b/src/controls/vg-fullscreen/vg-fullscreen.ts index 3cf8d935..32815142 100644 --- a/src/controls/vg-fullscreen/vg-fullscreen.ts +++ b/src/controls/vg-fullscreen/vg-fullscreen.ts @@ -42,7 +42,7 @@ export class VgFullscreen implements OnInit, OnDestroy { elem: HTMLElement; vgFor: string; target: Object; - isFullscreen: boolean = false; + isFullscreen = false; subscriptions: Subscription[] = []; diff --git a/src/controls/vg-mute/vg-mute.spec.ts b/src/controls/vg-mute/vg-mute.spec.ts index 7b38e412..7f89c87f 100644 --- a/src/controls/vg-mute/vg-mute.spec.ts +++ b/src/controls/vg-mute/vg-mute.spec.ts @@ -1,127 +1,122 @@ -import {VgMute} from "./vg-mute"; -import {VgAPI} from "../../core/services/vg-api"; -import {ElementRef} from "@angular/core"; +import { VgMute } from './vg-mute'; +import { VgAPI } from '../../core/services/vg-api'; +import { ElementRef } from '@angular/core'; describe('Mute Button', () => { - let mute:VgMute; - let ref:ElementRef; - let api:VgAPI; - - beforeEach(() => { - ref = { - nativeElement: { - getAttribute: (name) => { - return name; - } - } - }; - - api = new VgAPI(); - api.medias = { - main: { - id: 'main', - volume: 1 - }, - secondary: { - id: 'secondary', - volume: 0.5 - } - }; - - - mute = new VgMute(ref, api); + let mute: VgMute; + let ref: ElementRef; + let api: VgAPI; + + beforeEach(() => { + ref = { + nativeElement: { + getAttribute: (name) => { + return name; + } + } + }; + + api = new VgAPI(); + api.medias = { + main: { + id: 'main', + volume: 1 + }, + secondary: { + id: 'secondary', + volume: 0.5 + } + }; + + mute = new VgMute(ref, api); + }); + + it('Should get media by id on init', () => { + spyOn(api, 'getMediaById').and.callFake(() => { volume: 1 }); + + mute.vgFor = 'test'; + mute.onPlayerReady(); + + expect(api.getMediaById).toHaveBeenCalledWith('test'); + expect(mute.currentVolume).toBe(1); + }); + + it('Should get volume for one media file', () => { + api.medias = { + main: { + volume: 1 + } + }; + + mute.target = api; + + let volume = mute.getVolume(); + + expect(volume).toBe(1); + }); + + describe('onClick (single media)', () => { + it('should mute volume if current volume is different than 0', () => { + api.medias = { + main: { + volume: 0.75 + } + }; + + mute.target = api; + + mute.onClick(); + + expect(mute.currentVolume).toBe(0.75); + expect(api.volume).toEqual(0); }); - it('Should get media by id on init', () => { - spyOn(api, 'getMediaById').and.callFake(() => { - return { - volume: 1 - }; - }); + it('should unmute volume if current volume is 0', () => { + api.medias = { + main: { + volume: 0 + } + }; - mute.vgFor = 'test'; - mute.onPlayerReady(); + mute.target = api; - expect(api.getMediaById).toHaveBeenCalledWith('test'); - expect(mute.currentVolume).toBe(1); - }); - - it('Should get volume for one media file', () => { - api.medias = { - main: { - volume: 1 - } - }; - - mute.target = api; + mute.currentVolume = 0.75; - let volume = mute.getVolume(); + mute.onClick(); - expect(volume).toBe(1); + expect(api.volume).toEqual(0.75); }); + }); - describe('onClick (single media)', () => { - it('should mute volume if current volume is different than 0', () => { - api.medias = { - main: { - volume: 0.75 - } - }; - - mute.target = api; - - mute.onClick(); - - expect(mute.currentVolume).toBe(0.75); - expect(api.volume).toEqual(0); - }); + describe('onClick (multiple medias)', () => { + it('should mute volume if current volume is different than 0', () => { + mute.target = api; - it('should unmute volume if current volume is 0', () => { - api.medias = { - main: { - volume: 0 - } - }; + mute.onClick(); - mute.target = api; - - mute.currentVolume = 0.75; - - mute.onClick(); - - expect(api.volume).toEqual(0.75); - }); + expect(mute.currentVolume).toBe(1); + expect(api.volume).toEqual(0); }); - describe('onClick (multiple medias)', () => { - it('should mute volume if current volume is different than 0', () => { - mute.target = api; - - mute.onClick(); - - expect(mute.currentVolume).toBe(1); - expect(api.volume).toEqual(0); - }); - - it('should unmute volume if current volume is 0', () => { - api.medias = { - main: { - id: 'main', - volume: 0 - }, - secondary: { - id: 'secondary', - volume: 0 - } - }; + it('should unmute volume if current volume is 0', () => { + api.medias = { + main: { + id: 'main', + volume: 0 + }, + secondary: { + id: 'secondary', + volume: 0 + } + }; - mute.target = api; + mute.target = api; - mute.currentVolume = 0.75; + mute.currentVolume = 0.75; - mute.onClick(); + mute.onClick(); - expect(api.volume).toEqual(0.75); - }); + expect(api.volume).toEqual(0.75); }); + }); }); diff --git a/src/controls/vg-play-pause/vg-play-pause.spec.ts b/src/controls/vg-play-pause/vg-play-pause.spec.ts index 0fd5a98d..788b0fb3 100644 --- a/src/controls/vg-play-pause/vg-play-pause.spec.ts +++ b/src/controls/vg-play-pause/vg-play-pause.spec.ts @@ -1,110 +1,105 @@ -import {VgPlayPause} from "./vg-play-pause"; -import {VgAPI} from "../../core/services/vg-api"; -import {ElementRef} from "@angular/core"; -import {VgStates} from "../../core/states/vg-states"; +import { VgPlayPause } from './vg-play-pause'; +import { VgAPI } from '../../core/services/vg-api'; +import { ElementRef } from '@angular/core'; +import { VgStates } from '../../core/states/vg-states'; describe('Play/Pause Button', () => { - let playPause:VgPlayPause; - let ref:ElementRef; - let api:VgAPI; - - beforeEach(() => { - ref = { - nativeElement: { - getAttribute: (name) => { - return name; - } - } - }; - - api = new VgAPI(); - api.medias = { - main: { - state: VgStates.VG_PLAYING - }, - secondary: { - state: VgStates.VG_PAUSED - } - }; - - - playPause = new VgPlayPause(ref, api); + let playPause: VgPlayPause; + let ref: ElementRef; + let api: VgAPI; + + beforeEach(() => { + ref = { + nativeElement: { + getAttribute: (name) => { + return name; + } + } + }; + + api = new VgAPI(); + api.medias = { + main: { + state: VgStates.VG_PLAYING + }, + secondary: { + state: VgStates.VG_PAUSED + } + }; + + playPause = new VgPlayPause(ref, api); + }); + + it('Should get media by id on init', () => { + spyOn(api, 'getMediaById').and.callFake(() => { volume: 1 }); + + playPause.vgFor = 'test'; + playPause.onPlayerReady(); + + expect(api.getMediaById).toHaveBeenCalledWith('test'); + }); + + it('Should get state for one media file', () => { + api.medias = { + main: { + state: VgStates.VG_PLAYING + } + }; + + playPause.target = api; + + let state = playPause.getState(); + + expect(state).toBe(VgStates.VG_PLAYING); + }); + + describe('onClick (single and multiple media)', () => { + it('should pause if current state is different play', () => { + spyOn(api, 'pause').and.callFake(() => {}); + + api.medias = { + main: { + state: VgStates.VG_PLAYING + } + }; + + playPause.target = api; + + playPause.onClick(); + + expect(api.pause).toHaveBeenCalled(); }); - it('Should get media by id on init', () => { - spyOn(api, 'getMediaById').and.callFake(() => { - return { - volume: 1 - }; - }); + it('should play if current state is pause', () => { + spyOn(api, 'play').and.callFake(() => {}); - playPause.vgFor = 'test'; - playPause.onPlayerReady(); + api.medias = { + main: { + state: VgStates.VG_PAUSED + } + }; - expect(api.getMediaById).toHaveBeenCalledWith('test'); - }); - - it('Should get state for one media file', () => { - api.medias = { - main: { - state: VgStates.VG_PLAYING - } - }; + playPause.target = api; - playPause.target = api; + playPause.onClick(); - let state = playPause.getState(); - - expect(state).toBe(VgStates.VG_PLAYING); + expect(api.play).toHaveBeenCalled(); }); - describe('onClick (single and multiple media)', () => { - it('should pause if current state is different play', () => { - spyOn(api, 'pause').and.callFake(() => {}); - - api.medias = { - main: { - state: VgStates.VG_PLAYING - } - }; - - playPause.target = api; - - playPause.onClick(); - - expect(api.pause).toHaveBeenCalled(); - }); - - it('should play if current state is pause', () => { - spyOn(api, 'play').and.callFake(() => {}); - - api.medias = { - main: { - state: VgStates.VG_PAUSED - } - }; - - playPause.target = api; - - playPause.onClick(); - - expect(api.play).toHaveBeenCalled(); - }); - - it('should play if current state is ended', () => { - spyOn(api, 'play').and.callFake(() => {}); + it('should play if current state is ended', () => { + spyOn(api, 'play').and.callFake(() => {}); - api.medias = { - main: { - state: VgStates.VG_ENDED - } - }; + api.medias = { + main: { + state: VgStates.VG_ENDED + } + }; - playPause.target = api; + playPause.target = api; - playPause.onClick(); + playPause.onClick(); - expect(api.play).toHaveBeenCalled(); - }); + expect(api.play).toHaveBeenCalled(); }); + }); }); diff --git a/src/controls/vg-playback-button/vg-playback-button.spec.ts b/src/controls/vg-playback-button/vg-playback-button.spec.ts index aef3490c..5cb7b6d7 100644 --- a/src/controls/vg-playback-button/vg-playback-button.spec.ts +++ b/src/controls/vg-playback-button/vg-playback-button.spec.ts @@ -1,91 +1,90 @@ -import {VgPlaybackButton} from "./vg-playback-button"; -import {VgAPI} from "../../core/services/vg-api"; -import {ElementRef} from "@angular/core"; -import {VgStates} from "../../core/states/vg-states"; +import { VgPlaybackButton } from './vg-playback-button'; +import { VgAPI } from '../../core/services/vg-api'; +import { ElementRef } from '@angular/core'; +import { VgStates } from '../../core/states/vg-states'; describe('Playback Button', () => { - let playbackButton:VgPlaybackButton; - let ref:ElementRef; - let api:VgAPI; - - beforeEach(() => { - ref = { - nativeElement: { - getAttribute: (name) => { - return name; - } - } - }; - - api = new VgAPI(); - api.medias = { - main: { - state: VgStates.VG_PLAYING - }, - secondary: { - state: VgStates.VG_PAUSED - } - }; - - - playbackButton = new VgPlaybackButton(ref, api); + let playbackButton: VgPlaybackButton; + let ref: ElementRef; + let api: VgAPI; + + beforeEach(() => { + ref = { + nativeElement: { + getAttribute: (name) => { + return name; + } + } + }; + + api = new VgAPI(); + api.medias = { + main: { + state: VgStates.VG_PLAYING + }, + secondary: { + state: VgStates.VG_PAUSED + } + }; + + playbackButton = new VgPlaybackButton(ref, api); + }); + + it('Should set playbackIndex default value to 1', () => { + expect(playbackButton.playbackIndex).toEqual(1); + }); + + it('Should get media by id on init', () => { + spyOn(api, 'getMediaById').and.callFake(() => {}); + + playbackButton.vgFor = 'test'; + playbackButton.onPlayerReady(); + + expect(api.getMediaById).toHaveBeenCalledWith('test'); + }); + + describe('onClick (single and multiple media)', () => { + it('should increase playbackIndex', () => { + api.medias = { + main: { + state: VgStates.VG_PLAYING + } + }; + + playbackButton.target = api; + + playbackButton.onClick(); + + expect(playbackButton.playbackIndex).toEqual(2); }); - it('Should set playbackIndex default value to 1', () => { - expect(playbackButton.playbackIndex).toEqual(1); - }); + it('should set playbackRate to target media', () => { + api.medias = { + main: { + state: VgStates.VG_PLAYING + } + }; - it('Should get media by id on init', () => { - spyOn(api, 'getMediaById').and.callFake(() => { }); + playbackButton.target = api; - playbackButton.vgFor = 'test'; - playbackButton.onPlayerReady(); + playbackButton.onClick(); - expect(api.getMediaById).toHaveBeenCalledWith('test'); + expect(playbackButton.target.playbackRate).toEqual('1.5'); }); - describe('onClick (single and multiple media)', () => { - it('should increase playbackIndex', () => { - api.medias = { - main: { - state: VgStates.VG_PLAYING - } - }; - - playbackButton.target = api; - - playbackButton.onClick(); - - expect(playbackButton.playbackIndex).toEqual(2); - }); - - it('should set playbackRate to target media', () => { - api.medias = { - main: { - state: VgStates.VG_PLAYING - } - }; - - playbackButton.target = api; - - playbackButton.onClick(); - - expect(playbackButton.target.playbackRate).toEqual('1.5'); - }); - - it('should set playbackRate to target media', () => { - let media = { - playbackRate: { - test: '1' - } - }; + it('should set playbackRate to target media', () => { + let media = { + playbackRate: { + test: '1' + } + }; - playbackButton.target = media; - playbackButton.vgFor = 'test'; + playbackButton.target = media; + playbackButton.vgFor = 'test'; - playbackButton.onClick(); + playbackButton.onClick(); - expect(playbackButton.target.playbackRate.test).toEqual('1.5'); - }); + expect(playbackButton.target.playbackRate.test).toEqual('1.5'); }); + }); }); diff --git a/src/controls/vg-quality-selector/vg-quality-selector.spec.ts b/src/controls/vg-quality-selector/vg-quality-selector.spec.ts index ad940292..48822f0c 100644 --- a/src/controls/vg-quality-selector/vg-quality-selector.spec.ts +++ b/src/controls/vg-quality-selector/vg-quality-selector.spec.ts @@ -3,6 +3,8 @@ import { VgAPI } from "../../core/services/vg-api"; import { ElementRef } from "@angular/core"; describe('Quality Selector control', () => { + + // @ts-ignore let vgQualitySelector: VgQualitySelector; beforeEach(() => { diff --git a/src/controls/vg-quality-selector/vg-quality-selector.ts b/src/controls/vg-quality-selector/vg-quality-selector.ts index 130a5fa0..7c164cc6 100644 --- a/src/controls/vg-quality-selector/vg-quality-selector.ts +++ b/src/controls/vg-quality-selector/vg-quality-selector.ts @@ -116,7 +116,7 @@ export class VgQualitySelector implements OnInit, OnChanges, OnDestroy { ngOnChanges(changes: SimpleChanges) { if (changes['bitrates'].currentValue && changes['bitrates'].currentValue.length) { - this.bitrates.forEach(item => item.label = item.label || Math.round(item.bitrate / 1000).toString()) + this.bitrates.forEach(item => item.label = item.label || Math.round(item.bitrate / 1000).toString()); } } diff --git a/src/controls/vg-scrub-bar/vg-scrub-bar-cue-points/vg-scrub-bar-cue-points.ts b/src/controls/vg-scrub-bar/vg-scrub-bar-cue-points/vg-scrub-bar-cue-points.ts index f589225c..a3843851 100644 --- a/src/controls/vg-scrub-bar/vg-scrub-bar-cue-points/vg-scrub-bar-cue-points.ts +++ b/src/controls/vg-scrub-bar/vg-scrub-bar-cue-points/vg-scrub-bar-cue-points.ts @@ -5,6 +5,7 @@ import { OnChanges, OnDestroy, OnInit, + DoCheck, SimpleChange, ViewEncapsulation } from '@angular/core'; @@ -41,13 +42,13 @@ import { Subscription } from 'rxjs'; } ` ] }) -export class VgScrubBarCuePoints implements OnInit, OnChanges, OnDestroy { +export class VgScrubBarCuePoints implements OnInit, OnChanges, OnDestroy, DoCheck { @Input() vgCuePoints: TextTrackCueList; @Input() vgFor: string; elem: HTMLElement; target: any; - onLoadedMetadataCalled: boolean = false; + onLoadedMetadataCalled = false; cuePoints: Array = []; subscriptions: Subscription[] = []; diff --git a/src/controls/vg-scrub-bar/vg-scrub-bar-current-time/vg-scrub-bar-current-time.ts b/src/controls/vg-scrub-bar/vg-scrub-bar-current-time/vg-scrub-bar-current-time.ts index 745af3de..fedd526e 100644 --- a/src/controls/vg-scrub-bar/vg-scrub-bar-current-time/vg-scrub-bar-current-time.ts +++ b/src/controls/vg-scrub-bar/vg-scrub-bar-current-time/vg-scrub-bar-current-time.ts @@ -47,7 +47,7 @@ import { Subscription } from 'rxjs'; }) export class VgScrubBarCurrentTime implements OnInit, OnDestroy { @Input() vgFor: string; - @Input() vgSlider: boolean = false; + @Input() vgSlider = false; elem: HTMLElement; target: any; diff --git a/src/controls/vg-scrub-bar/vg-scrub-bar.spec.ts b/src/controls/vg-scrub-bar/vg-scrub-bar.spec.ts index 1860b408..78d61eeb 100644 --- a/src/controls/vg-scrub-bar/vg-scrub-bar.spec.ts +++ b/src/controls/vg-scrub-bar/vg-scrub-bar.spec.ts @@ -40,7 +40,7 @@ describe('Scrub bar', () => { detach: () => {}, reattach: () => {}, checkNoChanges: () => {} - } + }; api = new VgAPI(); media = new VgMedia(api, cdRef); diff --git a/src/controls/vg-scrub-bar/vg-scrub-bar.ts b/src/controls/vg-scrub-bar/vg-scrub-bar.ts index 6f563f8f..f6f31392 100644 --- a/src/controls/vg-scrub-bar/vg-scrub-bar.ts +++ b/src/controls/vg-scrub-bar/vg-scrub-bar.ts @@ -22,7 +22,7 @@ import { Subscription } from 'rxjs'; [attr.aria-valuetext]="getPercentage() + '%'"> - + `, styles: [ ` vg-scrub-bar { @@ -46,7 +46,7 @@ import { Subscription } from 'rxjs'; -ms-transition: bottom 1s, opacity 0.5s; transition: bottom 1s, opacity 0.5s; } - + vg-scrub-bar .scrubBar { position: relative; display: flex; @@ -82,15 +82,15 @@ import { Subscription } from 'rxjs'; ` ] }) export class VgScrubBar implements OnInit, OnDestroy { - @HostBinding('class.hide') hideScrubBar: boolean = false; + @HostBinding('class.hide') hideScrubBar = false; @Input() vgFor: string; - @Input() vgSlider: boolean = true; + @Input() vgSlider = true; elem: HTMLElement; target: any; - isSeeking: boolean = false; - wasPlaying: boolean = false; + isSeeking = false; + wasPlaying = false; subscriptions: Subscription[] = []; @@ -151,7 +151,7 @@ export class VgScrubBar implements OnInit, OnDestroy { } protected getTouchOffset(event: any) { - let offsetLeft: number = 0; + let offsetLeft = 0; let element: any = event.target; while (element) { offsetLeft += element.offsetLeft; @@ -214,18 +214,16 @@ export class VgScrubBar implements OnInit, OnDestroy { } } } - - @HostListener('document:touchcancel', [ '$event' ]) - onTouchCancelScrubBar($event: any) { + // @ts-ignore + @HostListener('document:touchcancel', [ '$event' ]) onTouchCancelScrubBar($event: any) { if (this.target) { if (!this.target.isLive && this.vgSlider && this.isSeeking) { this.touchEnd(); } } } - - @HostListener('document:touchend', [ '$event' ]) - onTouchEndScrubBar($event: any) { + // @ts-ignore + @HostListener('document:touchend', [ '$event' ]) onTouchEndScrubBar($event: any) { if (this.target) { if (!this.target.isLive && this.vgSlider && this.isSeeking) { this.touchEnd(); diff --git a/src/controls/vg-time-display/vg-time-display.spec.ts b/src/controls/vg-time-display/vg-time-display.spec.ts index e3375ec5..495f38ce 100644 --- a/src/controls/vg-time-display/vg-time-display.spec.ts +++ b/src/controls/vg-time-display/vg-time-display.spec.ts @@ -6,6 +6,7 @@ describe('Time Display', () => { let timeDisplay:VgTimeDisplay; let ref:ElementRef; let api:VgAPI; + // @ts-ignore let renderer; beforeEach(() => { diff --git a/src/controls/vg-time-display/vg-time-display.ts b/src/controls/vg-time-display/vg-time-display.ts index 12acf191..6edd4046 100644 --- a/src/controls/vg-time-display/vg-time-display.ts +++ b/src/controls/vg-time-display/vg-time-display.ts @@ -59,8 +59,8 @@ export class VgUtcPipe implements PipeTransform { }) export class VgTimeDisplay implements OnInit, OnDestroy { @Input() vgFor: string; - @Input() vgProperty: string = 'current'; - @Input() vgFormat: string = 'mm:ss'; + @Input() vgProperty = 'current'; + @Input() vgFormat = 'mm:ss'; elem: HTMLElement; target: any; diff --git a/src/controls/vg-track-selector/vg-track-selector.spec.ts b/src/controls/vg-track-selector/vg-track-selector.spec.ts index 1faaf703..51b6caae 100644 --- a/src/controls/vg-track-selector/vg-track-selector.spec.ts +++ b/src/controls/vg-track-selector/vg-track-selector.spec.ts @@ -1,101 +1,105 @@ -import {VgTrackSelector} from "./vg-track-selector"; -import {VgAPI} from "../../core/services/vg-api"; -import {ElementRef} from "@angular/core"; +import { VgTrackSelector } from './vg-track-selector'; +import { VgAPI } from '../../core/services/vg-api'; +import { ElementRef } from '@angular/core'; describe('Track Selector control', () => { - let vgTrackSelector:VgTrackSelector; + let vgTrackSelector: VgTrackSelector; - function createSubtitleTrack(label:string, srclang:string, isDefault:boolean) { - const track:HTMLTrackElement = {} as HTMLTrackElement; - (track as any).tagName = 'TRACK'; - track.kind = 'subtitles'; - track.label = label; - track.srclang = srclang; - track.default = isDefault; - return track; - } + function createSubtitleTrack(label: string, srclang: string, isDefault: boolean) { + const track: HTMLTrackElement = {} as HTMLTrackElement; + (track as any).tagName = 'TRACK'; + track.kind = 'subtitles'; + track.label = label; + track.srclang = srclang; + track.default = isDefault; + return track; + } + beforeEach(() => { + const ref: ElementRef = { + nativeElement: { + getAttribute: (name) => { + return name; + } + } + }; + vgTrackSelector = new VgTrackSelector(ref, new VgAPI()); + }); + + describe('onPlayerReady', () => { beforeEach(() => { - const ref:ElementRef = { - nativeElement: { - getAttribute: (name) => { - return name; - } - } - }; - vgTrackSelector = new VgTrackSelector(ref, new VgAPI()); + vgTrackSelector.API.getMasterMedia = () => { + return { + elem: { + children: [ + createSubtitleTrack('English', 'en', false), + createSubtitleTrack('Español', 'es', true), + {} as HTMLTrackElement, + {} as HTMLTrackElement, + {} as HTMLTrackElement + ] + } + } as any; + }; + }); + it('Should show subtitles tracks only', () => { + vgTrackSelector.onPlayerReady(); + expect(vgTrackSelector.tracks.length).toBe(3); // 2 subs + 'Off' + }); + it('Should set the selected option', () => { + vgTrackSelector.onPlayerReady(); + expect(vgTrackSelector.tracks.filter((item) => item.selected === true)[0].label).toBe( + 'Español' + ); + }); + it('Should have an Off option', () => { + vgTrackSelector.onPlayerReady(); + expect(vgTrackSelector.tracks.filter((item) => item.label === 'Off').length).toBe(1); }); + it('Should set Off option as selected when there is no default track', () => { + vgTrackSelector.API.getMasterMedia = () => { + return { + elem: { + children: [ + createSubtitleTrack('English', 'en', false), + createSubtitleTrack('Español', 'es', false) + ] + } + } as any; + }; + vgTrackSelector.onPlayerReady(); + expect(vgTrackSelector.tracks.filter((item) => item.selected === true)[0].label).toBe( + 'Off' + ); + }); + }); - describe('onPlayerReady', () => { - beforeEach(() => { - vgTrackSelector.API.getMasterMedia = () => { - return {elem: { - children: [ - createSubtitleTrack('English', 'en', false), - createSubtitleTrack('Español', 'es', true), - {} as HTMLTrackElement, - {} as HTMLTrackElement, - {} as HTMLTrackElement - ] - }} as any; - }; - }); - it('Should show subtitles tracks only', ()=> { - vgTrackSelector.onPlayerReady(); - expect(vgTrackSelector.tracks.length).toBe(3);// 2 subs + 'Off' - }); - it('Should set the selected option', ()=> { - vgTrackSelector.onPlayerReady(); - expect(vgTrackSelector.tracks.filter(item=>item.selected===true)[0].label).toBe('Español'); - }); - it('Should have an Off option', ()=> { - vgTrackSelector.onPlayerReady(); - expect(vgTrackSelector.tracks.filter(item=>item.label==='Off').length).toBe(1); - }); - it('Should set Off option as selected when there is no default track', ()=> { - vgTrackSelector.API.getMasterMedia = () => { - return {elem: { - children: [ - createSubtitleTrack('English', 'en', false), - createSubtitleTrack('Español', 'es', false) - ] - }} as any; - }; - vgTrackSelector.onPlayerReady(); - expect(vgTrackSelector.tracks.filter(item=>item.selected===true)[0].label).toBe('Off'); - }); + describe('selectTrack', () => { + beforeEach(() => { + spyOn(vgTrackSelector.API, 'getMasterMedia').and.returnValue({ + elem: { + textTracks: [ + { mode: 'showing', language: 'en' }, + { mode: 'hidden', language: 'es' } + ] + } + }); + }); + it('Should select by track id', () => { + vgTrackSelector.selectTrack('es'); + expect( + (vgTrackSelector.API.getMasterMedia().elem as any).textTracks.filter( + (item) => item.mode === 'showing' + )[0].language + ).toBe('es'); }); - - describe('selectTrack', () => { - beforeEach(() => { - spyOn(vgTrackSelector.API, 'getMasterMedia').and.returnValue({ - elem: { - textTracks: [ - {mode: 'showing', language: 'en'}, - {mode: 'hidden', language: 'es'} - ] - } - }); - }); - it('Should select by track id', ()=> { - vgTrackSelector.selectTrack('es'); - expect( - (vgTrackSelector.API.getMasterMedia().elem as any) - .textTracks - .filter( - (item)=>item.mode==='showing' - )[0].language - ).toBe('es'); - }); - it('Should select Off when track id is null', ()=> { - vgTrackSelector.selectTrack(null); - expect( - (vgTrackSelector.API.getMasterMedia().elem as any) - .textTracks - .filter( - (item)=>item.mode==='showing' - ).length - ).toBe(0); - }); + it('Should select Off when track id is null', () => { + vgTrackSelector.selectTrack(null); + expect( + (vgTrackSelector.API.getMasterMedia().elem as any).textTracks.filter( + (item) => item.mode === 'showing' + ).length + ).toBe(0); }); + }); }); diff --git a/src/controls/vg-volume/vg-volume.spec.ts b/src/controls/vg-volume/vg-volume.spec.ts index f936b8ae..a25dbfa3 100644 --- a/src/controls/vg-volume/vg-volume.spec.ts +++ b/src/controls/vg-volume/vg-volume.spec.ts @@ -102,7 +102,7 @@ describe('Volume control', () => { vgVol.volumeBarRef = { nativeElement: { getBoundingClientRect() { - return { left: 5, width: 100 } + return { left: 5, width: 100 }; } } }; diff --git a/src/controls/vg-volume/vg-volume.ts b/src/controls/vg-volume/vg-volume.ts index f9d766b7..cf549018 100644 --- a/src/controls/vg-volume/vg-volume.ts +++ b/src/controls/vg-volume/vg-volume.ts @@ -1,15 +1,21 @@ import { - Component, Input, ElementRef, HostListener, OnInit, ViewEncapsulation, ViewChild, - OnDestroy + Component, + Input, + ElementRef, + HostListener, + OnInit, + ViewEncapsulation, + ViewChild, + OnDestroy } from '@angular/core'; import { VgAPI } from '../../core/services/vg-api'; import { Subscription } from 'rxjs'; @Component({ - selector: 'vg-volume', - encapsulation: ViewEncapsulation.None, - template: ` -
`, - styles: [ ` + styles: [ + ` vg-volume { -webkit-touch-callout: none; -webkit-user-select: none; @@ -78,94 +85,96 @@ import { Subscription } from 'rxjs'; vg-volume .volumeBackground.dragging .volumeKnob { transition: none; } - ` ] + ` + ] }) export class VgVolume implements OnInit, OnDestroy { - @Input() vgFor: string; - @ViewChild('volumeBar') volumeBarRef: ElementRef; + @Input() vgFor: string; + @ViewChild('volumeBar', { static: true }) + volumeBarRef: ElementRef; - elem: HTMLElement; - target: any; - isDragging: boolean; - mouseDownPosX: number; - ariaValue: number; + elem: HTMLElement; + target: any; + isDragging: boolean; + mouseDownPosX: number; + ariaValue: number; - subscriptions: Subscription[] = []; + subscriptions: Subscription[] = []; - constructor(ref: ElementRef, public API: VgAPI) { - this.elem = ref.nativeElement; - this.isDragging = false; - } + constructor(ref: ElementRef, public API: VgAPI) { + this.elem = ref.nativeElement; + this.isDragging = false; + } - ngOnInit() { - if (this.API.isPlayerReady) { - this.onPlayerReady(); - } - else { - this.subscriptions.push(this.API.playerReadyEvent.subscribe(() => this.onPlayerReady())); - } + ngOnInit() { + if (this.API.isPlayerReady) { + this.onPlayerReady(); + } else { + this.subscriptions.push( + this.API.playerReadyEvent.subscribe(() => this.onPlayerReady()) + ); } + } - onPlayerReady() { - this.target = this.API.getMediaById(this.vgFor); - this.ariaValue = this.getVolume() * 100; - } + onPlayerReady() { + this.target = this.API.getMediaById(this.vgFor); + this.ariaValue = this.getVolume() * 100; + } - onClick(event: { clientX: number }) { - this.setVolume(this.calculateVolume(event.clientX)); - } + onClick(event: { clientX: number }) { + this.setVolume(this.calculateVolume(event.clientX)); + } - onMouseDown(event: { clientX: number }) { - this.mouseDownPosX = event.clientX; - this.isDragging = true; - } + onMouseDown(event: { clientX: number }) { + this.mouseDownPosX = event.clientX; + this.isDragging = true; + } - @HostListener('document:mousemove', [ '$event' ]) - onDrag(event: { clientX: number }) { - if (this.isDragging) { - this.setVolume(this.calculateVolume(event.clientX)); - } + @HostListener('document:mousemove', [ '$event' ]) + onDrag(event: { clientX: number }) { + if (this.isDragging) { + this.setVolume(this.calculateVolume(event.clientX)); } + } - @HostListener('document:mouseup', [ '$event' ]) - onStopDrag(event: { clientX: number }) { - if (this.isDragging) { - this.isDragging = false; - if (this.mouseDownPosX === event.clientX) { - this.setVolume(this.calculateVolume(event.clientX)); - } - } + @HostListener('document:mouseup', [ '$event' ]) + onStopDrag(event: { clientX: number }) { + if (this.isDragging) { + this.isDragging = false; + if (this.mouseDownPosX === event.clientX) { + this.setVolume(this.calculateVolume(event.clientX)); + } } + } - @HostListener('keydown', ['$event']) - arrowAdjustVolume(event: KeyboardEvent) { - if (event.keyCode === 38 || event.keyCode === 39) { - event.preventDefault(); - this.setVolume(Math.max(0, Math.min(100,(this.getVolume() * 100) + 10))); - } - else if (event.keyCode === 37 || event.keyCode === 40) { - event.preventDefault(); - this.setVolume(Math.max(0, Math.min(100,(this.getVolume() * 100) - 10))); - } + @HostListener('keydown', [ '$event' ]) + arrowAdjustVolume(event: KeyboardEvent) { + if (event.keyCode === 38 || event.keyCode === 39) { + event.preventDefault(); + this.setVolume(Math.max(0, Math.min(100, this.getVolume() * 100 + 10))); + } else if (event.keyCode === 37 || event.keyCode === 40) { + event.preventDefault(); + this.setVolume(Math.max(0, Math.min(100, this.getVolume() * 100 - 10))); } + } - calculateVolume(mousePosX: number) { - const recObj = this.volumeBarRef.nativeElement.getBoundingClientRect(); - const volumeBarOffsetLeft: number = recObj.left; - const volumeBarWidth: number = recObj.width; - return (mousePosX - volumeBarOffsetLeft) / volumeBarWidth * 100; - } + calculateVolume(mousePosX: number) { + const recObj = this.volumeBarRef.nativeElement.getBoundingClientRect(); + const volumeBarOffsetLeft: number = recObj.left; + const volumeBarWidth: number = recObj.width; + return (mousePosX - volumeBarOffsetLeft) / volumeBarWidth * 100; + } - setVolume(vol: number) { - this.target.volume = Math.max(0, Math.min(1, vol / 100)); - this.ariaValue = this.target.volume * 100; - } + setVolume(vol: number) { + this.target.volume = Math.max(0, Math.min(1, vol / 100)); + this.ariaValue = this.target.volume * 100; + } - getVolume(): number { - return this.target ? this.target.volume : 0; - } + getVolume(): number { + return this.target ? this.target.volume : 0; + } - ngOnDestroy() { - this.subscriptions.forEach(s => s.unsubscribe()); - } + ngOnDestroy() { + this.subscriptions.forEach((s) => s.unsubscribe()); + } } diff --git a/src/core/events/vg-events.ts b/src/core/events/vg-events.ts index af2f9da2..82de85d1 100644 --- a/src/core/events/vg-events.ts +++ b/src/core/events/vg-events.ts @@ -2,35 +2,35 @@ import {Injectable} from '@angular/core'; @Injectable() export class VgEvents { - static VG_ABORT: string = 'abort'; - static VG_CAN_PLAY: string = 'canplay'; - static VG_CAN_PLAY_THROUGH: string = 'canplaythrough'; - static VG_DURATION_CHANGE: string = 'durationchange'; - static VG_EMPTIED: string = 'emptied'; - static VG_ENCRYPTED: string = 'encrypted'; - static VG_ENDED: string = 'ended'; - static VG_ERROR: string = 'error'; - static VG_LOADED_DATA: string = 'loadeddata'; - static VG_LOADED_METADATA: string = 'loadedmetadata'; - static VG_LOAD_START: string = 'loadstart'; - static VG_PAUSE: string = 'pause'; - static VG_PLAY: string = 'play'; - static VG_PLAYING: string = 'playing'; - static VG_PROGRESS: string = 'progress'; - static VG_RATE_CHANGE: string = 'ratechange'; - static VG_SEEK: string = 'seek'; - static VG_SEEKED: string = 'seeked'; - static VG_SEEKING: string = 'seeking'; - static VG_STALLED: string = 'stalled'; - static VG_SUSPEND: string = 'suspend'; - static VG_TIME_UPDATE: string = 'timeupdate'; - static VG_VOLUME_CHANGE: string = 'volumechange'; - static VG_WAITING: string = 'waiting'; + static VG_ABORT = 'abort'; + static VG_CAN_PLAY = 'canplay'; + static VG_CAN_PLAY_THROUGH = 'canplaythrough'; + static VG_DURATION_CHANGE = 'durationchange'; + static VG_EMPTIED = 'emptied'; + static VG_ENCRYPTED = 'encrypted'; + static VG_ENDED = 'ended'; + static VG_ERROR = 'error'; + static VG_LOADED_DATA = 'loadeddata'; + static VG_LOADED_METADATA = 'loadedmetadata'; + static VG_LOAD_START = 'loadstart'; + static VG_PAUSE = 'pause'; + static VG_PLAY = 'play'; + static VG_PLAYING = 'playing'; + static VG_PROGRESS = 'progress'; + static VG_RATE_CHANGE = 'ratechange'; + static VG_SEEK = 'seek'; + static VG_SEEKED = 'seeked'; + static VG_SEEKING = 'seeking'; + static VG_STALLED = 'stalled'; + static VG_SUSPEND = 'suspend'; + static VG_TIME_UPDATE = 'timeupdate'; + static VG_VOLUME_CHANGE = 'volumechange'; + static VG_WAITING = 'waiting'; - static VG_LOAD: string = 'load'; - static VG_ENTER: string = 'enter'; - static VG_EXIT: string = 'exit'; + static VG_LOAD = 'load'; + static VG_ENTER = 'enter'; + static VG_EXIT = 'exit'; - static VG_START_ADS: string = 'startads'; - static VG_END_ADS: string = 'endads'; + static VG_START_ADS = 'startads'; + static VG_END_ADS = 'endads'; } diff --git a/src/core/services/vg-api.spec.ts b/src/core/services/vg-api.spec.ts index aa65f1df..28133ee6 100644 --- a/src/core/services/vg-api.spec.ts +++ b/src/core/services/vg-api.spec.ts @@ -96,7 +96,7 @@ describe('Videogular Player', () => { it('Should get duration', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let duration = api.duration; expect(api.$$getAllProperties).toHaveBeenCalledWith('duration'); @@ -112,7 +112,7 @@ describe('Videogular Player', () => { it('Should get state', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let state = api.state; expect(api.$$getAllProperties).toHaveBeenCalledWith('state'); @@ -128,7 +128,7 @@ describe('Videogular Player', () => { it('Should get currentTime', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let currentTime = api.currentTime; expect(api.$$getAllProperties).toHaveBeenCalledWith('currentTime'); @@ -144,7 +144,7 @@ describe('Videogular Player', () => { it('Should get volume', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let volume = api.volume; expect(api.$$getAllProperties).toHaveBeenCalledWith('volume'); @@ -160,7 +160,7 @@ describe('Videogular Player', () => { it('Should get playbackRate', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let playbackRate = api.playbackRate; expect(api.$$getAllProperties).toHaveBeenCalledWith('playbackRate'); @@ -168,7 +168,7 @@ describe('Videogular Player', () => { it('Should get canPlay', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let canPlay = api.canPlay; expect(api.$$getAllProperties).toHaveBeenCalledWith('canPlay'); @@ -176,7 +176,7 @@ describe('Videogular Player', () => { it('Should get canPlayThrough', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let canPlayThrough = api.canPlayThrough; expect(api.$$getAllProperties).toHaveBeenCalledWith('canPlayThrough'); @@ -184,7 +184,7 @@ describe('Videogular Player', () => { it('Should get isMetadataLoaded', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let isMetadataLoaded = api.isMetadataLoaded; expect(api.$$getAllProperties).toHaveBeenCalledWith('isMetadataLoaded'); @@ -192,7 +192,7 @@ describe('Videogular Player', () => { it('Should get isWaiting', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let isWaiting = api.isWaiting; expect(api.$$getAllProperties).toHaveBeenCalledWith('isWaiting'); @@ -200,7 +200,7 @@ describe('Videogular Player', () => { it('Should get isCompleted', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let isCompleted = api.isCompleted; expect(api.$$getAllProperties).toHaveBeenCalledWith('isCompleted'); @@ -208,7 +208,7 @@ describe('Videogular Player', () => { it('Should get time', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let time = api.time; expect(api.$$getAllProperties).toHaveBeenCalledWith('time'); @@ -216,7 +216,7 @@ describe('Videogular Player', () => { it('Should get buffer', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let time = api.buffer; expect(api.$$getAllProperties).toHaveBeenCalledWith('buffer'); @@ -224,7 +224,7 @@ describe('Videogular Player', () => { it('Should get buffered', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let buffered = api.buffered; expect(api.$$getAllProperties).toHaveBeenCalledWith('buffered'); @@ -232,7 +232,7 @@ describe('Videogular Player', () => { it('Should get subscriptions', () => { spyOn(api, '$$getAllProperties').and.callFake(() => {}); - + // @ts-ignore let subscriptions = api.subscriptions; expect(api.$$getAllProperties).toHaveBeenCalledWith('subscriptions'); diff --git a/src/core/services/vg-api.ts b/src/core/services/vg-api.ts index ff44fa6b..a249a2e0 100644 --- a/src/core/services/vg-api.ts +++ b/src/core/services/vg-api.ts @@ -8,7 +8,7 @@ export class VgAPI { medias:Object = {};// TODO: refactor to Set videogularElement: any; playerReadyEvent: EventEmitter = new EventEmitter(true); - isPlayerReady: boolean = false; + isPlayerReady = false; fsAPI: VgFullscreenAPI; constructor() { diff --git a/src/core/services/vg-fullscreen-api.ts b/src/core/services/vg-fullscreen-api.ts index c3d3bb60..757f309a 100644 --- a/src/core/services/vg-fullscreen-api.ts +++ b/src/core/services/vg-fullscreen-api.ts @@ -1,15 +1,15 @@ import { EventEmitter, Injectable, QueryList } from '@angular/core'; import { VgUtils } from './vg-utils'; import { VgMedia } from '../vg-media/vg-media'; -import { Subscription , Observable, fromEvent } from 'rxjs'; +import { Subscription, fromEvent } from 'rxjs'; @Injectable() export class VgFullscreenAPI { polyfill: any; onchange: string; onerror: string; - nativeFullscreen: boolean = true; - isFullscreen: boolean = false; + nativeFullscreen = true; + isFullscreen = false; isAvailable: boolean; videogularElement: HTMLElement; medias: QueryList; @@ -83,7 +83,7 @@ export class VgFullscreenAPI { } if (VgUtils.isiOSDevice()) { - this.polyfill = APIs.ios + this.polyfill = APIs.ios; } this.isAvailable = (this.polyfill != null); diff --git a/src/core/services/vg-utils.spec.ts b/src/core/services/vg-utils.spec.ts index 5fcb6ec9..8e0b6735 100644 --- a/src/core/services/vg-utils.spec.ts +++ b/src/core/services/vg-utils.spec.ts @@ -1,34 +1,30 @@ -import {VgUtils} from "./vg-utils"; +import { VgUtils } from './vg-utils'; describe('Videogular Utils', () => { - it('Should get the highest z-index', () => { - spyOn(window, 'getComputedStyle').and.callFake(() => { - return { - 'z-index': 2 - }; - }); + it('Should get the highest z-index', () => { + spyOn(window, 'getComputedStyle').and.callFake(() => { 'z-index': 2 }); - let highestZ = VgUtils.getZIndex(); + let highestZ = VgUtils.getZIndex(); - expect(highestZ).toBe(3); - }); + expect(highestZ).toBe(3); + }); - it('Should get if is a mobile device', () => { - // window.orientation is not writable - let isMobileDevice = VgUtils.isMobileDevice(); + it('Should get if is a mobile device', () => { + // window.orientation is not writable + let isMobileDevice = VgUtils.isMobileDevice(); - expect(isMobileDevice).toBeFalsy(); - }); + expect(isMobileDevice).toBeFalsy(); + }); - it('Should get if is an iOS device', () => { - let isiOS = VgUtils.isiOSDevice(); + it('Should get if is an iOS device', () => { + let isiOS = VgUtils.isiOSDevice(); - expect(isiOS).toBeFalsy(); - }); + expect(isiOS).toBeFalsy(); + }); - it('Should get if is a Cordova app', () => { - let isCordova = VgUtils.isCordova(); + it('Should get if is a Cordova app', () => { + let isCordova = VgUtils.isCordova(); - expect(isCordova).toBeFalsy(); - }); + expect(isCordova).toBeFalsy(); + }); }); diff --git a/src/core/services/vg-utils.ts b/src/core/services/vg-utils.ts index 3664129e..9ac5fc97 100644 --- a/src/core/services/vg-utils.ts +++ b/src/core/services/vg-utils.ts @@ -27,13 +27,13 @@ export class VgUtils { // Very simple mobile detection, not 100% reliable static isMobileDevice() { return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf("IEMobile") !== -1); - }; + } static isiOSDevice() { return (navigator.userAgent.match(/ip(hone|ad|od)/i) && !navigator.userAgent.match(/(iemobile)[\/\s]?([\w\.]*)/i)); - }; + } static isCordova() { return document.URL.indexOf('http://') === -1 && document.URL.indexOf('https://') === -1; - }; + } } diff --git a/src/core/states/vg-states.ts b/src/core/states/vg-states.ts index 9a1db403..e7d9fe69 100644 --- a/src/core/states/vg-states.ts +++ b/src/core/states/vg-states.ts @@ -2,8 +2,8 @@ import {Injectable} from '@angular/core'; @Injectable() export class VgStates { - static VG_ENDED: string = 'ended'; - static VG_PAUSED: string = 'paused'; - static VG_PLAYING: string = 'playing'; - static VG_LOADING: string = 'waiting'; + static VG_ENDED = 'ended'; + static VG_PAUSED = 'paused'; + static VG_PLAYING = 'playing'; + static VG_LOADING = 'waiting'; } diff --git a/src/core/vg-cue-points/vg-cue-points.spec.ts b/src/core/vg-cue-points/vg-cue-points.spec.ts index 340e055e..c733df4e 100644 --- a/src/core/vg-cue-points/vg-cue-points.spec.ts +++ b/src/core/vg-cue-points/vg-cue-points.spec.ts @@ -21,7 +21,7 @@ describe('Cue points', () => { cuePoints.ngOnInit(); - expect(cuePoints.onLoad$).toBeDefined() + expect(cuePoints.onLoad$).toBeDefined(); }); xit('Should handle enter/exit events', () => { @@ -31,7 +31,7 @@ describe('Cue points', () => { }; let track = event.target.addTextTrack('captions', 'test'); - let cue = track.addCue(new TextTrackCue(1, 2, 'cue 1')); // Illegal Constructor + track.addCue(new TextTrackCue(1, 2, 'cue 1')); // Illegal Constructor cuePoints.onLoad(event); expect(cuePoints.onEnter$).toBeDefined(); diff --git a/src/core/vg-cue-points/vg-cue-points.ts b/src/core/vg-cue-points/vg-cue-points.ts index 9378ae40..169a389b 100644 --- a/src/core/vg-cue-points/vg-cue-points.ts +++ b/src/core/vg-cue-points/vg-cue-points.ts @@ -1,15 +1,15 @@ -import { Directive, ElementRef, EventEmitter, OnDestroy, OnInit, Output } from '@angular/core'; +import { Directive, ElementRef, EventEmitter, OnDestroy, OnInit, Output, DoCheck } from '@angular/core'; import { VgEvents } from '../events/vg-events'; import { Observable , Subscription, fromEvent } from 'rxjs'; @Directive({ selector: '[vgCuePoints]' }) -export class VgCuePoints implements OnInit, OnDestroy { - @Output('onEnterCuePoint') onEnterCuePoint: EventEmitter = new EventEmitter(); - @Output('onUpdateCuePoint') onUpdateCuePoint: EventEmitter = new EventEmitter(); - @Output('onExitCuePoint') onExitCuePoint: EventEmitter = new EventEmitter(); - @Output('onCompleteCuePoint') onCompleteCuePoint: EventEmitter = new EventEmitter(); +export class VgCuePoints implements OnInit, OnDestroy, DoCheck { + @Output() onEnterCuePoint: EventEmitter = new EventEmitter(); + @Output() onUpdateCuePoint: EventEmitter = new EventEmitter(); + @Output() onExitCuePoint: EventEmitter = new EventEmitter(); + @Output() onCompleteCuePoint: EventEmitter = new EventEmitter(); subscriptions: Subscription[] = []; cuesSubscriptions: Subscription[] = []; diff --git a/src/core/vg-media/i-media-element.ts b/src/core/vg-media/i-media-element.ts index 106fd1be..fcbc1eb3 100644 --- a/src/core/vg-media/i-media-element.ts +++ b/src/core/vg-media/i-media-element.ts @@ -24,7 +24,8 @@ export interface IMediaElement { */ readonly buffered: TimeRanges; /** - * Gets or sets a flag that indicates whether the client provides a set of controls for the media (in case the developer does not include controls for the player). + * Gets or sets a flag that indicates whether the client provides a set of controls for + * the media (in case the developer does not include controls for the player). */ controls: boolean; crossOrigin: string | null; @@ -42,7 +43,8 @@ export interface IMediaElement { */ defaultPlaybackRate: number; /** - * Returns the duration in seconds of the current media resource. A NaN value is returned if duration is not available, or Infinity if the media resource is streaming. + * Returns the duration in seconds of the current media resource. A NaN value is returned if duration + * is not available, or Infinity if the media resource is streaming. */ readonly duration: number; /** @@ -76,7 +78,8 @@ export interface IMediaElement { */ msPlayToDisabled: boolean; /** - * Gets or sets the path to the preferred media source. This enables the Play To target device to stream the media content, which can be DRM protected, from a different location, such as a cloud media server. + * Gets or sets the path to the preferred media source. This enables the Play To target device to + * stream the media content, which can be DRM protected, from a different location, such as a cloud media server. */ msPlayToPreferredSourceUri: string; /** @@ -106,7 +109,8 @@ export interface IMediaElement { */ readonly paused: boolean; /** - * Gets or sets the current rate of speed for the media resource to play. This speed is expressed as a multiple of the normal speed of the media resource. + * Gets or sets the current rate of speed for the media resource to play. This speed is + * expressed as a multiple of the normal speed of the media resource. */ playbackRate: number; /** @@ -161,7 +165,8 @@ export interface IMediaElement { */ msSetMediaProtectionManager(mediaProtectionManager?: any): void; /** - * Pauses the current playback and sets paused to TRUE. This can be used to test whether the media is playing or paused. You can also use the pause or play events to tell whether the media is playing or not. + * Pauses the current playback and sets paused to TRUE. This can be used to test whether the media is + * playing or paused. You can also use the pause or play events to tell whether the media is playing or not. */ pause(): void; /** diff --git a/src/core/vg-media/vg-media-element.ts b/src/core/vg-media/vg-media-element.ts index 2db66a9a..99eaaa6a 100644 --- a/src/core/vg-media/vg-media-element.ts +++ b/src/core/vg-media/vg-media-element.ts @@ -3,7 +3,7 @@ import { IMediaElement } from './i-media-element'; export class VgMediaElement implements IMediaElement { id: string; elem: any; - get audioTracks(): AudioTrackList { return null; }; + get audioTracks(): AudioTrackList { return null; } autoplay: boolean; buffered: TimeRanges; controls: boolean; @@ -51,11 +51,11 @@ export class VgMediaElement implements IMediaElement { NETWORK_IDLE: number; NETWORK_LOADING: number; NETWORK_NO_SOURCE: number; - + // @ts-ignore addTextTrack(kind: string, label?: string, language?: string): TextTrack { return null; } - + // @ts-ignore canPlayType(type: string): string { return null; } @@ -69,13 +69,13 @@ export class VgMediaElement implements IMediaElement { msGetAsCastingSource(): any { return null; } - + // @ts-ignore msInsertAudioEffect(activatableClassId: string, effectRequired: boolean, config?: any): void { } - + // @ts-ignore msSetMediaKeys(mediaKeys: MSMediaKeys): void { } - + // @ts-ignore msSetMediaProtectionManager(mediaProtectionManager?: any): void { } @@ -85,11 +85,11 @@ export class VgMediaElement implements IMediaElement { play(): Promise { return null; } - + // @ts-ignore setMediaKeys(mediaKeys: MediaKeys | any): Promise { return null; } - + // @ts-ignore addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void { } } diff --git a/src/core/vg-media/vg-media.spec.ts b/src/core/vg-media/vg-media.spec.ts index f2666385..1cf5d3cb 100644 --- a/src/core/vg-media/vg-media.spec.ts +++ b/src/core/vg-media/vg-media.spec.ts @@ -8,7 +8,6 @@ import { fakeAsync, tick } from '@angular/core/testing'; describe('Videogular Media', () => { let media:VgMedia; - let ref:{ nativeElement: VgMediaElement }; let cdRef:ChangeDetectorRef; let api:VgAPI; let elem = new VgMediaElement(); @@ -24,9 +23,7 @@ describe('Videogular Media', () => { elem.id = 'testVideo'; beforeEach(() => { - ref = { - nativeElement: elem - }; + cdRef = { detectChanges: () => {}, markForCheck: () => {}, diff --git a/src/core/vg-media/vg-media.ts b/src/core/vg-media/vg-media.ts index 9683a946..a4b07c22 100644 --- a/src/core/vg-media/vg-media.ts +++ b/src/core/vg-media/vg-media.ts @@ -29,23 +29,23 @@ export class VgMedia implements OnInit, OnDestroy, IPlayable { track: any; subscriptions: IMediaSubscriptions | any; - canPlay: boolean = false; - canPlayThrough: boolean = false; - isMetadataLoaded: boolean = false; - isWaiting: boolean = false; - isCompleted: boolean = false; - isLive: boolean = false; + canPlay = false; + canPlayThrough = false; + isMetadataLoaded = false; + isWaiting = false; + isCompleted = false; + isLive = false; - isBufferDetected: boolean = false; + isBufferDetected = false; - checkInterval: number = 200; - currentPlayPos: number = 0; - lastPlayPos: number = 0; + checkInterval = 200; + currentPlayPos = 0; + lastPlayPos = 0; checkBufferSubscription: any; syncSubscription: Subscription; canPlayAllSubscription: any; - playAtferSync: boolean = false; + playAtferSync = false; mutationObs: Subscription; canPlayObs: Subscription; @@ -166,7 +166,7 @@ export class VgMedia implements OnInit, OnDestroy, IPlayable { this.canPlayAllSubscription = combineLatest(canPlayAll).pipe( map((...params) => { const checkReadyState = (event) => { - return event.target.readyState === 4 + return event.target.readyState === 4; }; let allReady: boolean = params.some(checkReadyState); @@ -319,21 +319,21 @@ export class VgMedia implements OnInit, OnDestroy, IPlayable { get textTracks() { return this.vgMedia.textTracks; } - + // @ts-ignore onCanPlay(event: any) { this.isBufferDetected = false; this.bufferDetected.next(this.isBufferDetected); this.canPlay = true; this.ref.detectChanges(); } - + // @ts-ignore onCanPlayThrough(event: any) { this.isBufferDetected = false; this.bufferDetected.next(this.isBufferDetected); this.canPlayThrough = true; this.ref.detectChanges(); } - + // @ts-ignore onLoadMetadata(event: any) { this.isMetadataLoaded = true; @@ -350,23 +350,23 @@ export class VgMedia implements OnInit, OnDestroy, IPlayable { this.isLive = (t === Infinity); this.ref.detectChanges(); } - + // @ts-ignore onWait(event: any) { this.isWaiting = true; this.ref.detectChanges(); } - + // @ts-ignore onComplete(event: any) { this.isCompleted = true; this.state = VgStates.VG_ENDED; this.ref.detectChanges(); } - + // @ts-ignore onStartPlaying(event: any) { this.state = VgStates.VG_PLAYING; this.ref.detectChanges(); } - + // @ts-ignore onPlay(event: any) { this.state = VgStates.VG_PLAYING; @@ -379,7 +379,7 @@ export class VgMedia implements OnInit, OnDestroy, IPlayable { this.startBufferCheck(); this.ref.detectChanges(); } - + // @ts-ignore onPause(event: any) { this.state = VgStates.VG_PAUSED; @@ -392,7 +392,7 @@ export class VgMedia implements OnInit, OnDestroy, IPlayable { this.stopBufferCheck(); this.ref.detectChanges(); } - + // @ts-ignore onTimeUpdate(event: any) { let end = this.buffered.length - 1; @@ -407,7 +407,7 @@ export class VgMedia implements OnInit, OnDestroy, IPlayable { } this.ref.detectChanges(); } - + // @ts-ignore onProgress(event: any) { let end = this.buffered.length - 1; @@ -416,12 +416,12 @@ export class VgMedia implements OnInit, OnDestroy, IPlayable { } this.ref.detectChanges(); } - + // @ts-ignore onVolumeChange(event: any) { // TODO: Save to localstorage the current volume this.ref.detectChanges(); } - + // @ts-ignore onError(event: any) { // TODO: Handle error messages this.ref.detectChanges(); diff --git a/src/core/vg-player/vg-player.spec.ts b/src/core/vg-player/vg-player.spec.ts index 9951b98a..27be5267 100644 --- a/src/core/vg-player/vg-player.spec.ts +++ b/src/core/vg-player/vg-player.spec.ts @@ -1,7 +1,6 @@ -import {async, inject, TestBed} from "@angular/core/testing"; +import {async, TestBed} from "@angular/core/testing"; import {Component} from "@angular/core"; import {VgPlayer} from "./vg-player"; -import {VgMedia} from "../vg-media/vg-media"; import {VgAPI} from "../services/vg-api"; import {VgFullscreenAPI} from "../services/vg-fullscreen-api"; import {ElementRef} from "@angular/core"; @@ -62,7 +61,6 @@ describe('Videogular Player', () => { }); describe('Videogular Player', () => { - let builder; beforeEach(() => { TestBed.configureTestingModule({ diff --git a/src/core/vg-player/vg-player.ts b/src/core/vg-player/vg-player.ts index 6a867c2c..75187b98 100644 --- a/src/core/vg-player/vg-player.ts +++ b/src/core/vg-player/vg-player.ts @@ -45,9 +45,9 @@ import { VgControlsHidden } from '../services/vg-controls-hidden'; export class VgPlayer implements AfterContentInit, OnDestroy { elem: HTMLElement; - @HostBinding('class.fullscreen') isFullscreen: boolean = false; - @HostBinding('class.native-fullscreen') isNativeFullscreen: boolean = false; - @HostBinding('class.controls-hidden') areControlsHidden: boolean = false; + @HostBinding('class.fullscreen') isFullscreen = false; + @HostBinding('class.native-fullscreen') isNativeFullscreen = false; + @HostBinding('class.controls-hidden') areControlsHidden = false; @HostBinding('style.z-index') zIndex: string; @Output() diff --git a/src/ima-ads/vg-ima-ads.ts b/src/ima-ads/vg-ima-ads.ts index 28e8e67d..b76cfe39 100644 --- a/src/ima-ads/vg-ima-ads.ts +++ b/src/ima-ads/vg-ima-ads.ts @@ -41,12 +41,12 @@ export class VgImaAds implements OnInit, OnDestroy { elem: HTMLElement; target: IPlayable; ima: Ima; - isFullscreen: boolean = false; + isFullscreen = false; skipButton: HTMLElement; subscriptions: Subscription[] = []; - @HostBinding('style.display') displayState: string = 'none'; + @HostBinding('style.display') displayState = 'none'; constructor(ref: ElementRef, public API: VgAPI, public fsAPI: VgFullscreenAPI) { this.elem = ref.nativeElement; @@ -176,7 +176,7 @@ export class VgImaAds implements OnInit, OnDestroy { this.ima.adsManager = evt.getAdsManager(this.target); this.processAdsManager(this.ima.adsManager); } - + // @ts-ignore processAdsManager(adsManager: google.ima.AdsManager) { const w = this.API.videogularElement.offsetWidth; const h = this.API.videogularElement.offsetHeight; @@ -243,7 +243,7 @@ export class VgImaAds implements OnInit, OnDestroy { this.onAdStart.emit(true); this.hide(); } - + // @ts-ignore onAdError(evt) { if (this.ima.adsManager) { this.ima.adsManager.destroy(); diff --git a/src/overlay-play/vg-overlay-play.spec.ts b/src/overlay-play/vg-overlay-play.spec.ts index e91a67e3..73cfe642 100644 --- a/src/overlay-play/vg-overlay-play.spec.ts +++ b/src/overlay-play/vg-overlay-play.spec.ts @@ -1,113 +1,117 @@ -import {VgOverlayPlay} from "./vg-overlay-play"; -import {VgAPI} from "../core/services/vg-api"; -import {ElementRef} from "@angular/core"; -import {VgStates} from "../core/states/vg-states"; +import { VgOverlayPlay } from './vg-overlay-play'; +import { VgAPI } from '../core/services/vg-api'; +import { ElementRef } from '@angular/core'; +import { VgStates } from '../core/states/vg-states'; import { VgFullscreenAPI } from '../core/services/vg-fullscreen-api'; import { VgControlsHidden } from '../core/services/vg-controls-hidden'; describe('Videogular Player', () => { - let overlayPlay: VgOverlayPlay; - let ref:ElementRef; - let api:VgAPI; - let fsAPI:VgFullscreenAPI; - let controlsHidden:VgControlsHidden; + let overlayPlay: VgOverlayPlay; + let ref: ElementRef; + let api: VgAPI; + let fsAPI: VgFullscreenAPI; + let controlsHidden: VgControlsHidden; + + beforeEach(() => { + ref = { + nativeElement: { + getAttribute: (name) => { + return name; + } + } + }; + + controlsHidden = { + isHidden: { + subscribe: () => {} + } + } as VgControlsHidden; + + api = new VgAPI(); + fsAPI = new VgFullscreenAPI(); + overlayPlay = new VgOverlayPlay(ref, api, fsAPI, controlsHidden); + }); + + it('Should get media by id on init', () => { + spyOn(api, 'getMediaById').and.returnValue({ + subscriptions: { + bufferDetected: { subscribe: jasmine.createSpy('bufferDetected') } + } + }); + + overlayPlay.vgFor = 'test'; + overlayPlay.onPlayerReady(); + + expect(api.getMediaById).toHaveBeenCalledWith('test'); + expect(overlayPlay.target.subscriptions.bufferDetected.subscribe).toHaveBeenCalled(); + }); + describe('onClick', () => { beforeEach(() => { - ref = { - nativeElement: { - getAttribute: (name) => { - return name; - } - } - }; - - controlsHidden = { - isHidden: { - subscribe: () => {} - } - } as VgControlsHidden; - - api = new VgAPI(); - fsAPI = new VgFullscreenAPI(); - overlayPlay = new VgOverlayPlay(ref, api, fsAPI, controlsHidden); + overlayPlay.target = { + play: () => {}, + pause: () => {} + }; }); - it('Should get media by id on init', () => { - spyOn(api, 'getMediaById').and.returnValue({ - subscriptions: { - bufferDetected: {subscribe: jasmine.createSpy('bufferDetected') } - } - }); + it('current state play should set target to pause', () => { + spyOn(overlayPlay, 'getState').and.callFake(() => { + return VgStates.VG_PLAYING; + }); + spyOn(overlayPlay.target, 'pause'); - overlayPlay.vgFor = 'test'; - overlayPlay.onPlayerReady(); + overlayPlay.onClick(); - expect(api.getMediaById).toHaveBeenCalledWith('test'); - expect(overlayPlay.target.subscriptions.bufferDetected.subscribe).toHaveBeenCalled(); + expect(overlayPlay.getState).toHaveBeenCalled(); + expect(overlayPlay.target.pause).toHaveBeenCalled(); }); - describe('onClick', () => { - beforeEach(() => { - overlayPlay.target = { - play: () => { }, - pause: () => { } - }; - }); + it('current state pause should set target to play', () => { + spyOn(overlayPlay, 'getState').and.callFake(() => { + return VgStates.VG_PAUSED; + }); + spyOn(overlayPlay.target, 'play'); - it('current state play should set target to pause', () => { - spyOn(overlayPlay, 'getState').and.callFake(() => { return VgStates.VG_PLAYING; }); - spyOn(overlayPlay.target, 'pause'); + overlayPlay.onClick(); - overlayPlay.onClick(); + expect(overlayPlay.getState).toHaveBeenCalled(); + expect(overlayPlay.target.play).toHaveBeenCalled(); + }); + }); - expect(overlayPlay.getState).toHaveBeenCalled(); - expect(overlayPlay.target.pause).toHaveBeenCalled(); - }); + describe('getState', () => { + beforeEach(() => { + overlayPlay.target = { + state: null + }; + }); + + it('if only one state returns that state', () => { + overlayPlay.target.state = VgStates.VG_PAUSED; - it('current state pause should set target to play', () => { - spyOn(overlayPlay, 'getState').and.callFake(() => { return VgStates.VG_PAUSED; }); - spyOn(overlayPlay.target, 'play'); + expect(overlayPlay.getState()).toEqual(VgStates.VG_PAUSED); + }); - overlayPlay.onClick(); + it('if more than one target should return pause if all of them are pause', () => { + overlayPlay.target.state = [ + VgStates.VG_PAUSED, + VgStates.VG_PAUSED, + VgStates.VG_PAUSED, + VgStates.VG_PAUSED + ]; - expect(overlayPlay.getState).toHaveBeenCalled(); - expect(overlayPlay.target.play).toHaveBeenCalled(); - }); + expect(overlayPlay.getState()).toEqual(VgStates.VG_PAUSED); }); - describe('getState', () => { - beforeEach(() => { - overlayPlay.target = { - state: null - }; - }); - - it('if only one state returns that state', () => { - overlayPlay.target.state = VgStates.VG_PAUSED; - - expect(overlayPlay.getState()).toEqual(VgStates.VG_PAUSED); - }); - - it('if more than one target should return pause if all of them are pause', () => { - overlayPlay.target.state = [ - VgStates.VG_PAUSED, - VgStates.VG_PAUSED, - VgStates.VG_PAUSED, - VgStates.VG_PAUSED - ]; - - expect(overlayPlay.getState()).toEqual(VgStates.VG_PAUSED); - }); - - it('if more than one target should return play if any of them is play', () => { - overlayPlay.target.state = [ - VgStates.VG_PAUSED, - VgStates.VG_PLAYING, - VgStates.VG_PAUSED, - VgStates.VG_PAUSED - ]; - - expect(overlayPlay.getState()).toEqual(VgStates.VG_PLAYING); - }); + it('if more than one target should return play if any of them is play', () => { + overlayPlay.target.state = [ + VgStates.VG_PAUSED, + VgStates.VG_PLAYING, + VgStates.VG_PAUSED, + VgStates.VG_PAUSED + ]; + + expect(overlayPlay.getState()).toEqual(VgStates.VG_PLAYING); }); + }); }); diff --git a/src/overlay-play/vg-overlay-play.ts b/src/overlay-play/vg-overlay-play.ts index 57ff3d00..5fc21a36 100644 --- a/src/overlay-play/vg-overlay-play.ts +++ b/src/overlay-play/vg-overlay-play.ts @@ -70,12 +70,12 @@ export class VgOverlayPlay implements OnInit, OnDestroy { elem: HTMLElement; target: any; - isNativeFullscreen: boolean = false; - areControlsHidden: boolean = false; + isNativeFullscreen = false; + areControlsHidden = false; subscriptions: Subscription[] = []; - @HostBinding('class.is-buffering') isBuffering: boolean = false; + @HostBinding('class.is-buffering') isBuffering = false; constructor(ref: ElementRef, public API: VgAPI, public fsAPI: VgFullscreenAPI, private controlsHidden: VgControlsHidden) { this.elem = ref.nativeElement; diff --git a/src/streaming/streaming.ts b/src/streaming/streaming.ts index b963691e..c3a358ad 100644 --- a/src/streaming/streaming.ts +++ b/src/streaming/streaming.ts @@ -6,7 +6,7 @@ import { VgHLS } from "./vg-hls/vg-hls"; export interface IDRMLicenseServer { [index: string]: { serverURL: string; - } + }; } @NgModule({ diff --git a/src/streaming/vg-dash/vg-dash.ts b/src/streaming/vg-dash/vg-dash.ts index 596fecec..7552fc4e 100644 --- a/src/streaming/vg-dash/vg-dash.ts +++ b/src/streaming/vg-dash/vg-dash.ts @@ -76,7 +76,9 @@ export class VgDASH implements OnInit, OnChanges, OnDestroy { if (this.vgDRMToken) { for (let drmServer in drmOptions) { - drmOptions[drmServer].httpRequestHeaders = { Authorization: this.vgDRMToken }; + if(drmServer.hasOwnProperty(drmServer)) { + drmOptions[drmServer].httpRequestHeaders = { Authorization: this.vgDRMToken }; + } } } } diff --git a/src/streaming/vg-hls/vg-hls.ts b/src/streaming/vg-hls/vg-hls.ts index 2d576727..d84e03ca 100644 --- a/src/streaming/vg-hls/vg-hls.ts +++ b/src/streaming/vg-hls/vg-hls.ts @@ -50,20 +50,19 @@ export class VgHLS implements OnInit, OnChanges, OnDestroy { this.crossorigin = this.ref.nativeElement.getAttribute('crossorigin'); this.preload = this.ref.nativeElement.getAttribute('preload') !== 'none'; this.vgFor = this.ref.nativeElement.getAttribute('vgFor'); - - if(this.vgFor) - { + + if(this.vgFor){ this.target = this.API.getMediaById(this.vgFor); } else{ this.target = this.API.getDefaultMedia(); } - + this.config = { autoStartLoad: this.preload }; - + // @ts-ignore this.config.xhrSetup = (xhr, url) => { // Send cookies if (this.crossorigin === 'use-credentials') { @@ -111,9 +110,8 @@ export class VgHLS implements OnInit, OnChanges, OnDestroy { let video:HTMLVideoElement = this.ref.nativeElement; this.hls = new Hls(this.config); - this.hls.on( - Hls.Events.MANIFEST_PARSED, - (event, data) => { + // @ts-ignore + this.hls.on(Hls.Events.MANIFEST_PARSED, (event, data) => { const videoList = []; videoList.push({ @@ -139,9 +137,8 @@ export class VgHLS implements OnInit, OnChanges, OnDestroy { this.onGetBitrates.emit(videoList); } ); - this.hls.on( - Hls.Events.LEVEL_LOADED, - (event, data) => { + // @ts-ignore + this.hls.on(Hls.Events.LEVEL_LOADED, (event, data) => { this.target.isLive = data.details.live; } ); diff --git a/tsconfig.json b/tsconfig.json index 94cb5105..1f2c4d91 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,8 +4,11 @@ "noImplicitAny": false, "module": "commonjs", "target": "es5", + "outDir": "compiled", "emitDecoratorMetadata": true, "experimentalDecorators": true, + "noUnusedLocals": true, + "noUnusedParameters": true, "inlineSourceMap": true, "inlineSources": true, "declaration": true, @@ -17,6 +20,6 @@ "coverage/*" ], "angularCompilerOptions": { - "genDir": "compiled" + "skipTemplateCodegen": true } } diff --git a/tslint.json b/tslint.json index f8483d98..4a54c4e5 100644 --- a/tslint.json +++ b/tslint.json @@ -1,4 +1,10 @@ { + "linterOptions": { + "exclude": [ + "node_modules/**/*", + "compiled/**/*" + ] + }, "rulesDirectory": [ "node_modules/codelyzer" ], @@ -46,7 +52,6 @@ "no-switch-case-fall-through": true, "no-trailing-whitespace": false, "no-unused-expression": true, - "no-use-before-declare": true, "no-var-keyword": true, "object-literal-sort-keys": false, "one-line": [ @@ -60,6 +65,7 @@ ], "radix": true, "semicolon": [ + true, "always" ], "triple-equals": [ @@ -89,16 +95,14 @@ "directive-selector": [true, "attribute", "vg", "camelCase"], "component-selector": [true, "element", "vg", "kebab-case"], - "use-input-property-decorator": true, - "use-output-property-decorator": true, - "use-host-property-decorator": true, + "no-inputs-metadata-property": true, + "no-outputs-metadata-property": true, + "no-host-metadata-property": true, "no-input-rename": true, "no-output-rename": true, "use-life-cycle-interface": true, "use-pipe-transform-interface": true, "component-class-suffix": false, - "directive-class-suffix": false, - "templates-use-public": true, - "invoke-injectable": true + "directive-class-suffix": false } }