From f6184dcba93fe1a760afbe4ba8d63beeb42ef3d1 Mon Sep 17 00:00:00 2001 From: Alex Buznik Date: Wed, 4 Dec 2019 21:55:08 +0200 Subject: [PATCH] Strategies POC --- src/content/Control.Strategies.js | 30 ++++++++++++++++++++++++++++++ src/content/Service.js | 18 ++++++++++++++++++ src/content/ServicesRegistry.js | 27 +++++++++++++++++++++++++++ src/content/Status.Strategies.js | 18 ++++++++++++++++++ src/content/index.js | 28 +++++++++++++++++++++++++++- 5 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/content/Control.Strategies.js create mode 100644 src/content/Service.js create mode 100644 src/content/ServicesRegistry.js create mode 100644 src/content/Status.Strategies.js diff --git a/src/content/Control.Strategies.js b/src/content/Control.Strategies.js new file mode 100644 index 0000000..7b53a17 --- /dev/null +++ b/src/content/Control.Strategies.js @@ -0,0 +1,30 @@ + +import { Status } from './Status.Types.js'; + +export class BaseControlStrategy { + static play() {} + static pause() {} +} + +export class oneOfTheVideos extends BaseControlStrategy { + static getVideosArray() { + return Array.from(document.getElementsByTagName('video')); + } + + static pause() { + oneOfTheVideos.getVideosArray() + .filter((player) => !player.paused) + .forEach((player) => { + player.pause(); + }); + } + + static play() { + oneOfTheVideos.getVideosArray() + .filter((player) => player.paused && player.played.length > 0) + .forEach((player) => { + player.play(); + }); + } + +} diff --git a/src/content/Service.js b/src/content/Service.js new file mode 100644 index 0000000..1746fcc --- /dev/null +++ b/src/content/Service.js @@ -0,0 +1,18 @@ +/* Base Service class */ +export class Service { + constructor(options) { + this.options = options; + } + + getStatus() { + return this.options.statusStrategy.getStatus(); + } + + play() { + this.options.controlStrategy.play(); + } + + pause() { + this.options.controlStrategy.pause(); + } +} diff --git a/src/content/ServicesRegistry.js b/src/content/ServicesRegistry.js new file mode 100644 index 0000000..1e8c136 --- /dev/null +++ b/src/content/ServicesRegistry.js @@ -0,0 +1,27 @@ +import { Service } from './Service.js'; +import * as StatusStrategies from './Status.Strategies.js'; +import * as ControlStrategies from './Control.Strategies.js'; + +export const servicesRegistry = [ + { + hosts: ['ted.com', 'facebook.com', 'kickstarter.com', 'music.youtube.com' ], // we can add support fields, like `host: string`, `hosts: Array` + options: { + statusStrategy: StatusStrategies.oneOfTheVideosPlaying, + controlStrategy: ControlStrategies.oneOfTheVideos + } + }, +]; + +export function getService(domain) { + const matchedService = servicesRegistry.find(serviceConfig => { + return serviceConfig.host === domain + || serviceConfig.hosts.includes(domain) + || serviceConfig.hostPattern.match(domain); + }); + + if (!matchedService) { + return; + } + + return new Service(matchedService.options); +} diff --git a/src/content/Status.Strategies.js b/src/content/Status.Strategies.js new file mode 100644 index 0000000..51fcedd --- /dev/null +++ b/src/content/Status.Strategies.js @@ -0,0 +1,18 @@ +import { Status } from './Status.Types.js'; + +export class BaseStatusStrategy { + static getStatus() {} +} + +/* A shared mixin for when there is a video tag on page */ +export class oneOfTheVideosPlaying extends BaseStatusStrategy { + static getStatus() { + let status = Status.PAUSED; + const videos = document.getElementsByTagName("video"); + if (videos.length > 0) { + const hasPlayingVideo = Array.from(videos).some((player) => !player.paused); + status = hasPlayingVideo ? Status.PLAYING : Status.PAUSED; + } + return status; + } +} diff --git a/src/content/index.js b/src/content/index.js index 057967b..e1b9b47 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -1,6 +1,7 @@ /* StoPlay Content JS */ import { CheckTimer } from './CheckTimer.js'; import { ProviderCheckStatus } from './ProviderCheckStatus.js'; +import { getService } from './ServicesRegistry.js'; import { Status } from './Status.Types.js'; function safeGetElementTextContentByQuery(query) { @@ -45,6 +46,7 @@ class Provider { this.customLastPauseSelector = null; this.checkStatus = new ProviderCheckStatus(); + this.service = null; chrome.storage.sync.get({ enabled: true, @@ -54,7 +56,13 @@ class Provider { this.timer = new CheckTimer({ delay: CHECK_TIMEOUT, callback: () => { - let status = this.checkStatus.check(); + let status; + if (this.service) { + status = this.service.getStatus(); + console.log('service getstatus', status); + } else { + status = this.checkStatus.check(); + } this.__changeState(status); }, recursive: true @@ -161,6 +169,9 @@ class Provider { clearSubDomains = "bandcamp.com"; } if (clearSubDomains) this.host = clearSubDomains; + + this.service = getService(this.host); + return this.host; } @@ -277,6 +288,13 @@ class Provider { let p, selector, selectorQuery, playerPauseButton; if (this.status === Status.PLAYING) { + if (this.service) { + this.service.pause(); + // #TODO: remove duplication for POC + this.__changeState(Status.PAUSED); + return; + } + switch(this.host) { case "radiolist.com.ua": if (this.customLastPlayerSelector) { @@ -549,6 +567,14 @@ class Provider { let p, selector, selectorQuery, playerPlayButton; if (this.status !== Status.PLAYING) { + if (this.service) { + this.service.play(); + // #TODO: remove duplication for POC + this.__changeState(Status.PLAYING); + return; + + } + switch(this.host) { case "radiolist.com.ua": if (this.customLastPlayerSelector) {