/**
* @namespace MainObjects
* @property {MelEventManager} MelEventManager
* @property {MelObject} MelObject
*/
export { MelObject };
import { BnumPromise } from './BnumPromise.js';
import { BaseStorage } from './classes/base_storage.js';
import { Cookie } from './classes/cookies.js';
import { FramesManager } from './classes/frame_manager.js';
import { EMPTY_STRING } from './constants/constants.js';
import { isNullOrUndefined } from './mel.js';
import { Top } from './top.js';
/**
* La classe MelEventManager étend BaseStorage et permet d'ajouter, d'appeler et de supprimer des rappels pour des clés d'écoute spécifiques.
* @class
* @classdesc Système d'évènement. Les évènements sont toujours au context le plus haut.
* @extends BaseStorage
* @package
* @frommodule BaseStorage {@membertype .}
*/
class MelEventManager extends BaseStorage {
constructor() {
super();
const super_add = this.add;
/**
* La fonction ajoute un rappel à un écouteur dans un objet MelEvent.
* @param {string} listener_key - Il s'agit d'une clé qui identifie un auditeur spécifique. Il est utilisé pour
* récupérer l'objet MelEvent associé à l'écouteur.
* @param {function} callback - La fonction qui sera exécutée lorsque l'événement est déclenché.
* @param {?string} callback_key - Le paramètre callback_key est un paramètre facultatif qui représente un
* identifiant unique pour la fonction de rappel ajoutée à l'objet MelEvent. S'il n'est pas fourni, la
* fonction générera une clé unique pour le rappel.
* @returns {MelEventManager} l'objet courant (`this`) après avoir ajouté le rappel à l'objet MelEvent associé à la clé
* d'écouteur donnée.
* @override
*/
this.add = (listener_key, callback, callback_key = null) => {
if (!this.has(listener_key))
super_add.call(this, listener_key, new MelEvent());
if (callback_key) this.get(listener_key).add(callback_key, callback);
else this.get(listener_key).push(callback);
return this;
};
}
/**
* La fonction "call" vérifie si une clé d'écoute existe et l'appelle avec des arguments si c'est le
* cas.
* @param {string} listener_key Le paramètre listener_key est une clé utilisée pour identifier une fonction
* d'écouteur spécifique dans une collection de fonctions d'écouteur. Il est utilisé pour récupérer la
* fonction d'écouteur de la collection et l'appeler avec les arguments fournis.
* @param {...any} args args est un paramètre de repos qui permet à la fonction d'accepter n'importe quel
* nombre d'arguments sous forme de tableau. Dans ce cas, la fonction est conçue pour recevoir
* n'importe quel nombre d'arguments après le paramètre listener_key, qui sera transmis à la fonction
* de rappel lors de son appel.
* @returns {MelEventManager} L'objet `this` est renvoyé.
*/
call(listener_key, ...args) {
if (this.has(listener_key)) {
return this.get(listener_key).call(...args);
}
}
/**
* Cette fonction supprime un rappel d'un écouteur dans un objet JavaScript.
* @param {string} listener_key Clé utilisée pour identifier l'écouteur dans l'objet Map.
* @param {string} callback_key Le paramètre `callback_key` est un identifiant unique pour une fonction de
* rappel spécifique qui a été ajoutée à un écouteur. Il est utilisé pour supprimer la fonction de
* rappel correspondante de la liste des rappels de l'écouteur.
* @returns {MelEventManager} La méthode `remove_callback` renvoie l'instance de l'objet sur lequel elle a été appelée
* (`this`).
*/
remove_callback(listener_key, callback_key) {
if (this.has(listener_key) && this.get(listener_key).has(callback_key)) {
this.get(listener_key).remove(callback_key);
}
return this;
}
}
/**
* @abstract
* Classe de base du framework bnum.
*
* Donne divers fonction d'aide pour programmer.
* @class
* @classdesc Donne divers fonction d'aide pour programmer.
*/
class MelObject {
/**
* Constructeur de la classe
* @param {...any} args Arguments de la classe
*/
constructor(...args) {
/**
* @type {MelEventManager}
* @package
*/
this._listener = null;
let _rc_data = null;
/**
* @type {{task:string}}
* @package
*/
this.rc_data = { task: '' };
Object.defineProperties(this, {
_listener: {
get: function () {
const KEY = 'MEL_OBJECT_LISTENER';
if (!Top.has(KEY)) Top.add(KEY, new MelEventManager());
return Top.get(KEY);
},
configurable: true,
},
rc_data: {
get() {
if (!_rc_data) {
_rc_data = {};
Object.defineProperties(_rc_data, {
task: {
get() {
return rcmail.env.current_task;
},
configurable: false,
},
});
}
return _rc_data;
},
},
});
this.main(...args);
}
/**
* @abstract
* Cette fonction est appelé dans le constructeur de MelObject.
*
* Mettez vôtre code ici.
* @param {...any} args Arguments de la fonction
*/
main(...args) {}
/**
* Récupère "rcmail" | les fonctions utiles à roundcube
* @param {boolean} top Si on doit récupérer rcmail sur frame principale ou non
* @returns {rcube_webmail}
* @protected
*/
rcmail(top = false) {
return top && !!Top.top()?.rcmail ? Top.top().rcmail : window.rcmail;
}
open_compose_step({ to = undefined, subject = undefined } = {}) {
let config = {};
if (to) config.to = to;
if (subject) config.subject = subject;
this.rcmail().open_compose_step(config);
}
/**
* Récupère une clé sous forme de texte.
* @param {string} key_text Clé
* @param {!string} plugin Plugin d'où provient le texte traduit
* @returns {string}
* @protected
*/
gettext(key_text, plugin = '') {
return this.rcmail().gettext(key_text, plugin);
}
/**
* Ajoute un écouteur qui pourra être appelé plus tard.
* @param {string} key Clé qui permettra d'appeller l'écouteur
* @param {function} callback Fonction qui sera appelée
* @param {Object} param2 Si on doit récupérer rcmail sur frame principale ou non
* @param {?string} param2.callback_key Clé du callback
* @param {!boolean} param2.condition Si on doit éxécuter ou non le listener
* @protected
*/
add_event_listener(key, callback, { callback_key = null, condition = true }) {
let can_call = typeof condition === 'function' ? condition() : condition;
if (can_call) this._listener.add(key, callback, callback_key);
}
/**
* Trigger un écouteur
* @param {string} key Clé qui appelera tout les écouteurs lié à cette clé
* @param {any} args Arguments qui sera donnée aux écouteurs
* @returns {MelEventManager}
* @protected
*/
trigger_event(key, args) {
return this._listener.call(key, args);
}
/**
* Action à faire lorsqu'une frame est chargée
* @param {function} callback Function à éffectuer
* @param {Object} options Options de la fonction
* @param {?string} options.frame any pour toute n'importe quelle frame, sinon mettre le nom de la frame
* @param {?function} options.condition Condition custom pour charger la frame
* @protected
*/
on_frame_loaded(
callback,
{ callback_key = null, frame = 'any', condition = null },
) {
const KEY = 'frame_loaded';
const SYSTEM_KEY = `[system]${KEY}`;
if (!this._listener.has(SYSTEM_KEY)) {
this.rcmail().addEventListener(KEY, (args) => {
this.trigger_event(KEY, args);
});
this._listener.add(SYSTEM_KEY, true, SYSTEM_KEY);
}
this.add_event_listener(KEY, callback, {
callback_key,
condition: () => {
return (
condition?.() ?? (frame === 'any' || this.rcmail().env.task === frame)
);
},
});
}
/**
* Ajoute une action à faire lors du refresh du bnum
* @param {Function} callback Fonction à appeller
* @param {Object} options Options de la fonction
* @param {?string} options.callback_key clé qui permet de supprimer/remettre la fonction au refresh d'une frame
* @protected
*/
on_refresh(callback, { callback_key = null }) {
this.add_event_listener('mel_metapage_refresh', callback, {
callback_key,
});
}
/**
* Ajoute une action à faire lorsqu'une frame est mise à jours
* @param {function} callback Callback a=à appelé au refresh
* @param {string} frame Nom de la frame
* @param {Object} param2
* @param {?string} options.callback_key clé qui permet de supprimer/remettre la fonction au refresh d'une frame
* @protected
*/
on_frame_refresh(callback, frame, { callback_key = null }) {
this.add_event_listener(
'on_frame_refresh',
(args) => {
const { rc } = args;
if (frame === rc.env.task) {
callback();
}
},
{
callback_key,
},
);
}
/**
* Récupère une variable d'environnement de roundcube
* @param {string} key Nom de la variable
* @returns {?any}
* @protected
*/
get_env(key) {
return rcmail.env[key] ?? top?.rcmail?.env?.[key];
}
/**
* Change de page
* @param {string} frame Nom de la page
* @param {Object} param1
* @param {?string} param1.action Action de la page
* @param {Object<string, string>} param1.params Paramètres additionnels de la page
* @param {!boolean} param1.update {@deprecated}
* @param {!boolean} param1.force_update {@deprecated}
* @async
* @protected
* @return {Promise<void>}
* @deprecated Utilisez plutôt {@link switch_frame}
*/
async change_frame(
frame,
{ action = null, params = {}, update = true, force_update = false },
) {
if (action && (update || force_update)) params['_action'] = action;
await this.switch_frame(frame, {
changepage: true,
args: params,
});
}
/**
* Change de frame
* @param {string} task Nom de la tâche
* @param {Object} options
* @param {boolean} [options.changepage=true] Si l'on change de page ou si la frame reste caché pendant le chargement.
* @param {?Object<string, *>} [options.args=null] Options du changement de frame. Si la frame est déjà ouverte, force le changement d'url.
* @async
* @returns {Promise}
*/
async switch_frame(task, { changepage = true, args = null } = {}) {
await FramesManager.Instance.switch_frame(task, {
changepage,
args,
});
}
/**
* Vérifie si une frame est déjà chargée ou non
* @param {string} frame Nom de la frame
* @returns {boolean}
* @protected
*/
have_frame(frame) {
return FramesManager.Instance.get_window().has_frame(frame);
}
/**
* Selectionne une frame
* @param {string} frame Nom de la frame
* @returns {external:jQuery}
* @protected
*/
select_frame(frame) {
const $ = (top ?? window).$;
return $(`.${frame}-frame`);
}
/**
* Selectionne toutes les frames qui ne sont pas parmis les frames définie en arguments
* @param {...string} frames Frames à écarter
* @generator
* @yield {Node}
* @return {Generator<Node>}
* @protected
*/
*select_frame_except(...frames) {
const $ = (top ?? parent ?? window).$;
for (const frame of $('iframe.mm-frame')) {
if (!frames.find((x) => frame.classList.contains(`${x}-frame`)))
yield frame;
}
}
/**
* Récupère une url à partir d'une tâche et d'une action
* @param {string} task Nom de la tâche
* @param {Object} param1 action => Nom de l'action ('index' si non renseigné), params => Autres paramètres
* @param {!string} param1.action => Nom de l'action (index si non renseigné)
* @param {?Object<string, string>} Autres paramètres
* @returns {string}
* @protected
*/
url(
task,
{ action = EMPTY_STRING, params = null, removeIsFromIframe = false },
) {
const IFRAME = Object.freeze({ KEY: '_is_from', VALUE: 'iframe' });
let url = task;
if (!!action && action !== EMPTY_STRING) url += `&_action=${action}`;
if (
!removeIsFromIframe &&
(window !== parent ||
window.location.href.includes(`${IFRAME.KEY}=${IFRAME.VALUE}`))
) {
if (!params || !Object.keys(params).length) params = {};
params[IFRAME.KEY] = IFRAME.VALUE;
}
if (!!params && Object.keys(params).length) {
for (const key of Object.keys(params)) {
url += `&${key}=${params[key]}`;
}
}
// if (removeIsFromIframe && url.includes('&_is_from=iframe'))
// url = url.replace('&_is_from=iframe', EMPTY_STRING);
return this.rcmail().get_task_url(
url,
window.location.origin + window.location.pathname,
);
}
/**
* Effectue un appel ajax avec les options spécifiées.
* @param {Object} options - Les options pour l'appel HTTP.
* @param {string} options.url - L'URL à appeler.
* @param {(data:T) => Y} [options.on_success=() => {}] - La fonction à appeler en cas de succès.
* @param {(...args:any[]) => any[]} [options.on_error=(...args) => {console.error('###[http_call]', ...args)}] - La fonction à appeler en cas d'erreur.
* @param {Object} [options.params=null] - Les paramètres à envoyer dans la requête.
* @param {string | BnumPromise.Ajax.EAjaxMethod} [options.type=BnumPromise.Ajax.EAjaxMethod.post] - Le type de requête HTTP à effectuer.
* @returns {BnumPromise<Y>}
* @frommodulereturn BnumPromise
* @protected
* @template T
* @template Y
*/
http_call({
url,
on_success = () => {},
on_error = (...args) => {
console.error('###[http_call]', ...args);
},
params = null,
type = BnumPromise.Ajax.EAjaxMethod.post,
}) {
return BnumPromise.Ajax.Call(url, {
type,
success: on_success,
failed: on_error,
data: params,
});
}
/**
* Effectue un appel ajax vers les serveurs de l'application
* @param {Object} options - Les options pour l'appel HTTP.
* @param {string} options.task - Tache
* @param {string} options.action - Action
* @param {(data:T) => Y} [options.on_success=() => {}] - La fonction à appeler en cas de succès.
* @param {(...args:any[]) => any[]} [options.on_error=(...args) => {console.error('###[http_call]', ...args)}] - La fonction à appeler en cas d'erreur.
* @param {Object} [options.params=null] - Les paramètres à envoyer dans la requête.
* @param {string | BnumPromise.Ajax.EAjaxMethod} [options.type=BnumPromise.Ajax.EAjaxMethod.post] - Le type de requête HTTP à effectuer.
* @returns {BnumPromise<Y>}
* @protected
* @frommodulereturn BnumPromise
* @template T
* @template Y
*/
http_internal_call({
task,
action,
on_success = () => {},
on_error = (...args) => {
console.error('###[http_internal_call]', ...args);
},
params = null,
type = BnumPromise.Ajax.EAjaxMethod.post,
}) {
const isGet = ['GET', BnumPromise.Ajax.EAjaxMethod.get].includes(type);
return this.http_call({
type,
on_error,
on_success,
params: isGet ? null : params,
url: this.url(task, {
action: action,
params: isGet ? params : null,
}),
});
}
/**
* Effectue un appel ajax POST vers les serveurs de l'application
* @param {Object} options - Les options pour l'appel HTTP.
* @param {string} options.task - Tache
* @param {string} options.action - Action
* @param {(data:T) => Y} [options.on_success=() => {}] - La fonction à appeler en cas de succès.
* @param {(...args:any[]) => any[]} [options.on_error=(...args) => {console.error('###[http_call]', ...args)}] - La fonction à appeler en cas d'erreur.
* @param {Object} [options.params=null] - Les paramètres à envoyer dans la requête.
* @returns {BnumPromise<Y>}
* @protected
* @frommodulereturn BnumPromise
* @template T
* @template Y
*/
http_internal_post({
task,
action,
on_success = () => {},
on_error = (...args) => {
console.error('###[http_internal_post]', ...args);
},
params = null,
}) {
return this.http_internal_call({
task,
action,
on_success,
on_error,
params,
type: 'POST',
});
}
/**
* Effectue un appel ajax GET vers les serveurs de l'application
* @param {Object} options - Les options pour l'appel HTTP.
* @param {string} options.task - Tache
* @param {string} options.action - Action
* @param {(data:T) => Y} [options.on_success=() => {}] - La fonction à appeler en cas de succès.
* @param {(...args:any[]) => any[]} [options.on_error=(...args) => {console.error('###[http_call]', ...args)}] - La fonction à appeler en cas d'erreur.
* @param {Object} [options.params=null] - Les paramètres à envoyer dans la requête.
* @returns {BnumPromise<Y>}
* @protected
* @frommodulereturn BnumPromise
* @template T
* @template Y
*/
http_internal_get({
task,
action,
on_success = () => {},
on_error = (...args) => {
console.error('###[http_internal_post]', ...args);
},
params = null,
}) {
return this.http_internal_call({
task,
action,
on_success,
on_error,
params,
type: 'GET',
});
}
/**
* Sauvegarde des données dans le stockage local
* @param {string} key Clé qui permettra de retrouver les données sauvegarder
* @param {*} contents Données qui seront sauvegarder
* @returns {MelObject} Chaînage
* @protected
*/
save(key, contents) {
mel_metapage.Storage.set(key, JSON.stringify(contents));
return this;
}
/**
* Charge des données dans le stockage local
* @param {string} key Clé qui permet de retrouver les données
* @param {?any} default_value Valeur par défaut si la donnée n'éxiste pas
* @returns {?any}
* @protected
*/
load(key, default_value = null) {
try {
return JSON.parse(mel_metapage.Storage.get(key)) ?? default_value;
} catch (error) {
return default_value;
}
}
load_without_parsing(key, default_value = null) {
return mel_metapage.Storage.get(key) ?? default_value;
}
/**
* Décharge une donnée dans le stockage local
* @param {string} key clé dans le stockage
* @protected
*/
unload(key) {
mel_metapage.Storage.remove(key);
}
/**
* Récupère l'objet UI de la skin elastic
* @returns {Mel_Elastic}
* @protected
*/
get_skin() {
return window.MEL_ELASTIC_UI;
}
/**
* Récupère un objet Mel_CSS_Style_Sheet pour ajouter du css custom
* @returns {Mel_CSS_Style_Sheet}
* @protected
*/
get_custom_rules() {
return this.get_skin().css_rules;
}
/**
* Génère un loader du bnum
* @param {string} id id du loader
* @param {!boolean} absoluteCentered Centrer verticalement et horizontalement ?
* @returns {mel_html}
* @protected
*/
generate_loader(id, absoluteCentered = true) {
return this.get_skin().create_loader(id, absoluteCentered, false);
}
/**
* Séléctionne un document dom au format jquery
* @param {string} selector Selecteur au format jquery
* @returns {external:jQuery}
* @protected
*/
select(selector) {
return $(selector);
}
/**
* Copie un texte dans le press(papier)
* @param {string} elementToCopy Texte à mettre dans le presse papier
* @param {Object} [options={}]
* @param {?string} [options.text=null] Texte à afficher lorsque la copie a été effectuée
* @protected
*/
copy_to_clipboard(elementToCopy, { text = null } = {}) {
function copyOnClick(val) {
var tempInput = document.createElement('input');
tempInput.value = val;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand('copy');
document.body.removeChild(tempInput);
}
copyOnClick(elementToCopy);
rcmail.display_message(
text || `${elementToCopy} copier dans le presse-papier.`,
'confirmation',
);
return this;
}
/**
* Insert un cookie
* @param {string} key Clé qui permet d'identifier la données mise en cookie
* @param {string} name Donnée à mettre en cookie
* @param {Date | false} expire Date d'expiration, false pour aucune
* @returns {Cookie} Cookie créer
* @frommodulereturn Cookies {@membertype .}
* @protected
*/
cookie_set(key, name, expire = false) {
return Cookie.set_cookie(key, name, expire);
}
/**
* Récupère un cookie
* @param {string} key Indentifiant de la donnée
* @returns {Cookie}
* @frommodulereturn Cookies {@membertype .}
* @protected
*/
cookie_get(key) {
return Cookie.get_cookie(key);
}
/**
* Supprime un cookie
* @param {string} key Indentifiant du cookie à supprimer
* @returns {Cookie} Cookie supprimer
* @frommodulereturn Cookies {@membertype .}
* @protected
*/
cookie_remove(key) {
return Cookie.remove_cookie(key);
}
/**
* Renvoie vrai si la variable vaut `null` ou `undefined`.
* @param {?any} item Variable à tester
* @returns {boolean}
* @protected
*/
isNullOrUndefined(item) {
return isNullOrUndefined(item);
}
/**
* Envoie une notification BNUM
* @param {*} notification
* @protected
*/
send_notification(notification) {
this.rcmail().triggerEvent('plugin.push_notification', notification);
}
switch_url(url) {
window.location.href = url;
return this;
}
switch_task(task, { action = null, params = {} }) {
return this.switch_url(this.url(task, { action, params }));
}
export(name = null) {
window[name ?? this.get_class_name()] = this;
return this;
}
delete_export(name = null) {
window[name ?? this.get_class_name()] = null;
return this;
}
get_class_name() {
return this.constructor.name;
}
/**
* (async) Créer une promesse "Mel" qui contient des fonctionnalités en plus
* @param {import('./BnumPromise.js').PromiseCallback<T> | import('./BnumPromise.js').PromiseCallbackAsync<T>} callback Peut être asynchrone. Fonction qui sera appelé.
* @param {...any} args Arguments du callback
* @returns {BnumPromise<T>}
* @async
* @template T
* @frommodulereturn BnumPromise
*/
create_promise(callback, ...args) {
return new BnumPromise(callback, ...args);
}
/**
* (async) Attend qu'une condtion soit valide
* @param {import('../../../mel_metapage/js/lib/mel_promise.js').WaitCallback | import('../../../mel_metapage/js/lib/mel_promise.js').WaitCallbackAsync} callback Function qui est appelé à chaque tick. Lorsque "true" est renvoyé, la boucle s'arrête
* @param {Object} [options={}]
* @param {number} [options.timeout=5] Au bout de combien de secondes la boucle s'arrête
* @returns {BnumPromise<{ resolved: boolean; msg: (string | undefined); }>}
* @async
*/
wait_something(callback, { timeout = 5 } = {}) {
return BnumPromise.Wait(callback, { timeout });
}
/**
* (async) Attend x millisecondes
* @param {number} ms Temps en millisecondes
* @returns {BnumPromise<void>}
* @async
*/
sleep(ms) {
return BnumPromise.Sleep(ms);
}
/**
* Envoie un MelObject vide.
* @returns {EmptyMelObject}
* @static
*/
static Empty() {
if (!this.Empty.obj) this.Empty.obj = Object.freeze(new EmptyMelObject());
return this.Empty.obj;
}
/**
* Récupère une url à partir d'une tâche et d'une action
* @param {string} task Nom de la tâche
* @param {Object} [param1={}] action => Nom de l'action ('index' si non renseigné), params => Autres paramètres
* @param {!string} [param1.action=''] => Nom de l'action (index si non renseigné)
* @param {?Object<string, string>} [param1.params=null] Autres paramètres
* @param {boolean} [removeIsFromIframe=false] Si on supprime `is_from=iframe` qui correspond à l'url à l'intérieur des frames
* @returns {string}
* @static
*/
static Url(
task,
{ action = EMPTY_STRING, params = null, removeIsFromIframe = false } = {},
) {
return this.Empty().url(task, { action, params, removeIsFromIframe });
}
}
/**
* @class
* @classdesc Donne divers fonction d'aide pour programmer.
* @extends MelObject
*/
class EmptyMelObject extends MelObject {
/**
* Constructeur de la classe
*/
constructor() {
super();
}
/**
* Récupère "rcmail" | les fonctions utiles à roundcube
* @param {boolean} top Si on doit récupérer rcmail sur frame principale ou non
* @returns {rcube_webmail}
* @public
*/
rcmail(top = false) {
return super.rcmail(top);
}
/**
* Récupère une clé sous forme de texte.
* @param {string} key_text Clé
* @param {!string} plugin Plugin d'où provient le texte traduit
* @returns {string}
* @public
*/
gettext(key_text, plugin = '') {
return super.gettext(key_text, plugin);
}
/**
* Ajoute un écouteur qui pourra être appelé plus tard.
* @param {string} key Clé qui permettra d'appeller l'écouteur
* @param {function} callback Fonction qui sera appelée
* @param {Object} param2 Si on doit récupérer rcmail sur frame principale ou non
* @param {?string} param2.callback_key Clé du callback
* @param {!boolean} param2.condition Si on doit éxécuter ou non le listener
* @public
*/
add_event_listener(
key,
callback,
{ callback_key = null, condition = true } = {},
) {
return super.add_event_listener(key, callback, { callback_key, condition });
}
/**
* Trigger un écouteur
* @param {string} key Clé qui appelera tout les écouteurs lié à cette clé
* @param {any} args Arguments qui sera donnée aux écouteurs
* @returns {MelEventManager}
* @public
*/
trigger_event(key, args) {
return super.trigger_event(key, args);
}
/**
* Action à faire lorsqu'une frame est chargée
* @param {function} callback Function à éffectuer
* @param {Object} options Options de la fonction
* @param {?string} options.frame any pour toute n'importe quelle frame, sinon mettre le nom de la frame
* @param {?function} options.condition Condition custom pour charger la frame
* @public
*/
on_frame_loaded(
callback,
{ callback_key = null, frame = 'any', condition = null } = {},
) {
return super.on_frame_loaded(callback, { callback_key, frame, condition });
}
/**
* Ajoute une action à faire lors du refresh du bnum
* @param {Function} callback Fonction à appeller
* @param {Object} options Options de la fonction
* @param {?string} options.callback_key clé qui permet de supprimer/remettre la fonction au refresh d'une frame
* @public
*/
on_refresh(callback, { callback_key = null } = {}) {
return super.on_refresh(callback, { callback_key });
}
/**
* Ajoute une action à faire lorsqu'une frame est mise à jours
* @param {function} callback Callback a=à appelé au refresh
* @param {string} frame Nom de la frame
* @param {Object} param2
* @param {?string} options.callback_key clé qui permet de supprimer/remettre la fonction au refresh d'une frame
* @public
*/
on_frame_refresh(callback, frame, { callback_key = null } = {}) {
super.on_frame_refresh(callback, frame, { callback_key });
}
/**
* Récupère une variable d'environnement de roundcube
* @param {string} key Nom de la variable
* @returns {?any}
* @public
*/
get_env(key) {
return super.get_env(key);
}
/**
* Change de page
* @param {string} frame Nom de la page
* @param {Object} param1
* @param {?string} param1.action Action de la page
* @param {Object<string, string>} param1.params Paramètres additionnels de la page
* @param {!boolean} param1.update {@deprecated}
* @param {!boolean} param1.force_update {@deprecated}
* @async
* @public
* @return {Promise<void>}
* @deprecated Utilisez plutôt {@link switch_frame}
*/
async change_frame(
frame,
{ action = null, params = {}, update = true, force_update = false } = {},
) {
return await super.change_frame(frame, {
action,
params,
update,
force_update,
});
}
/**
* Change de frame
* @param {string} task Nom de la tâche
* @param {Object} options
* @param {boolean} [options.changepage=true] Si l'on change de page ou si la frame reste caché pendant le chargement.
* @param {?Object<string, *>} [options.args=null] Options du changement de frame. Si la frame est déjà ouverte, force le changement d'url.
* @async
* @returns {Promise}
*/
async switch_frame(task, { changepage = true, args = null } = {}) {
await super.switch_frame(task, { changepage, args });
}
/**
* Vérifie si une frame est déjà chargée ou non
* @param {string} frame Nom de la frame
* @returns {boolean}
* @public
*/
have_frame(frame) {
return super.have_frame(frame);
}
/**
* Selectionne une frame
* @param {string} frame Nom de la frame
* @returns {external:jQuery}
* @public
*/
select_frame(frame) {
return super.select_frame(frame);
}
/**
* Selectionne toutes les frames qui ne sont pas parmis les frames définie en arguments
* @param {...string} frames Frames à écarter
* @generator
* @yield {Node}
* @return {Generator<Node>}
* @public
*/
*select_frame_except(...frames) {
yield* super.select_frame_except(...frames);
}
/**
* Récupère une url à partir d'une tâche et d'une action
* @param {string} task Nom de la tâche
* @param {Object} param1 action => Nom de l'action ('index' si non renseigné), params => Autres paramètres
* @param {!string} param1.action => Nom de l'action (index si non renseigné)
* @param {?Object<string, string>} Autres paramètres
* @returns {string}
* @public
*/
url(
task,
{ action = EMPTY_STRING, params = null, removeIsFromIframe = false } = {},
) {
return super.url(task, { action, params, removeIsFromIframe });
}
/**
* Effectue un appel ajax avec les options spécifiées.
* @param {Object} options - Les options pour l'appel HTTP.
* @param {string} options.url - L'URL à appeler.
* @param {function} [options.on_success=() => {}] - La fonction à appeler en cas de succès.
* @param {function} [options.on_error=(...args) => {console.error('###[http_call]', ...args)}] - La fonction à appeler en cas d'erreur.
* @param {Object} [options.params=null] - Les paramètres à envoyer dans la requête.
* @param {string} [options.type='POST'] - Le type de requête HTTP à effectuer.
* @returns {Mel_Ajax}
* @public
*/
http_call({
url,
on_success = () => {},
on_error = (...args) => {
console.error('###[http_call]', ...args);
},
params = null,
type = 'POST',
}) {
return super.http_call({ url, on_success, on_error, params, type });
}
/**
* Effectue un appel ajax vers les serveurs de l'application
* @param {Object} options - Les options pour l'appel HTTP.
* @param {string} options.task - Tache
* @param {string} options.action - Action
* @param {function} [options.on_success=() => {}] - La fonction à appeler en cas de succès.
* @param {function} [options.on_error=(...args) => {console.error('###[http_call]', ...args)}] - La fonction à appeler en cas d'erreur.
* @param {Object} [options.params=null] - Les paramètres à envoyer dans la requête.
* @param {string} [options.type='POST'] - Le type de requête HTTP à effectuer.
* @returns {Mel_Ajax}
* @public
*/
http_internal_call({
task,
action,
on_success = () => {},
on_error = (...args) => {
console.error('###[http_internal_call]', ...args);
},
params = null,
type = 'POST',
}) {
return super.http_internal_call({
task,
action,
on_success,
on_error,
params,
type,
});
}
/**
* Effectue un appel ajax POST vers les serveurs de l'application
* @param {Object} options - Les options pour l'appel HTTP.
* @param {string} options.task - Tache
* @param {string} options.action - Action
* @param {function} [options.on_success=() => {}] - La fonction à appeler en cas de succès.
* @param {function} [options.on_error=(...args) => {console.error('###[http_call]', ...args)}] - La fonction à appeler en cas d'erreur.
* @param {Object} [options.params=null] - Les paramètres à envoyer dans la requête.
* @returns {Mel_Ajax}
* @public
*/
http_internal_post({
task,
action,
on_success = () => {},
on_error = (...args) => {
console.error('###[http_internal_post]', ...args);
},
params = null,
}) {
return super.http_internal_post({
task,
action,
on_success,
on_error,
params,
});
}
/**
* Effectue un appel ajax GET vers les serveurs de l'application
* @param {Object} options - Les options pour l'appel HTTP.
* @param {string} options.task - Tache
* @param {string} options.action - Action
* @param {function} [options.on_success=() => {}] - La fonction à appeler en cas de succès.
* @param {function} [options.on_error=(...args) => {console.error('###[http_call]', ...args)}] - La fonction à appeler en cas d'erreur.
* @param {Object} [options.params=null] - Les paramètres à envoyer dans la requête.
* @returns {Mel_Ajax}
* @public
*/
http_internal_get({
task,
action,
on_success = () => {},
on_error = (...args) => {
console.error('###[http_internal_post]', ...args);
},
params = null,
}) {
return super.http_internal_get({
task,
action,
on_success,
on_error,
params,
});
}
/**
* Sauvegarde des données dans le stockage local
* @param {string} key Clé qui permettra de retrouver les données sauvegarder
* @param {*} contents Données qui seront sauvegarder
* @returns {MelObject} Chaînage
* @public
*/
save(key, contents) {
return super.save(key, contents);
}
/**
* Charge des données dans le stockage local
* @param {string} key Clé qui permet de retrouver les données
* @param {?any} default_value Valeur par défaut si la donnée n'éxiste pas
* @returns {?any}
* @public
*/
load(key, default_value = null) {
return super.load(key, default_value);
}
load_without_parsing(key, default_value = null) {
return super.load_without_parsing(key, default_value);
}
/**
* Décharge une donnée dans le stockage local
* @param {string} key clé dans le stockage
* @public
*/
unload(key) {
return super.unload(key);
}
/**
* Récupère l'objet UI de la skin elastic
* @returns {Mel_Elastic}
* @public
*/
get_skin() {
return super.get_skin();
}
/**
* Récupère un objet Mel_CSS_Style_Sheet pour ajouter du css custom
* @returns {Mel_CSS_Style_Sheet}
* @public
*/
get_custom_rules() {
return super.get_custom_rules();
}
/**
* Génère un loader du bnum
* @param {string} id id du loader
* @param {!boolean} absoluteCentered Centrer verticalement et horizontalement ?
* @returns {mel_html}
* @public
*/
generate_loader(id, absoluteCentered = true) {
return super.generate_loader(id, absoluteCentered);
}
/**
* Séléctionne un document dom au format jquery
* @param {string} selector Selecteur au format jquery
* @returns {external:jQuery}
* @public
*/
select(selector) {
return super.select(selector);
}
/**
* Copie un texte dans le press(papier)
* @param {string} elementToCopy Texte à mettre dans le presse papier
* @param {Object} [options={}]
* @param {?string} [options.text=null] Texte à afficher lorsque la copie a été effectuée
* @returns {EmptyMelObject} Chaînage
* @public
* @override
*/
copy_to_clipboard(elementToCopy, { text = null } = {}) {
return super.copy_to_clipboard(elementToCopy, { text });
}
/**
* Insert un cookie
* @param {string} key Clé qui permet d'identifier la données mise en cookie
* @param {string} name Donnée à mettre en cookie
* @param {Date | false} expire Date d'expiration, false pour aucune
* @returns {Cookie} Cookie créer
* @frommodulereturn Cookies {@membertype .}
* @public
*/
cookie_set(key, name, expire = false) {
return super.cookie_set(key, name, expire);
}
/**
* Récupère un cookie
* @param {string} key Indentifiant de la donnée
* @returns {Cookie}
* @frommodulereturn Cookies {@membertype .}
* @public
*/
cookie_get(key) {
return super.cookie_get(key);
}
/**
* Supprime un cookie
* @param {string} key Indentifiant du cookie à supprimer
* @returns {Cookie} Cookie supprimer
* @frommodulereturn Cookies {@membertype .}
* @public
*/
cookie_remove(key) {
return super.cookie_remove(key);
}
/**
* Renvoie vrai si la variable vaut `null` ou `undefined`.
* @param {?any} item Variable à tester
* @returns {boolean}
* @public
*/
isNullOrUndefined(item) {
return super.isNullOrUndefined(item);
}
/**
* Envoie une notification BNUM
* @param {*} notification
* @public
*/
send_notification(notification) {
return super.send_notification(notification);
}
switch_url(url) {
return super.switch_url(url);
}
switch_task(task, { action = null, params = {} } = {}) {
return super.switch_task(task, { action, params });
}
export(name = null) {
return super.export(name);
}
delete_export(name = null) {
return super.delete_export(name);
}
get_class_name() {
return this.constructor.name;
}
/**
* (async) Créer une promesse "Mel" qui contient des fonctionnalités en plus
* @param {import('../../../mel_metapage/js/lib/mel_promise.js').MelPromiseCallback} callback Peut être asynchrone. Fonction qui sera appelé.
* @param {...any} args Arguments du callback
* @returns {Mel_Promise}
* @async
*/
create_promise(callback, ...args) {
return super.create_promise(callback, ...args);
}
/**
* (async) Attend qu'une condtion soit valide
* @param {import('../../../mel_metapage/js/lib/mel_promise.js').WaitCallback | import('../../../mel_metapage/js/lib/mel_promise.js').WaitCallbackAsync} callback Function qui est appelé à chaque tick. Lorsque "true" est renvoyé, la boucle s'arrête
* @param {Object} [options={}]
* @param {number} [options.timeout=5] Au bout de combien de secondes la boucle s'arrête
* @returns {WaitSomething | WaitSomethingAsync}
* @async
*/
wait_something(callback, { timeout = 5 } = {}) {
return super.wait_something(callback, { timeout });
}
/**
* (async) Attend x millisecondes
* @param {number} ms Temps en millisecondes
* @returns {Mel_Promise}
* @async
*/
sleep(ms) {
return super.sleep(ms);
}
}