/**
* @file middleware.js
* @module Middleware
* /
importiere {assign} aus '.. /utils/obj.js ';
importiere {toTitleCase} aus '../utils/string-cases.js';
const Middleware = {};
const MiddlewareInstances = {};
exportiere const TERMINATOR = {};
/**
* Ein Middleware-Objekt ist ein einfaches JavaScript-Objekt mit Methoden, die
* entspricht den {@link Tech} -Methoden, die in den Listen der zulässigen Methoden enthalten sind
* {@link module:middleware.allowedGetters|Getter},
* {@link module:middleware.allowedSetters|setters} und
* {@link module:middleware.allowedMediators|Mediatoren}.
*
* @typedef {Objekt} Middleware-Objekt
* /
/**
* Eine Middleware-Factory-Funktion, die eine zurückgeben sollte
* {@link Module:Middleware~MiddlewareObject|MiddlewareObjekt}.
*
* Diese Fabrik wird bei Bedarf für jeden Spieler zusammen mit dem Spieler aufgerufen
* als Argument übergeben.
*
* @callback Middleware-Fabrik
* @param {Player} Spieler
* Ein Video.js Player.
* /
/**
* Definieren Sie eine Middleware, die der Spieler als Factory-Funktion verwenden soll
* das gibt ein Middleware-Objekt zurück.
*
* @param {string} type
* Der zu übereinstimmende MIME-Typ oder `"*"` für alle MIME-Typen.
*
* @param {MiddlewareFactory} Middleware
* Eine Middleware-Factory-Funktion, die ausgeführt wird für
* passende Typen.
* /
Exportfunktion verwenden (Typ, Middleware) {
Middleware [Typ] = Middleware [Typ] | [];
Middleware [Typ] .push (Middleware);
}
/**
* Ruft Middlewares nach Typ ab (oder alle Middlewares).
*
* @param {string} type
* Der zu übereinstimmende MIME-Typ oder `"*"` für alle MIME-Typen.
*
* @return {Funktion [] |undefiniert}
* Ein Array von Middlewares oder `undefined`, falls keine vorhanden sind.
* /
Exportfunktion getMiddleware (Typ) {
wenn (Typ) {
Middlewares [Typ] zurückgeben;
}
Middleware zurückgeben;
}
/**
* Legt mithilfe von Middleware asynchron eine Quelle fest, indem eine beliebige Quelle wiederholt wird
* passende Middlewares und Aufruf von `setSource` für jede, wobei
* jedes Mal der vorherige Rückgabewert.
*
* @param {Player} Spieler
* Eine {@link Player}-Instanz.
*
* @param {tech~sourceObject} src
* Ein Quellobjekt.
*
* @param {Funktion}
* Die nächste Middleware, die ausgeführt werden soll.
* /
Exportfunktion setSource (player, src, next) {
player.setTimeout () => setSourceHelper (src, Middlewares [src.type], next, player), 1);
}
/**
* Wenn die Technologie eingestellt ist, wird sie an die `SetTech`-Methode jeder Middleware übergeben.
*
* @param {Objekt []} Middleware
* Eine Reihe von Middleware-Instanzen.
*
* @param {Tech} tech
* Ein Video.js Techniker.
* /
Exportfunktion SetTech (Middleware, Tech) {
Middleware.forEach (mw) => mw.SetTech & mw.SetTech (tech));
}
/**
* Ruft zuerst einen Techniker über jede Middleware auf
* von rechts nach links zum Spieler.
*
* @param {Object[]} middleware
* Ein Array von Middleware-Instanzen.
*
* @param {Tech} tech
* Die aktuelle tech.
*
* @param {string} Methode
* Ein Methodenname.
*
* @return {Mixed}
* Der endgültige Wert der Technologie, nachdem die Middleware sie abgefangen hat.
* /
Exportfunktion get (Middleware, Technik, Methode) {
return Middleware.reduceRight (MiddlewareIterator (Methode), tech [Methode] ());
}
/**
* Nimmt das dem Spieler übergebene Argument und ruft bei jedem die Setter-Methode auf
* Middleware von links nach rechts zum Techniker.
*
* @param {Object[]} middleware
* Ein Array von Middleware-Instanzen.
*
* @param {Tech} tech
* Die aktuelle tech.
*
* @param {string} Methode
* Ein Methodenname.
*
* @param {Mixed} arg
* Der Wert, der auf der Tech eingestellt werden soll.
*
* @return {Mixed}
* Der Rückgabewert der `Methode` des `tech`.
* /
Funktionssatz exportieren (Middleware, Technik, Methode, Argument) {
return tech [Methode] (middleware.reduce (MiddlewareIterator (Methode), arg));
}
/**
* Nimmt das dem Spieler übergebene Argument und ruft die `Call`-Version des
* Methode für jede Middleware von links nach rechts.
*
* Rufen Sie dann die übergebene Methode auf dem Tech auf und geben Sie das Ergebnis unverändert zurück
* zurück zum Player, über Middleware, diesmal von rechts nach links.
*
* @param {Object[]} middleware
* Ein Array von Middleware-Instanzen.
*
* @param {Tech} tech
* Die aktuelle tech.
*
* @param {string} Methode
* Ein Methodenname.
*
* @param {Mixed} arg
* Der Wert, der auf der Tech eingestellt werden soll.
*
* @return {Mixed}
* Der Rückgabewert der `Methode` des `tech`, unabhängig von
* Rückgabewerte von Middlewares.
* /
Exportfunktion mediate (Middleware, Tech, Methode, arg = null) {
const callMethod = 'aufrufen' + toTitleCase (Methode);
const MiddlewareValue = middleware.reduce (MiddlewareIterator (CallMethod), arg);
const terminiert = MiddlewareValue === TERMINATOR;
//veraltet. Der Rückgabewert `Null` sollte stattdessen TERMINATOR zurückgeben zu
//verhindert Verwirrung, wenn eine Tech-Methode tatsächlich Null zurückgibt.
const ReturnValue = beendet? null: tech [Methode] (MiddlewareValue);
executeRight (Middleware, Methode, ReturnValue, beendet);
ReturnValue zurückgeben;
}
/**
* Aufzählung der zulässigen Getter, wobei die Schlüssel Methodennamen sind.
*
* @Typ {Objekt}
* /
exportiere const allowedGetters = {
gepuffert: 1,
aktuelleZeit: 1,
Dauer: 1,
stummgeschaltet: 1,
gespielt: 1,
angehalten: 1,
suchbar: 1,
volumen: 1,
endete: 1
};
/**
* Aufzählung der zulässigen Setter, wobei die Schlüssel Methodennamen sind.
*
* @Typ {Objekt}
* /
exportiere const AllowedSetters = {
Aktuelle Uhrzeit festlegen: 1,
Stummschalten: 1,
Lautstärke einstellen: 1
};
/**
* Aufzählung der zulässigen Mediatoren, wobei die Schlüssel Methodennamen sind.
*
* @Typ {Objekt}
* /
exportiere const AllowedMediators = {
abspielen: 1,
Pause: 1
};
Funktion MiddlewareIterator (Methode) {
return (value, mw) => {
//Wenn die vorherige Middleware beendet wurde, geben Sie die Terminierung weiter
if (Wert === TERMINATOR) {
TERMINATOR zurückgeben;
}
if (mw[Methode]) {
gib mw [Methode] (Wert) zurück;
}
rückgabewert;
};
}
Funktion executeRight (mws, Methode, Wert, terminiert) {
für (sei i = mws.length - 1; i >= 0; i--) {
const mw = mws [i];
if (mw[Methode]) {
mw [Methode] (abgeschlossen, Wert);
}
}
}
/**
* Leeren Sie den Middleware-Cache für einen Spieler.
*
* @param {Player} Spieler
* Eine {@link Player}-Instanz.
* /
Exportfunktion ClearCacheForPlayer (Spieler) {
MiddlewareInstances [player.id ()] = null;
}
/**
* {
* [PlayerID]: [MwFactory, MWInstanz],...]
* }
*
* @privat
* /
Funktion getOrCreateFactory (Spieler, mwFactory) {
const mws = MiddlewareInstances [player.id ()];
lass mich = null;
if (ms === undefiniert || ms === null) {
mw = mwFactory(player);
MiddlewareInstances [player.id ()] = [mwFactory, mw]];
zurück mw;
}
für (sei i = 0; i < mws.length; i++) {
const [mwf, mwi] = mws [i];
wenn (mwf! == MWFactory) {
weiter;
}
mw = mwi;
}
wenn (mw === null) {
mw = mwFactory(player);
ms.push ([MWFactory, mw]);
}
zurück mw;
}
function setSourceHelper (src = {}, Middleware = [], next, player, acc = [], lastRun = falsch) {
const [mwFactory,... mwrest] = Middleware;
//wenn mwFactory eine Zeichenfolge ist, dann befinden wir uns an einer Weggabelung
if (typeof MWFactory === 'Zeichenfolge') {
setSourceHelper (src, Middlewares [MWFactory], next, player, acc, lastRun);
//wenn wir eine MWFactory haben, rufe sie mit dem Player auf, um das MW zu bekommen,
//dann rufe die setSource-Methode von mw auf
} sonst wenn (mwFactory) {
const mw = getOrCreateFactory (Spieler, mwFactory);
//wenn setSource nicht vorhanden ist, wählen Sie implizit diese Middleware aus
wenn (! mw.setSource) {
acc.push(mw);
return setSourceHelper(src, mwrest, next, player, acc, lastRun);
}
mw.setSource (assign ({}, src), function (err, _src) {
//etwas ist passiert, probiere die nächste Middleware auf dem aktuellen Level aus
//stelle sicher, dass du das alte src benutzt
if (err) {
return setSourceHelper(src, mwrest, next, player, acc, lastRun);
}
//Es ist uns gelungen, jetzt müssen wir tiefer gehen
acc.push(mw);
//wenn es derselbe Typ ist, setze die aktuelle Kette fort
//sonst wollen wir die neue Kette hinuntergehen
setSourceHelper (
_src,
src.type === _src.type? mrest: Middleware [_src.type],
als nächstes,
spieler,
gemäß,
Letzter Run
);
});
} sonst wenn (mwrest.length) {
setSourceHelper (src, mwrest, next, player, acc, lastRun);
} sonst wenn (LastRun) {
weiter (src, acc);
} sonst {
setSourceHelper (src, Middlewares ['*'], next, player, acc, true);
}
}