/**
* @file plugin.js
* /
importiere evented von './mixins/evented';
import stateful from './mixins/stateful';
importiere * als Ereignisse aus '. /utils/events ';
Protokoll aus 'importieren. /utils/log ';
import Player von './player';
/**
* Der Name des Basis-Plugins.
*
* @privat
* @konstant
* @Typ {String}
* /
const BASE_PLUGIN_NAME = 'Erweiterung';
/**
* Der Schlüssel, auf dem der aktive Plugins-Cache eines Spielers gespeichert ist.
*
* @privat
* @konstant
* @type {Zeichenfolge}
* /
const PLUGIN_CACHE_KEY = 'ActivePlugins_';
/**
* Speichert registrierte Plugins in einem privaten Bereich.
*
* @privat
* @type {Objekt}
* /
const pluginStorage = {};
/**
* Meldet, ob ein Plugin registriert wurde oder nicht.
*
* @privat
* @param {string} name
* Der Name eines Plugins.
*
* @return {boolean}
* Ob das Plugin registriert wurde oder nicht.
* /
const pluginExists = (Name) => pluginStorage.hasOwnProperty (Name);
/**
* Holen Sie sich ein einzelnes registriertes Plugin mit Namen.
*
* @privat
* @param {string} name
* Der Name eines Plugins.
*
* @return {Funktion|undefined}
* Das Plugin (oder undefiniert).
* /
const getPlugin = (Name) => PluginExists (Name)? pluginStorage [Name]: undefiniert;
/**
* Markiert ein Plugin auf einem Player als „aktiv“.
*
* Stellt außerdem sicher, dass der Player über ein Objekt verfügt, um aktive Plugins zu verfolgen.
*
* @privat
* @param {Player} -Spieler
* Eine Player-Instanz von Video.js.
*
* @param {string} name
* Der Name eines Plugins.
* /
const markPluginAsActive = (Spieler, Name) => {
spieler [PLUGIN_CACHE_KEY] = Spieler [PLUGIN_CACHE_KEY] || {};
Spieler [PLUGIN_CACHE_KEY] [Name] = wahr;
};
/**
* Löst ein Paar Plugin-Setup-Ereignisse aus.
*
* @privat
* @param {Player} Spieler
* Eine Player-Instanz von Video.js.
*
* @param {plugin~pluginEventHash} -Hash
* Ein Plugin-Event-Hash.
*
* @param {boolean} [vorher]
* Falls wahr, wird dem Eventnamen das Präfix „before“ vorangestellt. Mit anderen Worten,
* benutze dies, um „beforepluginsetup“ statt „pluginsetup“ auszulösen.
* /
const triggerSetupEvent = (Spieler, Hash, vorher) => {
const eventName = (vorher? 'vorher': „) + 'pluginsetup';
player.trigger (EventName, Hash);
player.trigger (EventName + ':' + Hashname, Hashwert);
};
/**
* Nimmt eine grundlegende Plugin-Funktion und gibt eine Wrapper-Funktion zurück, die markiert
* auf dem Player, dass das Plugin aktiviert wurde.
*
* @privat
* @param {string} name
* Der Name des Plugins.
*
* @param {Funktion} plugin
* Das Basis-Plugin.
*
* @return {Funktion}
* Eine Wrapper-Funktion für das angegebene Plugin.
* /
const createBasicPlugin = Funktion (Name, Plugin) {
const basicPluginWrapper = Funktion () {
//Wir lösen die Ereignisse „beforepluginsetup“ und „pluginsetup“ auf dem Player aus
//unabhängig davon, aber wir möchten, dass der Hash mit dem angegebenen Hash übereinstimmt
//für fortgeschrittene Plugins.
// //
//Die einzige potenziell kontraintuitive Sache hier ist die `Instanz` in
//Das Ereignis „pluginsetup“ ist der Wert, der von der Funktion `plugin` zurückgegeben wird.
triggerSetupEvent (this, {Name, Plugin, Instanz: null}, wahr);
const instance = plugin.apply (dies, Argumente);
markPluginAsActive (dies, Name);
triggerSetupEvent (this, {Name, Plugin, Instanz});
instanz zurückgeben;
};
Object.keys (Plugin) .forEach (Funktion (Requisite) {
basicPluginWrapper [prop] = Plugin [Requisite];
});
gib basicPluginWrapper zurück;
};
/**
* Nimmt eine Plugin-Unterklasse und gibt eine Factory-Funktion zum Generieren zurück
* Beispiele dafür.
*
* Diese Factory-Funktion ersetzt sich selbst durch eine Instanz der angeforderten
* Unterklasse des Plugins.
*
* @privat
* @param {string} name
* Der Name des Plugins.
*
* @param {Plugin} PluginSubclass
* Das erweiterte Plugin.
*
* @return {Funktion}
* /
const createPluginFactory = (Name, PluginSubclass) => {
//Füge dem Plugin-Prototyp eine `name`-Eigenschaft hinzu, damit jedes Plugin
//bezeichnet sich selbst beim Namen.
PluginSubClass.prototype.name = Name;
Funktion zurückgeben (... args) {
TriggerSetupEvent (dies, {name, plugin: pluginSubClass, Instanz: null}, wahr);
const instance = new PluginSubClass (... [das,... Argumente]);
//Das Plugin wird durch eine Funktion ersetzt, die die aktuelle Instanz zurückgibt.
this [name] = () => Instanz;
triggerSetupEvent (dies, instance.getEventHash ());
instanz zurückgeben;
};
};
/**
* Elternklasse für alle fortgeschrittenen Plugins.
*
* @mixes Modul: Evented~EventedMixin
* @mixes Modul: Stateful~StatefulMixin
* @fires Spieler #beforepluginsetup
* @fires Spieler #beforepluginsetup: $name
* @fires Spieler #pluginsetup
* @fires Spieler #pluginsetup: $name
* @listens Spieler #dispose
* @throws {Fehler}
* Beim Versuch, die Basisklasse {@link Plugin} zu instanziieren
* direkt statt über eine Unterklasse.
* /
Klasse Plugin {
/**
* Erzeugt eine Instanz dieser Klasse.
*
* Unterklassen sollten `super` aufrufen, um sicherzustellen, dass die Plugins korrekt initialisiert sind.
*
* @param {Player} Spieler
* Eine Player-Instanz von Video.js.
* /
Konstruktor (Spieler) {
if (this.constructor === Plugin) {
throw new Error ('Das Plugin muss unterklassiert sein; es muss nicht direkt instanziiert sein. ');
}
this.player = Spieler;
wenn (! this.log) {
this.log = this.player.log.createLogger (diese.name);
}
//Mache dieses Objekt ereignisreich, aber entferne die hinzugefügte `Trigger` Methode, damit wir
//verwende stattdessen die Prototyp-Version.
ereignete (dies);
lösche this.trigger;
stateful(this, this.constructor.defaultState);
Plugin als aktiv markieren (player, this.name);
//Bindet die Dispose-Methode automatisch, damit wir sie als Listener verwenden und die Bindung aufheben können
//es später einfach.
this.dispose = this.dispose.bind (dies);
//Wenn der Player entsorgt wird, entsorge das Plugin.
player.on ('entsorgen', diese.entsorgen);
}
/**
* Ruft die Version des Plugins ab, die auf <pluginName>.version gesetzt wurde
* /
version () {
gib this.constructor.Version zurück;
}
/**
* Jedes durch Plugins ausgelöste Ereignis enthält einen Hash zusätzlicher Daten mit
* konventionelle Eigenschaften.
*
* Dies gibt dieses Objekt zurück oder verändert einen vorhandenen Hash.
*
* @param {Object} [hash={}]
* Ein Objekt, das als Event- und Event-Hash verwendet werden soll.
*
* @return {plugin~pluginEventHash}
* Ein Event-Hash-Objekt mit eingemischten angegebenen Eigenschaften.
* /
getEventHash (Hashwert = {}) {
hash.name = diese.name;
hash.plugin = dieser.konstruktor;
hash.instance = das;
Hash zurückgeben;
}
/**
* Löst ein Ereignis im Plugin-Objekt aus und überschreibt
* {@link module:evented~eventedMixin.trigger|EventedMixin.trigger}.
*
* @param {string|Object} event
* Ein Ereignistyp oder ein Objekt mit einer Typeigenschaft.
*
* @param {Object} [hash={}]
* Zusätzlicher Daten-Hash zum Zusammenführen mit einem
* {@link plugin~pluginEventHash|pluginEventHash}.
*
* @return {boolean}
* Ob die Standardeinstellung verhindert wurde oder nicht.
* /
Trigger (Ereignis, Hash = {}) {
return events.trigger (this.eventBusel_, event, this.getEventHash (hash));
}
/**
* Behandelt „statechanged“ -Ereignisse im Plugin. Standardmäßig kein OP, überschreiben von
* Unterklassifizierung.
*
* @Abstrakt
* @param {Veranstaltung}
* Ein Ereignisobjekt, das durch ein „statechanged“ -Ereignis bereitgestellt wird.
*
* @param {Object} e.changes
* Ein Objekt, das Änderungen beschreibt, die mit dem „statechanged“ aufgetreten sind
* Veranstaltung.
* /
handleStateChanged (e) {}
/**
* Verfügt über ein Plugin.
*
* Unterklassen können dies überschreiben, wenn sie wollen, aber aus Sicherheitsgründen
* Es ist wahrscheinlich am besten, die Veranstaltung „Dispose“ zu abonnieren.
*
* @fires Plugin #dispose
* /
dispose() {
const {Name, Spieler} = das;
/**
* Signalisiert, dass ein erweitertes Plugin bald gelöscht wird.
*
* @event Plugin #dispose
* @type {EventTarget~Ereignis}
* /
this.trigger('dispose');
this.off ();
player.off ('entsorgen', diese.entsorgen);
//Beseitigen Sie alle möglichen Quellen für Speicherverlust, indem Sie aufräumen
//Verweise zwischen dem Player und der Plugin-Instanz und Nullstellen
//der Status des Plugins und das Ersetzen von Methoden durch eine Funktion, die auslöst.
Spieler [PLUGIN_CACHE_KEY] [Name] = falsch;
this.player = this.state = null;
//Ersetze abschließend den Plugin-Namen auf dem Player durch eine neue Factory
//Funktion, sodass das Plugin bereit ist, erneut eingerichtet zu werden.
spieler [name] = createPluginFactory (Name, PluginStorage [Name]);
}
/**
* Stellt fest, ob ein Plugin ein Basis-Plugin ist (also keine Unterklasse von `Plugin`).
*
* @param {string|Function} -Plugin
* Wenn eine Zeichenfolge, entspricht dies dem Namen eines Plugins. Wenn eine Funktion, wird
* direkt getestet.
*
* @return {boolean}
* Ob ein Plugin ein Basis-Plugin ist oder nicht.
* /
static isBasic (Plugin) {
const p = (Plugin-Art === 'Zeichenfolge')? getPlugin (Erweiterung): Erweiterung;
return typeof p === 'function' &&! plugin.prototype.isPrototypeOf (p.prototype);
}
/**
* Registrieren Sie ein Video.js Plugin.
*
* @param {string} name
* Der Name des Plugins, das registriert werden soll. Muss eine Zeichenfolge sein und
* darf keinem existierenden Plugin oder einer Methode auf dem `Player` entsprechen
* Prototyp.
*
* @param {Funktion} plugin
* Eine Unterklasse von `Plugin` oder eine Funktion für einfache Plugins.
*
* @return {Funktion}
* Für erweiterte Plugins eine Factory-Funktion für dieses Plugin. Für
* Basis-Plugins, eine Wrapper-Funktion, die das Plugin initialisiert.
* /
statisches RegisterPlugin (Name, Plugin) {
if (Art des Namens! == 'Zeichenfolge') {
einen neuen Fehler auslösen (`Ungültiger Plugin-Name, „$ {name}“, muss eine Zeichenfolge sein, war $ {typeof name} .`);
}
if (pluginExists(name)) {
log.warn (`Ein Plugin mit dem Namen „$ {name}“ existiert bereits. Möglicherweise möchten Sie die erneute Registrierung von Plugins vermeiden! `);
} sonst wenn (player.prototype.hasOwnProperty (name)) {
einen neuen Fehler auslösen (`Ungültiger Plugin-Name, „$ {name}“, kann keinen Namen mit einer vorhandenen Player-Methode teilen! `);
}
if (Plugin-Art! == 'Funktion') {
einen neuen Fehler auslösen (`Ungültiges Plugin für „$ {name}“, muss eine Funktion sein, war $ {typeof plugin} .`);
}
pluginStorage [Name] = Plugin;
//Füge eine Player-Prototyp-Methode für alle Plugins der Unterklasse hinzu (aber nicht für
//die Basis-Plugin-Klasse).
wenn (Name! == NAME DES BASIS-PLUGINS) {
wenn (plugin.isBasic (Plugin)) {
player.prototype [name] = createBasicPlugin (Name, Plugin);
} sonst {
player.prototype [name] = createPluginFactory (Name, Plugin);
}
}
Plugin zurückgeben;
}
/**
* Deregistrieren Sie ein Video.js Plugin.
*
* @param {string} name
* Der Name des Plugins, das deregistriert werden soll. Muss eine Zeichenfolge sein, die
* entspricht einem vorhandenen Plugin.
*
* @throws {Fehler}
* Wenn versucht wird, das Basis-Plugin zu deregistrieren.
* /
statisches DeregisterPlugin (Name) {
wenn (name === BASE_PLUGIN_NAME) {
einen neuen Fehler auslösen ('Das Basis-Plugin kann nicht deregistriert werden. ');
}
if (pluginExists(name)) {
lösche PluginStorage [Name];
lösche Player.prototype [Name];
}
}
/**
* Ruft ein Objekt ab, das mehrere Video.js Plugins enthält.
*
* @param {Array} [Namen]
* Falls angegeben, sollte es sich um ein Array von Plugin-Namen handeln. Die Standardeinstellung ist _all_
* Plugin-Namen.
*
* @return {Object|undefined}
* Ein Objekt, das Plugins enthält, die mit ihren Namen verknüpft sind, oder
* `undefined` falls keine passenden Plugins existieren).
* /
statische getPlugins (names = Object.keys (pluginStorage)) {
lass das Ergebnis;
names.forEach (name => {
const plugin = getPlugin(name);
wenn (Plugin) {
Ergebnis = Ergebnis || {};
Ergebnis [Name] = Plugin;
}
});
ergebnis zurückgeben;
}
/**
* Ruft die Version eines Plugins ab, falls verfügbar
*
* @param {string} name
* Der Name eines Plugins.
*
* @return {string}
* Die Version des Plugins oder eine leere Zeichenfolge.
* /
statische getPluginVersion (Name) {
const plugin = getPlugin(name);
gib das Plugin zurück & plugin.Version || „;
}
}
/**
* Ruft ein Plugin anhand seines Namens ab, falls es existiert.
*
* @static
* @method GetPlugin
* @memberOf -Plugin
* @param {string} name
* Der Name eines Plugins.
*
* @returns {Funktion|undefiniert}
* Das Plugin (oder `undefiniert`).
* /
plugin.getPlugin = GetPlugin;
/**
* Der Name der Basis-Plugin-Klasse, so wie sie registriert ist.
*
* @Typ {String}
* /
plugin.base_plugin_name = BASIS-PLUGINNAME;
plugin.registerPlugin (BASE_PLUGINNAME, Erweiterung);
/**
* Dokumentiert in player.js
*
* @ignore
* /
player.prototype.UsingPlugin = Funktion (Name) {
kehre zurück!! dieser [PLUGIN_CACHE_KEY] && dieser [PLUGIN_CACHE_KEY] [Name] === wahr;
};
/**
* Dokumentiert in player.js
*
* @ignore
* /
player.prototype.hasPlugin = Funktion (Name) {
kehre zurück!! PluginExists (Name);
};
Standard-Plugin exportieren;
/**
* Signalisiert, dass ein Plugin auf einem Player eingerichtet werden soll.
*
* @event Spieler #beforepluginsetup
* @Typ {Plugin~PluginEventHash}
* /
/**
* Signalisiert, dass ein Plugin auf einem Player eingerichtet werden soll — namentlich. Der Name
* ist der Name des Plugins.
*
* @event Spieler #beforepluginsetup: $name
* @Typ {Plugin~PluginEventHash}
* /
/**
* Signalisiert, dass gerade ein Plugin auf einem Player eingerichtet wurde.
*
* @event Spieler #pluginsetup
* @Typ {Plugin~PluginEventHash}
* /
/**
* Signalisiert, dass gerade ein Plugin auf einem Player eingerichtet wurde — namentlich. Der Name
* ist der Name des Plugins.
*
* @event Spieler #pluginsetup: $name
* @Typ {Plugin~PluginEventHash}
* /
/**
* @typedef {Object} plugin~pluginEventHash
*
* @property {string} -Instanz
* Für einfache Plugins der Rückgabewert der Plugin-Funktion. Für
* erweiterte Plugins, die Plugin-Instanz, auf der das Ereignis ausgelöst wird.
*
* @property {string} name
* Der Name des Plugins.
*
* @property {string} -Plugin
* Für einfache Plugins die Plugin-Funktion. Für fortgeschrittene Plugins ist das
* Plugin-Klasse/Konstruktor.
* /