/**
* @file mixins/stateful.js
* @module stateful
*/
import {isEvented} de './evented' ;
import * as Obj from '../utils/obj' ;
/**
* Contient des méthodes qui fournissent un état à un objet qui lui est transmis
* à {@link module:stateful}.
*
* @mixin StatefulMixin
*/
const StatefulMixin = {
/**
* Un hachage contenant des clés et des valeurs arbitraires représentant l'état de
* l'objet.
*
* @type {Objet}
*/
état : {},
/**
* Définir l'état d'un objet en modifiant son
* l'objet {@link module:stateful~StatefulMixin.state|state} est en place.
*
* @fires module:stateful~StatefulMixin#statechanged
* @param {Objet|Fonction} stateUpdates
* Un nouvel ensemble de propriétés à fusionner superficiellement dans l'état du plugin.
* Il peut s'agir d'un objet ordinaire ou d'une fonction renvoyant un objet ordinaire.
*
* @return {Objet|non défini}
* Un objet contenant les changements survenus. S'il n'y a pas de changement
* s'est produite, renvoie `undefined`.
*/
setState(stateUpdates) {
// Prise en charge de la fourniture de l'état `stateUpdates` en tant que fonction.
if (typeof stateUpdates === 'function') {
stateUpdates = stateUpdates() ;
}
laisser changer ;
Obj.each(stateUpdates, (value, key) => {
// Enregistrer le changement si la valeur est différente de celle contenue dans le fichier
// état actuel.
if (this.state[key] !== value) {
changes = changes || {} ;
changes[key] = {
de : this.state[key],
à : valeur
};
}
this.state[key] = value ;
}) ;
// Ne déclenche "statechange" que si des changements ont eu lieu ET que nous avons un déclencheur
// fonction. Cela nous permet de ne pas exiger que l'objet cible soit un
// objet événementiel.
if (changes && isEvented(this)) {
/**
* Un événement déclenché sur un objet qui est à la fois
* {@link module:stateful|stateful} et {@link module:evented|evented}
* indiquant que son état a changé.
*
* @event module:stateful~StatefulMixin#statechanged
* @type {Objet}
* @property {Objet} changes
* Un hachage contenant les propriétés qui ont été modifiées et
* les valeurs modifiées "de" et "en".
*/
this.trigger({
changements,
type : "statechanged" (changement d'état)
}) ;
}
les changements de retour ;
}
};
/**
* Applique {@link module:stateful~StatefulMixin|StatefulMixin} à une cible
* objet.
*
* Si l'objet cible est {@link module:evented|evented} et possède un élément
* cette méthode sera automatiquement liée à la méthode `handleStateChanged`
* l'événement `statechanged` sur lui-même.
*
* @param {Objet} target
* L'objet qui doit être transformé en état.
*
* @param {Object} [defaultState]
* Un ensemble de propriétés par défaut pour remplir les champs de l'objet nouvellement déclaré
* propriété `state`.
*
* @return {Object}
* Retourne la `cible`.
*/
function stateful(target, defaultState) {
Obj.assign(target, StatefulMixin) ;
// Cela se produit après le mixage car nous devons remplacer l'état (`state`)
// ajouté à cette étape.
target.state = Obj.assign({}, target.state, defaultState) ;
// Lier automatiquement la méthode `handleStateChanged` de l'objet cible si elle existe.
if (typeof target.handleStateChanged === 'function' && isEvented(target)) {
target.on('statechanged', target.handleStateChanged) ;
}
retourner la cible ;
}
export default stateful ;