- 1 :
/* eslint-disable no-shadow */
- 2 :
/**
- 3 :
* Met en pause une fonction asynchrone.
- 4 :
* @param {number} ms
- 5 :
*/
- 6 :
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
- 7 :
- 8 :
/**
- 9 :
* Vérifie si une fonction est asynchrone
- 10 :
* @param {Function} myFunction
- 11 :
* @returns {boolean}
- 12 :
*/
- 13 :
const isAsync = (myFunction) => myFunction.constructor.name === 'AsyncFunction';
- 14 :
- 15 :
/**
- 16 :
* Attend que la fonction soit vrai
- 17 :
* @param {Function} func
- 18 :
* @param {number} waitTime ms
- 19 :
*/
- 20 :
const wait = async function (func, waitTime = 500) {
- 21 :
while (isAsync(func) ? await func() : func()) {
- 22 :
await delay(waitTime);
- 23 :
}
- 24 :
};
- 25 :
- 26 :
const ping = async function (url, useSSL = true) {
- 27 :
// //let ip = url;
- 28 :
- 29 :
// var _that = this;
- 30 :
- 31 :
// let img = new Image();
- 32 :
- 33 :
// img.onload = function() {_that.ok = true;};
- 34 :
// img.onerror = function(e) {_that.ok = false; console.error(e);};
- 35 :
- 36 :
// //let start = new Date().getTime();
- 37 :
let ssl = useSSL ? 'https' : 'http';
- 38 :
// img.src = !url.includes("https") && !url.includes("http") ? (ssl + "://" + url) : url;
- 39 :
// console.log(img.src);
- 40 :
// let timer = setTimeout(function() { _that.ok = false;}, waitTime*1000);
- 41 :
// await wait(() => _that.ok === undefined);
- 42 :
// clearTimeout(timer)
- 43 :
// return _that.ok;
- 44 :
let ok;
- 45 :
try {
- 46 :
await $.ajax({
- 47 :
type: 'GET',
- 48 :
url:
- 49 :
!url.includes('https') && !url.includes('http')
- 50 :
? ssl + '://' + url
- 51 :
: url,
- 52 :
success: function (result) {
- 53 :
ok = true;
- 54 :
},
- 55 :
error: function (result) {
- 56 :
ok = false;
- 57 :
},
- 58 :
});
- 59 :
} catch (error) {
- 60 :
console.error(error);
- 61 :
ok = false;
- 62 :
}
- 63 :
return ok;
- 64 :
};
- 65 :
- 66 :
const mceToRcId = function (txt = '') {
- 67 :
return txt
- 68 :
.replaceAll('.', '_-P-_')
- 69 :
.replaceAll('@', "'_-A-_'")
- 70 :
.replaceAll('%', '_-C-_');
- 71 :
};
- 72 :
- 73 :
(() => {
- 74 :
function ureplacer(pmatch) {
- 75 :
var ret = '';
- 76 :
pmatch = pmatch.replace(/\,/g, '/');
- 77 :
var ix = pmatch.substr(1, pmatch.length - 2);
- 78 :
- 79 :
if (ix.length % 4 != 0)
- 80 :
ix = ix.padEnd(ix.length + 4 - (ix.length % 4), '=');
- 81 :
try {
- 82 :
var dx = atob(ix);
- 83 :
for (var j = 0; j < dx.length; j = j + 2) {
- 84 :
ret =
- 85 :
ret +
- 86 :
String.fromCharCode((dx.charCodeAt(j) << 8) + dx.charCodeAt(j + 1));
- 87 :
}
- 88 :
} catch (err) {
- 89 :
console.log(
- 90 :
'Error in decoding foldername IMAP UTF7, sending empty string back',
- 91 :
);
- 92 :
console.log(err);
- 93 :
ret = '';
- 94 :
}
- 95 :
return ret;
- 96 :
}
- 97 :
- 98 :
function breplacer(umatch) {
- 99 :
var bst = '';
- 100 :
for (var i = 0; i < umatch.length; i++) {
- 101 :
var f = umatch.charCodeAt(i);
- 102 :
bst = bst + String.fromCharCode(f >> 8) + String.fromCharCode(f & 255);
- 103 :
}
- 104 :
- 105 :
try {
- 106 :
bst = '&' + btoa(bst).replace(/\//g, ',').replace(/=+/, '') + '-';
- 107 :
} catch (err) {
- 108 :
console.log(
- 109 :
'Error in encoding foldername IMAP UTF7, sending empty string back',
- 110 :
);
- 111 :
console.log(err);
- 112 :
bst = '';
- 113 :
}
- 114 :
return bst;
- 115 :
}
- 116 :
- 117 :
function decode_imap_utf7(mstring) {
- 118 :
var stm = new RegExp(/(\&[A-Za-z0-9\+\,]+\-)/, 'g');
- 119 :
return mstring.replace(stm, ureplacer).replace('&-', '&');
- 120 :
}
- 121 :
- 122 :
function encode_imap_utf7(ustring) {
- 123 :
ustring = ustring.replace(/\/|\~|\\/g, '');
- 124 :
var vgm = new RegExp(/([^\x20-\x7e]+)/, 'g');
- 125 :
return ustring.replace('&', '&-').replace(vgm, breplacer);
- 126 :
}
- 127 :
- 128 :
function setCookie(cname, cvalue, exdays) {
- 129 :
const d = new Date();
- 130 :
d.setTime(d.getTime() + exdays * 24 * 60 * 60 * 1000);
- 131 :
let expires = 'expires=' + d.toUTCString();
- 132 :
document.cookie = cname + '=' + cvalue + ';' + expires + ';path=/';
- 133 :
}
- 134 :
- 135 :
window.decode_imap_utf7 = decode_imap_utf7;
- 136 :
- 137 :
window.melSetCookie = setCookie;
- 138 :
- 139 :
window.getCookie = (name) => {
- 140 :
return rcmail.get_cookie(name);
- 141 :
};
- 142 :
- 143 :
window.removeCookie = (name) => {
- 144 :
setCookie(name, '', -5);
- 145 :
};
- 146 :
})();
- 147 :
/**
- 148 :
* Lien du chargement des évènements d'un calendrier.
- 149 :
*/
- 150 :
const ev_calendar_url = '?_task=calendar&_action=load_events';
- 151 :
- 152 :
/**
- 153 :
* Liste des différents données constantes utile pour le plugin "mel_metapage".
- 154 :
*/
- 155 :
const mel_metapage = {
- 156 :
/**
- 157 :
* Liste des différents évènements.
- 158 :
*/
- 159 :
EventListeners: {
- 160 :
/**
- 161 :
* Lorsque le calendrier est mis à jours.
- 162 :
*/
- 163 :
calendar_updated: new EventListenerDatas('mel_metapage.calendar_updated'),
- 164 :
/**
- 165 :
* Lorsque les tâches sont mises à jours.
- 166 :
*/
- 167 :
tasks_updated: new EventListenerDatas('mel_metapage.tasks_updated'),
- 168 :
/**
- 169 :
* Lorsque les mails sont mis à jours.
- 170 :
*/
- 171 :
mails_updated: new EventListenerDatas('mel_metapage.mails_updated'),
- 172 :
/**
- 173 :
* Lorsque le stockage est mis à jours.
- 174 :
*/
- 175 :
wsp_stockage_updated: new EventListenerDatas(
- 176 :
'mel_metapage.wsp_stockage_updated',
- 177 :
),
- 178 :
workspaces_updated: new EventListenerDatas('workspace.updated'),
- 179 :
},
- 180 :
/**
- 181 :
* Différents clés de stockage local.
- 182 :
*/
- 183 :
Storage: {
- 184 :
unexist: Symbol('unexist'),
- 185 :
exists(val) {
- 186 :
return (val ?? this.unexist) !== this.unexist;
- 187 :
},
- 188 :
/**
- 189 :
*
- 190 :
* @returns {MelDataStore}
- 191 :
*/
- 192 :
_getDataStore() {
- 193 :
let self = (top ?? window).mel_metapage.Storage;
- 194 :
- 195 :
if (!self._getDataStore.datastoreobject) {
- 196 :
const current_user_key = `bnum.${rcmail.env.username}`;
- 197 :
self._getDataStore.datastoreobject = new MelDataStore(
- 198 :
current_user_key,
- 199 :
{},
- 200 :
);
- 201 :
- 202 :
if (rcmail.env.keep_login) {
- 203 :
const keys = Object.keys(localStorage);
- 204 :
- 205 :
for (let index = 0, len = keys.length; index < len; ++index) {
- 206 :
const key = keys[index];
- 207 :
- 208 :
if (key !== current_user_key && key.includes('bnum')) {
- 209 :
localStorage.removeItem(key);
- 210 :
}
- 211 :
}
- 212 :
}
- 213 :
}
- 214 :
- 215 :
return self._getDataStore.datastoreobject;
- 216 :
},
- 217 :
/**
- 218 :
* Récupère une donnée depuis le stockage local.
- 219 :
* @param {string} key Clé de la donnée à récupérer.
- 220 :
*/
- 221 :
get(key, _default = null) {
- 222 :
let self = mel_metapage.Storage;
- 223 :
try {
- 224 :
return self._getDataStore().get(key) ?? _default;
- 225 :
} catch (error) {
- 226 :
console.error(error);
- 227 :
return self.unexist;
- 228 :
}
- 229 :
},
- 230 :
/**
- 231 :
* Ajoute ou modifie une donnée dans le stockage local.
- 232 :
* @param {string} key Clé de la donnée pour la retrouver.
- 233 :
* @param {*} item Donnée à sauvegarder.
- 234 :
*/
- 235 :
set(key, item, stringify = true) {
- 236 :
this._getDataStore().set(key, item);
- 237 :
this.setStoreChange(key, item);
- 238 :
},
- 239 :
/**
- 240 :
* Supprime une donnée dans le stockage local.
- 241 :
* @param {string} key Clé de la donnée à supprimer.
- 242 :
*/
- 243 :
remove(key) {
- 244 :
this._getDataStore().remove(key);
- 245 :
this.setStoreChange(key, undefined);
- 246 :
},
- 247 :
setStoreChange(key, item) {
- 248 :
if ((top ?? window).rcmail !== undefined)
- 249 :
(top ?? window).rcmail.triggerEvent('storage.change', { key, item });
- 250 :
- 251 :
(top ?? window).$('iframe.mm-frame').each((i, e) => {
- 252 :
try {
- 253 :
e.contentWindow.rcmail.triggerEvent('storage.change', { key, item });
- 254 :
} catch (error) {}
- 255 :
});
- 256 :
},
- 257 :
getAppStorageSize() {
- 258 :
return this._getDataStore().getSize();
- 259 :
},
- 260 :
check(storage = null) {
- 261 :
if (storage === null) {
- 262 :
let items = [];
- 263 :
for (const key in mel_metapage.Storage) {
- 264 :
const element = mel_metapage.Storage[key];
- 265 :
if (element !== undefined) {
- 266 :
items.push(mel_metapage.Storage.check_day(key));
- 267 :
}
- 268 :
}
- 269 :
- 270 :
return {
- 271 :
items: items,
- 272 :
wait: async function () {
- 273 :
for (let index = 0; index < this.items.length; ++index) {
- 274 :
const element = this.items[index];
- 275 :
if (element.wait !== undefined) await element.wait();
- 276 :
}
- 277 :
},
- 278 :
};
- 279 :
} else {
- 280 :
const update_element = (update_key, day_key) => {
- 281 :
let item = {
- 282 :
wait: async () => {
- 283 :
return mel_metapage.Storage.get(update_key);
- 284 :
},
- 285 :
};
- 286 :
let update = false;
- 287 :
if (
- 288 :
!update &&
- 289 :
moment(mel_metapage.Storage.get(day_key)).format('DD/MM/YYYY') !==
- 290 :
moment().format('DD/MM/YYYY')
- 291 :
)
- 292 :
update = true;
- 293 :
if (!update && mel_metapage.Storage.get(update_key) === null)
- 294 :
update = true;
- 295 :
if (update) {
- 296 :
mel_metapage.Storage.remove(update_key);
- 297 :
workspaces.sync.PostToParent({
- 298 :
exec: 'rcmail.mel_metapage_fn.tasks_updated()',
- 299 :
child: false,
- 300 :
});
- 301 :
item.wait = async () => {
- 302 :
await wait(() => mel_metapage.Storage.get(update_key) === null);
- 303 :
return mel_metapage.Storage.get(update_key);
- 304 :
};
- 305 :
}
- 306 :
return item;
- 307 :
};
- 308 :
- 309 :
switch (storage) {
- 310 :
case mel_metapage.Storage.other_tasks:
- 311 :
case mel_metapage.Storage.tasks:
- 312 :
return update_element(
- 313 :
storage,
- 314 :
mel_metapage.Storage.last_task_update,
- 315 :
);
- 316 :
case mel_metapage.Storage.calendar_all_events:
- 317 :
case mel_metapage.Storage.calendar:
- 318 :
return update_element(
- 319 :
storage,
- 320 :
mel_metapage.Storage.last_calendar_update,
- 321 :
);
- 322 :
default:
- 323 :
return item;
- 324 :
}
- 325 :
}
- 326 :
},
- 327 :
/**
- 328 :
* Clé des données du calendrier.
- 329 :
*/
- 330 :
calendar_all_events: CONST_STORAGE_KEY_ALL_EVENTS,
- 331 :
calendar: 'mel_metapage.calendar',
- 332 :
calendar_by_days: 'mel_metapage.calendars.by_days',
- 333 :
calendars_number_wainting: 'mel_metapage.calendars.by_days.waiting',
- 334 :
/**
- 335 :
* Clé des données des tâches.
- 336 :
*/
- 337 :
tasks: 'mel_metapage.tasks',
- 338 :
other_tasks: 'mel_metapage.tasks.others',
- 339 :
other_tasks_count: 'mel_metapage.tasks.others.count',
- 340 :
/**
- 341 :
* Clé du nombre de mail non lus.
- 342 :
*/
- 343 :
mail: 'mel_metapage.mail.count',
- 344 :
wsp_mail: 'mel_metapage.wsp.mails',
- 345 :
last_calendar_update: 'mel_metapage.calendar.last_update_2',
- 346 :
last_task_update: 'mel_metapage.tasks.last_update',
- 347 :
ariane: 'ariane_datas',
- 348 :
wait_frame_loading: 'mel_metapage.wait_frame_loading',
- 349 :
wait_frame_waiting: 'waiting...',
- 350 :
wait_frame_loaded: 'loaded',
- 351 :
wait_call_loading: 'mel_metapage.call.loading',
- 352 :
color_mode: 'colorMode',
- 353 :
title_workspaces: 'workspaces.title',
- 354 :
},
- 355 :
/**
- 356 :
* Liste des symboles.
- 357 :
*/
- 358 :
Symbols: {
- 359 :
/**
- 360 :
* Symboles du plugin "My_Day".
- 361 :
*/
- 362 :
my_day: {
- 363 :
/**
- 364 :
* Symbole "Calendrier", est utilisé pour savoir si il faut mettre à jours uniquement les évènements ou non.
- 365 :
*/
- 366 :
calendar: Symbol('calendar'),
- 367 :
/**
- 368 :
* Symbole "Tâches", est utilisé pour savoir si il faut mettre à jours uniquement les tâches ou non.
- 369 :
*/
- 370 :
tasks: Symbol('tasks'),
- 371 :
},
- 372 :
nextcloud: {
- 373 :
folder: Symbol('folder'),
- 374 :
file: Symbol('file'),
- 375 :
},
- 376 :
navigator: {
- 377 :
firefox: Symbol('firefox'),
- 378 :
},
- 379 :
null: Symbol('null'),
- 380 :
},
- 381 :
/**
- 382 :
* Les différents Identifiants
- 383 :
*/
- 384 :
Ids: {
- 385 :
/**
- 386 :
* Ids pour le menu.
- 387 :
*/
- 388 :
menu: {
- 389 :
/**
- 390 :
* Id des différents badges du menu.
- 391 :
*/
- 392 :
badge: {
- 393 :
calendar: 'menu-badge-calendar',
- 394 :
tasks: 'menu-badge-tasks',
- 395 :
mail: 'menu-badge-mail',
- 396 :
ariane: 'menu-badge-ariane',
- 397 :
},
- 398 :
},
- 399 :
create: {
- 400 :
doc_input: 'generated-document-input-mel-metapage',
- 401 :
doc_input_ext: 'generated-document-input-mel-metapage-ext',
- 402 :
doc_input_hidden: 'generated-document-input-mel-metapage-hidden',
- 403 :
doc_input_path: 'generated-document-select-mel-metapage-path',
- 404 :
},
- 405 :
},
- 406 :
PopUp: {
- 407 :
/**
- 408 :
* Ouvre la popup de chat
- 409 :
* @returns
- 410 :
*/
- 411 :
open_ariane() {
- 412 :
if (rcmail.busy) return;
- 413 :
- 414 :
if (mel_metapage.PopUp.ariane === null) {
- 415 :
mel_metapage.PopUp.ariane = new ArianePopUp(ArianeButton.default());
- 416 :
rcmail.addEventListener('toggle-options-user', (show) => {
- 417 :
let $iframe =
- 418 :
mel_metapage.PopUp.ariane.ariane.card.body.card.find('iframe');
- 419 :
- 420 :
if (show.show === true) $iframe.css('z-index', '1');
- 421 :
else $iframe.css('z-index', '');
- 422 :
});
- 423 :
}
- 424 :
- 425 :
if (mel_metapage.PopUp.ariane.is_show === true)
- 426 :
mel_metapage.PopUp.ariane.hide();
- 427 :
else mel_metapage.PopUp.ariane.show();
- 428 :
},
- 429 :
ariane: null,
- 430 :
},
- 431 :
Other: {
- 432 :
webconf: {
- 433 :
private: '/group',
- 434 :
},
- 435 :
},
- 436 :
RCMAIL_Start: {
- 437 :
async ping_nextcloud() {
- 438 :
if (
- 439 :
rcmail.env.nextcloud_url !== undefined &&
- 440 :
rcmail.env.nextcloud_url !== null &&
- 441 :
rcmail.env.nextcloud_url !== ''
- 442 :
) {
- 443 :
rcmail.env.nextcloud_pinged = await ping(rcmail.env.nextcloud_url);
- 444 :
if (rcmail.env.nextcloud_pinged === false)
- 445 :
rcmail.env.nextcloud_pinged = await ping(
- 446 :
rcmail.env.nextcloud_url,
- 447 :
true,
- 448 :
);
- 449 :
}
- 450 :
},
- 451 :
},
- 452 :
Frames: {
- 453 :
max: 10,
- 454 :
lastFrames: [],
- 455 :
add(frame) {
- 456 :
if (parent !== window) return parent.mel_metapage.Frames.add(frame);
- 457 :
- 458 :
if (frame?.task === 'webconf') return this;
- 459 :
- 460 :
if (this.lastFrames.length + 1 > 5) this.lastFrames.pop();
- 461 :
- 462 :
this.lastFrames.push(frame);
- 463 :
return this;
- 464 :
},
- 465 :
reset() {
- 466 :
if (parent !== window) return parent.mel_metapage.Frames.reset();
- 467 :
- 468 :
this.lastFrames = [];
- 469 :
return this;
- 470 :
},
- 471 :
pop() {
- 472 :
if (parent !== window) return parent.mel_metapage.Frames.pop();
- 473 :
- 474 :
if (this.lastFrames.length === 0) return null;
- 475 :
- 476 :
return this.lastFrames.pop();
- 477 :
},
- 478 :
last(it = 0) {
- 479 :
if (parent !== window) return parent.mel_metapage.Frames.last(it);
- 480 :
- 481 :
if (this.lastFrames.length === 0) return null;
- 482 :
- 483 :
return this.lastFrames[this.lastFrames.length - 1 - it];
- 484 :
},
- 485 :
back(_default = 'home') {
- 486 :
if (parent !== window) return parent.mel_metapage.Frames.back(_default);
- 487 :
- 488 :
const unexist = mel_metapage.Storage.unexist;
- 489 :
let last = this.pop()?.task || _default;
- 490 :
- 491 :
if (last === unexist) last = _default;
- 492 :
- 493 :
return mel_metapage.Functions.change_frame(last, true, true).then(() => {
- 494 :
if ($('.menu-last-frame').hasClass('disabled')) {
- 495 :
m_mp_ChangeLasteFrameInfo();
- 496 :
}
- 497 :
});
- 498 :
},
- 499 :
create_frame(name, task, icon) {
- 500 :
return {
- 501 :
name,
- 502 :
task,
- 503 :
icon,
- 504 :
};
- 505 :
},
- 506 :
},
- 507 :
Functions: {
- 508 :
/**
- 509 :
* Copie un texte dans le press-papier
- 510 :
* @param {string} text Texte à copier
- 511 :
*/
- 512 :
copy(text) {
- 513 :
function copyOnClick(val) {
- 514 :
var tempInput = document.createElement('input');
- 515 :
tempInput.value = val;
- 516 :
document.body.appendChild(tempInput);
- 517 :
tempInput.select();
- 518 :
document.execCommand('copy');
- 519 :
document.body.removeChild(tempInput);
- 520 :
}
- 521 :
- 522 :
copyOnClick(text);
- 523 :
rcmail.display_message(
- 524 :
`${text} copier dans le presse-papier.`,
- 525 :
'confirmation',
- 526 :
);
- 527 :
- 528 :
return this;
- 529 :
},
- 530 :
- 531 :
/**
- 532 :
* Récupère les données du calendrier entre deux dates.
- 533 :
* @param {moment} start (moment) Début des évènements à récupérer
- 534 :
* @param {moment} end (moment) Fin des évènements à récupérer
- 535 :
*/
- 536 :
update_calendar(start, end) {
- 537 :
start = start.format('YYYY-MM-DDTHH:mm:ss');
- 538 :
end = end.format('YYYY-MM-DDTHH:mm:ss');
- 539 :
- 540 :
if (rcmail.env.ev_calendar_url === undefined)
- 541 :
rcmail.env.ev_calendar_url = ev_calendar_url;
- 542 :
- 543 :
return $.ajax({
- 544 :
// fonction permettant de faire de l'ajax
- 545 :
type: 'GET', // methode de transmission des données au fichier php
- 546 :
url:
- 547 :
rcmail.env.ev_calendar_url +
- 548 :
`&source=${mceToRcId(rcmail.env.username)}` +
- 549 :
'&start=' +
- 550 :
start +
- 551 :
'&end=' +
- 552 :
end, // url du fichier php
- 553 :
success: function (data) {
- 554 :
try {
- 555 :
let events = [];
- 556 :
data = JSON.parse(data);
- 557 :
data = Enumerable.from(data)
- 558 :
.where(
- 559 :
(x) =>
- 560 :
mel_metapage.Functions.check_if_date_is_okay(
- 561 :
x.start,
- 562 :
x.end,
- 563 :
start,
- 564 :
) ||
- 565 :
mel_metapage.Functions.check_if_date_is_okay(
- 566 :
x.start,
- 567 :
x.end,
- 568 :
end,
- 569 :
),
- 570 :
)
- 571 :
.toArray();
- 572 :
return data;
- 573 :
} catch (ex) {
- 574 :
console.error(ex);
- 575 :
rcmail.display_message(
- 576 :
'Une erreur est survenue lors de la synchronisation.',
- 577 :
'error',
- 578 :
);
- 579 :
}
- 580 :
},
- 581 :
error: function (xhr, ajaxOptions, thrownError) {
- 582 :
// Add these parameters to display the required response
- 583 :
console.error(xhr, ajaxOptions, thrownError);
- 584 :
rcmail.display_message(
- 585 :
'Une erreur est survenue lors de la synchronisation.',
- 586 :
'error',
- 587 :
);
- 588 :
},
- 589 :
});
- 590 :
},
- 591 :
- 592 :
/**
- 593 :
* Vérifie si un élement est valide ou si c'est un doublon ou une instance originale
- 594 :
* @param {JSON} element
- 595 :
* @param {Array<JSON>} events
- 596 :
* @param {boolean} test
- 597 :
* @returns {boolean|JSON} True si pas de problème | Evènement problématique
- 598 :
*/
- 599 :
check_if_calendar_valid(element, events, test = true) {
- 600 :
if (mceToRcId(rcmail.env.username) !== element.calendar) return false;
- 601 :
else {
- 602 :
if (element._instance !== undefined && test) {
- 603 :
for (let it = 0; it < events.length; it++) {
- 604 :
const event = events[it];
- 605 :
if (event.uid === element.uid && event._instance === undefined)
- 606 :
return event;
- 607 :
}
- 608 :
}
- 609 :
}
- 610 :
return true;
- 611 :
},
- 612 :
- 613 :
/**
- 614 :
* Vérifie si une date se trouve entre 2 dates
- 615 :
* @param {string|moment} sd
- 616 :
* @param {string|moment} ed
- 617 :
* @param {string|moment} date
- 618 :
* @returns {boolean}
- 619 :
*/
- 620 :
check_if_date_is_okay(sd, ed, date) {
- 621 :
if (typeof sd === 'string') sd = moment(sd).startOf('day');
- 622 :
- 623 :
if (typeof ed === 'string') ed = moment(ed).endOf('day');
- 624 :
- 625 :
if (typeof date === 'string') date = moment(date);
- 626 :
- 627 :
startDate = moment(date).startOf('day');
- 628 :
endDate = moment(date).endOf('day');
- 629 :
- 630 :
if (startDate <= sd && sd <= endDate) return true;
- 631 :
else if (startDate <= ed && ed <= endDate) return true;
- 632 :
else if (
- 633 :
sd <= startDate &&
- 634 :
startDate <= ed &&
- 635 :
sd <= endDate &&
- 636 :
endDate <= ed
- 637 :
)
- 638 :
return true;
- 639 :
else return false;
- 640 :
},
- 641 :
- 642 :
get_from_url(url) {
- 643 :
const URL_VARIABLE = '/?';
- 644 :
const URL_SEPARATOR = '&';
- 645 :
url = url.split(URL_VARIABLE)[1].split(URL_SEPARATOR);
- 646 :
let datas = {};
- 647 :
- 648 :
for (let index = 0, len = url.length; index < len; ++index) {
- 649 :
const element = url[index].split('=');
- 650 :
datas[element[0]] = element[1];
- 651 :
}
- 652 :
- 653 :
return datas;
- 654 :
},
- 655 :
- 656 :
/**
- 657 :
* Récupère une URL conforme.
- 658 :
* @param {string} task Tâche
- 659 :
* @param {string} action Action
- 660 :
* @param {JSON} args divers arguments ex {_eventType:1}
- 661 :
* @returns {string}
- 662 :
*/
- 663 :
url(task, action = '', args = null) {
- 664 :
let url = task;
- 665 :
if (action !== null && action !== undefined && action !== '')
- 666 :
url += '&_action=' + action;
- 667 :
- 668 :
if (
- 669 :
window.location.href.includes(
- 670 :
`${rcmail.env.mel_metapage_const.key}=${rcmail.env.mel_metapage_const.value}`,
- 671 :
) ||
- 672 :
window !== parent
- 673 :
) {
- 674 :
if (args === null || args === undefined) {
- 675 :
args = {};
- 676 :
args[rcmail.env.mel_metapage_const.key] =
- 677 :
rcmail.env.mel_metapage_const.value;
- 678 :
} else if (args[rcmail.env.mel_metapage_const.key] === undefined)
- 679 :
args[rcmail.env.mel_metapage_const.key] =
- 680 :
rcmail.env.mel_metapage_const.value;
- 681 :
}
- 682 :
- 683 :
if (args !== null) {
- 684 :
for (const key in args) {
- 685 :
if (Object.hasOwnProperty.call(args, key)) {
- 686 :
const element = args[key];
- 687 :
url += '&' + key + '=' + element;
- 688 :
}
- 689 :
}
- 690 :
}
- 691 :
return rcmail.get_task_url(
- 692 :
url,
- 693 :
window.location.origin + window.location.pathname,
- 694 :
);
- 695 :
},
- 696 :
- 697 :
public_url(path, args = null) {
- 698 :
let url =
- 699 :
window.location.origin +
- 700 :
window.location.pathname +
- 701 :
(window.location.pathname[window.location.pathname.length - 1] === '/'
- 702 :
? ''
- 703 :
: '/') +
- 704 :
'public/' +
- 705 :
path;
- 706 :
- 707 :
if (args !== null) {
- 708 :
for (const key in args) {
- 709 :
if (Object.hasOwnProperty.call(args, key)) {
- 710 :
const element = args[key];
- 711 :
url += (url.includes('?') ? '&' : '?') + key + '=' + element;
- 712 :
}
- 713 :
}
- 714 :
}
- 715 :
- 716 :
return url;
- 717 :
},
- 718 :
- 719 :
/**
- 720 :
* Change de frame, même si l'on est pas depuis "TOP"
- 721 :
* @param {string} frame Frame à ouvrir
- 722 :
* @param {boolean} changepage Si vrai, on change de page, sinon la page ouverte sera caché.
- 723 :
* @param {boolean} waiting Si l'on veux attendre que la frame sois ouverte ou non.
- 724 :
* @param {JSON} args Arguments à ajouter dans l'url de la frame.
- 725 :
*/
- 726 :
async change_frame(
- 727 :
frame,
- 728 :
changepage = true,
- 729 :
waiting = false,
- 730 :
args = null,
- 731 :
actions = [],
- 732 :
) {
- 733 :
await PageManager.SwitchFrame(frame, { changepage, args, actions });
- 734 :
// var busy;
- 735 :
// if (changepage) busy = (top ?? window).rcmail.set_busy(true, 'loading');
- 736 :
- 737 :
// // if (frame === "webconf")
- 738 :
// // {
- 739 :
// // var initial_change_page = changepage;
- 740 :
// // changepage = false;
- 741 :
// // }
- 742 :
- 743 :
// // if (waiting)
- 744 :
// // mel_metapage.Storage.set(
- 745 :
// // mel_metapage.Storage.wait_frame_loading,
- 746 :
// // mel_metapage.Storage.wait_frame_waiting,
- 747 :
// // );
- 748 :
- 749 :
// (top ?? window).rcmail.env.can_change_while_busy = true;
- 750 :
// let promise = (top ?? window).mm_st_OpenOrCreateFrame(
- 751 :
// frame,
- 752 :
// changepage,
- 753 :
// args,
- 754 :
// actions,
- 755 :
// );
- 756 :
- 757 :
// if (waiting) await promise;
- 758 :
// // if (waiting) {
- 759 :
// // await wait(
- 760 :
// // () =>
- 761 :
// // mel_metapage.Storage.get(
- 762 :
// // mel_metapage.Storage.wait_frame_loading,
- 763 :
// // ) !== mel_metapage.Storage.wait_frame_loaded,
- 764 :
// // );
- 765 :
// // mel_metapage.Storage.remove(mel_metapage.Storage.wait_frame_loading);
- 766 :
// // }
- 767 :
- 768 :
// // if (frame === "webconf")
- 769 :
// // {
- 770 :
// // if (initial_change_page)
- 771 :
// // {
- 772 :
// // (top ?? window).mm_st_OpenOrCreateFrame(frame, initial_change_page, args, actions);
- 773 :
// // }
- 774 :
// // //this.update_refresh_thing();
- 775 :
// // }
- 776 :
- 777 :
// if (changepage && busy) {
- 778 :
// (top ?? window).rcmail.set_busy(false, 'loading', busy);
- 779 :
// busy = null;
- 780 :
// }
- 781 :
- 782 :
return this;
- 783 :
},
- 784 :
- 785 :
/**
- 786 :
* Change de page en utilisant le combo tâche + action.
- 787 :
* @param {string} task
- 788 :
* @param {string} action
- 789 :
* @param {JSON} params
- 790 :
* @returns
- 791 :
*/
- 792 :
async change_page(
- 793 :
task,
- 794 :
action = null,
- 795 :
params = {},
- 796 :
update = true,
- 797 :
force = false,
- 798 :
) {
- 799 :
let contracted_task;
- 800 :
let $querry;
- 801 :
- 802 :
if (window !== parent)
- 803 :
return await parent.mel_metapage.Functions.change_page(
- 804 :
task,
- 805 :
action,
- 806 :
params,
- 807 :
update,
- 808 :
force,
- 809 :
);
- 810 :
- 811 :
contracted_task = mm_st_ClassContract(task);
- 812 :
- 813 :
if (action !== null) params['_action'] = action;
- 814 :
- 815 :
$querry = $(`iframe.${task}-frame`);
- 816 :
- 817 :
if (update) {
- 818 :
if ($querry.length > 0) {
- 819 :
params[rcmail.env.mel_metapage_const.key] =
- 820 :
rcmail.env.mel_metapage_const.value;
- 821 :
action = mel_metapage.Functions.url(task, null, params);
- 822 :
- 823 :
try {
- 824 :
if ($querry[0].contentWindow.location.href !== action)
- 825 :
$querry[0].src = action;
- 826 :
else if (force) {
- 827 :
$querry[0].contentWindow.location.reload();
- 828 :
}
- 829 :
} catch (error) {}
- 830 :
} else if ($(`.${task}-frame`).length > 0) {
- 831 :
action = mel_metapage.Functions.url(task, null, params);
- 832 :
if (window.location.href !== action) $(`.${task}-frame`).remove();
- 833 :
}
- 834 :
}
- 835 :
- 836 :
return await this.change_frame(contracted_task, true, true, params);
- 837 :
},
- 838 :
- 839 :
/**
- 840 :
* Ouvre la page de chat, avec un can/group/tem associé ou non.
- 841 :
* @param {string} channel_or_group group/ ou channel/
- 842 :
* @returns {Promise}
- 843 :
*/
- 844 :
open_chat(channel_or_group = null) {
- 845 :
return mel_metapage.Functions.change_frame('rocket', true, true).then(
- 846 :
() => {
- 847 :
if (channel_or_group !== null && channel_or_group !== undefined) {
- 848 :
if (channel_or_group[0] !== '/')
- 849 :
channel_or_group = `/${channel_or_group}`;
- 850 :
parent.$('.discussion-frame')[0].contentWindow.postMessage(
- 851 :
{
- 852 :
externalCommand: 'go',
- 853 :
path: channel_or_group,
- 854 :
},
- 855 :
'*',
- 856 :
);
- 857 :
}
- 858 :
},
- 859 :
);
- 860 :
},
- 861 :
- 862 :
/**
- 863 :
* F5 une frame
- 864 :
* @param {string} frame Classe de la frame à refresh
- 865 :
* @returns Chaînage
- 866 :
*/
- 867 :
update_frame(frame) {
- 868 :
this.call('reload_frame', false, {
- 869 :
_integrated: true,
- 870 :
always: true,
- 871 :
args: [`${frame}-frame`],
- 872 :
});
- 873 :
- 874 :
return this;
- 875 :
},
- 876 :
- 877 :
/**
- 878 :
* Reviens à la frame d'avant.
- 879 :
* @param {boolean} wait Si l'on doit attendre le changement de frame ou non.
- 880 :
* @param {string} default_frame Frame par défaut si il n'y a pas de frame d'avant. Si null, ne fait rien dans ce cas.
- 881 :
*/
- 882 :
async frame_back(wait = true, default_frame = null) {
- 883 :
let last = await this.ask('rcmail.env.last_frame_class');
- 884 :
- 885 :
if (
- 886 :
last === null ||
- 887 :
last === undefined ||
- 888 :
last === mel_metapage.Storage.unexist
- 889 :
) {
- 890 :
if (default_frame !== null) last = default_frame;
- 891 :
else return;
- 892 :
}
- 893 :
- 894 :
const tmp = await this.change_frame(last, true, wait);
- 895 :
- 896 :
top.rcmail.clear_messages();
- 897 :
- 898 :
for (const iterator of $('iframe.mm-frame')) {
- 899 :
iterator.contentWindow.rcmail.clear_messages();
- 900 :
}
- 901 :
- 902 :
return tmp;
- 903 :
},
- 904 :
- 905 :
get_current_title(current_task = null, _default = document.title) {
- 906 :
if (parent !== window)
- 907 :
return parent.mel_metapage.Function.get_current_title(
- 908 :
current_task,
- 909 :
_default,
- 910 :
);
- 911 :
- 912 :
if (current_task === null)
- 913 :
current_task = (top ?? window).rcmail.env.current_task;
- 914 :
- 915 :
if (current_task === 'chat' || current_task === 'discussion') {
- 916 :
return 'Discussion';
- 917 :
} else if (current_task === 'webconf') {
- 918 :
return 'Visioconférence';
- 919 :
} else {
- 920 :
const frame = $(`iframe.${current_task}-frame`);
- 921 :
if (frame.length > 0) return frame[0].contentDocument.title || _default;
- 922 :
else if ($(`.${current_task}-frame`).length > 0) return document.title;
- 923 :
else return _default;
- 924 :
}
- 925 :
},
- 926 :
- 927 :
/**
- 928 :
* Execute un string depuis "TOP"
- 929 :
* @param {string} exec String à éxécuter
- 930 :
* @param {string} child Exécuter aussi dans les fenetres filles ?
- 931 :
* @param {JSON} args Autres arguments (eval etc....)
- 932 :
*/
- 933 :
call(exec, child = false, args = {}) {
- 934 :
if (typeof exec !== 'string') {
- 935 :
const tmp_exec = JSON.stringify(exec);
- 936 :
if (tmp_exec === undefined) {
- 937 :
if (typeof exec === 'function') exec = `(${exec.toString()})()`;
- 938 :
else exec = exec.toString();
- 939 :
} else exec = tmp_exec;
- 940 :
}
- 941 :
- 942 :
let config = {
- 943 :
exec: exec,
- 944 :
child: child,
- 945 :
};
- 946 :
- 947 :
if (args != null && args !== undefined) {
- 948 :
for (const key in args) {
- 949 :
if (Object.hasOwnProperty.call(args, key)) {
- 950 :
const element = args[key];
- 951 :
config[key] = element;
- 952 :
}
- 953 :
}
- 954 :
}
- 955 :
- 956 :
if (
- 957 :
window.workspaces !== undefined &&
- 958 :
window.workspaces.sync !== undefined
- 959 :
)
- 960 :
workspaces.sync.PostToParent(config);
- 961 :
else {
- 962 :
parent.postMessage(config);
- 963 :
}
- 964 :
- 965 :
return this;
- 966 :
},
- 967 :
- 968 :
/**
- 969 :
* Execute du script à un contexte au dessus.
- 970 :
* @param {string} exec String à éxécuter
- 971 :
* @param {boolean} child Exécuter aussi dans les fenetres filles ?
- 972 :
* @param {JSON} args Autres arguments (eval etc....)
- 973 :
*/
- 974 :
async callAsync(exec, child = false, args = {}) {
- 975 :
mel_metapage.Storage.set(
- 976 :
mel_metapage.Storage.wait_call_loading,
- 977 :
mel_metapage.Storage.wait_frame_waiting,
- 978 :
);
- 979 :
this.call(exec, child, args);
- 980 :
await wait(() => {
- 981 :
return (
- 982 :
mel_metapage.Storage.get(mel_metapage.Storage.wait_call_loading) ===
- 983 :
mel_metapage.Storage.wait_frame_waiting
- 984 :
);
- 985 :
});
- 986 :
- 987 :
return this;
- 988 :
},
- 989 :
- 990 :
/**
- 991 :
* Modifie l'url du navigateur
- 992 :
* @param {string} url URL à afficher
- 993 :
*/
- 994 :
title(url) {
- 995 :
mel_metapage.Functions.call(
- 996 :
`window.history.replaceState({}, document.title, '${url}')`,
- 997 :
);
- 998 :
return this;
- 999 :
},
- 1000 :
- 1001 :
/**
- 1002 :
* Met (ou pas) la frame en cours et parente en loading.
- 1003 :
* @param {boolean} busy
- 1004 :
*/
- 1005 :
busy(busy = true) {
- 1006 :
const framed = window !== parent;
- 1007 :
mel_metapage.Storage.set('mel.busy', busy);
- 1008 :
if (busy) {
- 1009 :
this.call("rcmail.set_busy(true, 'loading')");
- 1010 :
if (framed) rcmail.set_busy(true, 'loading');
- 1011 :
} else {
- 1012 :
this.call('rcmail.set_busy(false);rcmail.clear_messages();');
- 1013 :
if (framed) {
- 1014 :
rcmail.set_busy(false);
- 1015 :
rcmail.clear_messages();
- 1016 :
}
- 1017 :
}
- 1018 :
- 1019 :
return this;
- 1020 :
},
- 1021 :
- 1022 :
/**
- 1023 :
* Vérifie si l'application est occupée.
- 1024 :
* @returns {boolean}
- 1025 :
*/
- 1026 :
is_busy() {
- 1027 :
const framed = window !== parent && rcmail.busy != undefined;
- 1028 :
if (framed)
- 1029 :
return mel_metapage.Storage.get('mel.busy') === true || rcmail.busy;
- 1030 :
else {
- 1031 :
if (rcmail.busy === undefined)
- 1032 :
return mel_metapage.Storage.get('mel.busy') === true;
- 1033 :
else
- 1034 :
return rcmail.busy || mel_metapage.Storage.get('mel.busy') === true;
- 1035 :
}
- 1036 :
},
- 1037 :
- 1038 :
/**
- 1039 :
* @async
- 1040 :
* Récupère une variable globale parente.
- 1041 :
* @param {string} props Variable à récupérer
- 1042 :
* @returns {Promise<any>} Valeur de la variable
- 1043 :
*/
- 1044 :
async ask(props) {
- 1045 :
this.call(`mel_metapage.Storage.set("mel.ask", ${props})`);
- 1046 :
await wait(() => mel_metapage.Storage.get('mel.ask') === null);
- 1047 :
props = mel_metapage.Storage.get('mel.ask');
- 1048 :
mel_metapage.Storage.remove('mel.ask');
- 1049 :
return props;
- 1050 :
},
- 1051 :
- 1052 :
updateRichText(html) {
- 1053 :
return html.replace(/</g, '<');
- 1054 :
},
- 1055 :
- 1056 :
remove_accents(string) {
- 1057 :
return string.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
- 1058 :
},
- 1059 :
- 1060 :
replace_dets(string = '', rep = '') {
- 1061 :
const dets = [
- 1062 :
' le ',
- 1063 :
' la ',
- 1064 :
' les ',
- 1065 :
' un ',
- 1066 :
' une ',
- 1067 :
' de ',
- 1068 :
' des ',
- 1069 :
' mon ',
- 1070 :
' ma ',
- 1071 :
' tes ',
- 1072 :
' ton ',
- 1073 :
' ta ',
- 1074 :
' son ',
- 1075 :
' sa ',
- 1076 :
' ses ',
- 1077 :
' notre ',
- 1078 :
' nos ',
- 1079 :
' vos ',
- 1080 :
' votre ',
- 1081 :
' leur ',
- 1082 :
' leurs ',
- 1083 :
' se ',
- 1084 :
' ce ',
- 1085 :
' cette ',
- 1086 :
' cet ',
- 1087 :
' ces ',
- 1088 :
' a ',
- 1089 :
"l'",
- 1090 :
];
- 1091 :
- 1092 :
for (const iterator of dets) {
- 1093 :
string = string.replaceAll(iterator, rep);
- 1094 :
}
- 1095 :
- 1096 :
while (string[0] === rep) {
- 1097 :
string = string.slice(1, string.length);
- 1098 :
}
- 1099 :
- 1100 :
return string;
- 1101 :
},
- 1102 :
- 1103 :
replace_special_char(string, rep = '') {
- 1104 :
const regexp = /[^a-zA-Z0-9_ -]/g;
- 1105 :
string = string.replace(regexp, rep);
- 1106 :
- 1107 :
while (string[0] === rep) {
- 1108 :
string = string.slice(1, string.length);
- 1109 :
}
- 1110 :
- 1111 :
return string;
- 1112 :
},
- 1113 :
- 1114 :
/**
- 1115 :
*
- 1116 :
* @param {string} url
- 1117 :
* @returns
- 1118 :
*/
- 1119 :
webconf_url(url) {
- 1120 :
if (url[url.length - 1] === '&') url = url.slice(0, url.length - 1);
- 1121 :
- 1122 :
let val = url.toUpperCase();
- 1123 :
- 1124 :
if (val.includes(rcmail.env['webconf.base_url'].toUpperCase())) {
- 1125 :
val = val.split('/');
- 1126 :
val = val[val.length - 1];
- 1127 :
val = val.toUpperCase();
- 1128 :
} else if (val.includes('PUBLIC/WEBCONF'))
- 1129 :
val = val.split('_KEY=')[1].split('&')[0];
- 1130 :
else {
- 1131 :
let link = WebconfLink.create({ location: url, categories: [] });
- 1132 :
val = link.key;
- 1133 :
- 1134 :
try {
- 1135 :
if (val === '') {
- 1136 :
link = WebconfLink.create({
- 1137 :
location: `#visio:${url}`,
- 1138 :
categories: [],
- 1139 :
});
- 1140 :
val = link.key;
- 1141 :
}
- 1142 :
} catch (error) {
- 1143 :
val = null;
- 1144 :
}
- 1145 :
}
- 1146 :
- 1147 :
return val || null;
- 1148 :
},
- 1149 :
- 1150 :
_shuffle(array) {
- 1151 :
var currentIndex = array.length,
- 1152 :
temporaryValue,
- 1153 :
randomIndex;
- 1154 :
// While there remain elements to shuffle...
- 1155 :
while (currentIndex !== 0) {
- 1156 :
// Pick a remaining element...
- 1157 :
randomIndex = Math.floor(Math.random() * currentIndex);
- 1158 :
currentIndex -= 1;
- 1159 :
- 1160 :
// And swap it with the current element.
- 1161 :
temporaryValue = array[currentIndex];
- 1162 :
array[currentIndex] = array[randomIndex];
- 1163 :
array[randomIndex] = temporaryValue;
- 1164 :
}
- 1165 :
return array;
- 1166 :
},
- 1167 :
- 1168 :
generateWebconfRoomName() {
- 1169 :
var charArray = [
- 1170 :
'A',
- 1171 :
'B',
- 1172 :
'C',
- 1173 :
'D',
- 1174 :
'E',
- 1175 :
'F',
- 1176 :
'G',
- 1177 :
'H',
- 1178 :
'I',
- 1179 :
'J',
- 1180 :
'K',
- 1181 :
'L',
- 1182 :
'M',
- 1183 :
'N',
- 1184 :
'O',
- 1185 :
'P',
- 1186 :
'Q',
- 1187 :
'R',
- 1188 :
'S',
- 1189 :
'T',
- 1190 :
'U',
- 1191 :
'V',
- 1192 :
'W',
- 1193 :
'X',
- 1194 :
'Y',
- 1195 :
'Z',
- 1196 :
];
- 1197 :
var digitArray = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
- 1198 :
var roomName =
- 1199 :
this._shuffle(digitArray).join('').substring(0, 3) +
- 1200 :
this._shuffle(charArray).join('').substring(0, 7);
- 1201 :
return this._shuffle(roomName.split('')).join('');
- 1202 :
},
- 1203 :
- 1204 :
/**
- 1205 :
* Faire facilement une requête ajax
- 1206 :
* @param {string} url
- 1207 :
* @param {JSON} datas
- 1208 :
* @param {function} success
- 1209 :
* @param {function} failed
- 1210 :
* @param {string} type
- 1211 :
* @returns {Promise<any>} Appel ajax
- 1212 :
*/
- 1213 :
ajax(
- 1214 :
url,
- 1215 :
datas = mel_metapage.Symbols.null,
- 1216 :
success = (datas) => {},
- 1217 :
failed = (xhr, ajaxOptions, thrownError) => {
- 1218 :
console.error(xhr, ajaxOptions, thrownError);
- 1219 :
},
- 1220 :
type = 'POST',
- 1221 :
) {
- 1222 :
let config = {
- 1223 :
// fonction permettant de faire de l'ajax
- 1224 :
type: type, // methode de transmission des données au fichier php
- 1225 :
url: url, //rcmail.env.ev_calendar_url+'&start='+dateNow(new Date())+'&end='+dateNow(new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()+1)), // url du fichier php
- 1226 :
success: success,
- 1227 :
error: failed,
- 1228 :
};
- 1229 :
if (datas !== mel_metapage.Symbols.null) config['data'] = datas;
- 1230 :
- 1231 :
return $.ajax(config);
- 1232 :
},
- 1233 :
- 1234 :
/**
- 1235 :
* Execute un appel ajax get
- 1236 :
* @param {string} url
- 1237 :
* @param {JSON} datas
- 1238 :
* @param {function} success
- 1239 :
* @param {function} failed
- 1240 :
* @returns {Promise<any>}
- 1241 :
*/
- 1242 :
get(
- 1243 :
url,
- 1244 :
datas = {},
- 1245 :
success = (datas) => {},
- 1246 :
failed = (xhr, ajaxOptions, thrownError) => {
- 1247 :
console.error(xhr, ajaxOptions, thrownError);
- 1248 :
},
- 1249 :
) {
- 1250 :
for (const key in datas) {
- 1251 :
if (Object.hasOwnProperty.call(datas, key)) {
- 1252 :
const element = datas[key];
- 1253 :
url += `${url.includes('?') ? '&' : '?'}${key}=${encodeURIComponent(element)}`;
- 1254 :
}
- 1255 :
}
- 1256 :
return this.ajax(url, mel_metapage.Symbols.null, success, failed, 'GET');
- 1257 :
},
- 1258 :
- 1259 :
/**
- 1260 :
* Execute un appel ajax post
- 1261 :
* @param {string} url
- 1262 :
* @param {Symbol|JSON} datas <c>mel_metapage.Symbols.null</c> si aucune données.
- 1263 :
* @param {function} success
- 1264 :
* @param {function} failed
- 1265 :
*/
- 1266 :
post(
- 1267 :
url,
- 1268 :
datas = mel_metapage.Symbols.null,
- 1269 :
success = (datas) => {},
- 1270 :
failed = (xhr, ajaxOptions, thrownError) => {
- 1271 :
console.error(xhr, ajaxOptions, thrownError);
- 1272 :
},
- 1273 :
) {
- 1274 :
return this.ajax(url, datas, success, failed);
- 1275 :
},
- 1276 :
- 1277 :
/**
- 1278 :
* Contient différents fonctions pour mettre à jours certaines données.
- 1279 :
*/
- 1280 :
update: {
- 1281 :
/**
- 1282 :
* Met à jours le calendrier.
- 1283 :
*/
- 1284 :
calendar() {
- 1285 :
mel_metapage.Functions.call(
- 1286 :
'rcmail.mel_metapage_fn.calendar_updated();',
- 1287 :
);
- 1288 :
return this;
- 1289 :
},
- 1290 :
},
- 1291 :
- 1292 :
/**
- 1293 :
* Vérifie si un handler existe sur un élément.
- 1294 :
* @param {DOMElement} element Element à tester.
- 1295 :
* @param {function} handler Fonction à vérifier
- 1296 :
* @param {string} type Type d'évènement
- 1297 :
* @returns {boolean}
- 1298 :
*/
- 1299 :
handlerExist(element, handler, type = 'click') {
- 1300 :
if (element.val !== undefined) element = element[0];
- 1301 :
return Enumerable.from(jQuery._data(element, 'events')[type])
- 1302 :
.where((x) => x.handler + '' === handler + '')
- 1303 :
.any();
- 1304 :
},
- 1305 :
- 1306 :
/**
- 1307 :
* Fonctions lié au stockage nextcloud.
- 1308 :
*/
- 1309 :
stockage: {
- 1310 :
/**
- 1311 :
* Ouvre la frame nextcloud et affiche un document en particulier (si il existe).
- 1312 :
* @param {JSON|Nextcloud_File} datas Données du document à afficher.
- 1313 :
* {
- 1314 :
file:nom du fichier,
- 1315 :
folder:chemin du fichier
- 1316 :
}
- 1317 :
* @param {boolean} isfiledatas Si vrai, datas est un objet <c>Nextcloud_File</c>
- 1318 :
* @param {function} thenFunc Action à faire une fois que l'on à changer de page.
- 1319 :
*/
- 1320 :
go(datas, goFunc = null, thenFunc = null) {
- 1321 :
let init = 'new Nextcloud("rcmail.env.nextcloud_username")';
- 1322 :
let go = `.go(${JSON.stringify(datas)}, ${goFunc})`;
- 1323 :
let then = '';
- 1324 :
- 1325 :
if (thenFunc !== null) {
- 1326 :
then = `.then((a) => { (${thenFunc + ''})(a) })`;
- 1327 :
}
- 1328 :
- 1329 :
return mel_metapage.Functions.call(init + go + then);
- 1330 :
},
- 1331 :
have_0_quota() {
- 1332 :
return rcmail.env.have_0_quota ?? false;
- 1333 :
},
- 1334 :
is_stockage_active() {
- 1335 :
const DEFAULT = false;
- 1336 :
return rcmail?.env?.why_is_not_active?.value
- 1337 :
? rcmail.env.why_is_not_active.value ===
- 1338 :
rcmail.env.why_is_not_active.consts.ST_ACTIVE
- 1339 :
: DEFAULT;
- 1340 :
},
- 1341 :
canDriveActions() {
- 1342 :
return !this.have_0_quota() && this.is_stockage_active();
- 1343 :
},
- 1344 :
},
- 1345 :
- 1346 :
/**
- 1347 :
* Recherche dans les mails
- 1348 :
* @param {string} itemToSearch Objet à chercher
- 1349 :
* @param {Array<string>} fields Champs
- 1350 :
* @param {boolean} openFrame Ouvrir ou non la frame
- 1351 :
*/
- 1352 :
async searchOnMail(itemToSearch, fields, openFrame = false) {
- 1353 :
if (parent === window) {
- 1354 :
if (openFrame)
- 1355 :
await mel_metapage.Functions.change_frame('mail', true, true);
- 1356 :
- 1357 :
if ($('iframe.mail-frame').length > 0)
- 1358 :
$('iframe.mail-frame')[0].contentWindow.postMessage({
- 1359 :
exec: 'search',
- 1360 :
_integrated: true,
- 1361 :
child: false,
- 1362 :
args: [itemToSearch, fields],
- 1363 :
});
- 1364 :
else search_action(itemToSearch, fields);
- 1365 :
} else
- 1366 :
mel_metapage.Functions.call(
- 1367 :
`mel_metapage.Functions.searchOnMail('${itemToSearch}', ${JSON.stringify(fields)}, ${openFrame})`,
- 1368 :
);
- 1369 :
- 1370 :
return this;
- 1371 :
},
- 1372 :
- 1373 :
doActionFrame(frame, doAction, ...functionArgs) {
- 1374 :
//console.log("[doActionFrame]",frame, doAction, parent !== window);
- 1375 :
if (parent !== window) {
- 1376 :
mel_metapage.Functions.call('mel_metapage.doActionFrame', false, {
- 1377 :
_integrated: true,
- 1378 :
always: true,
- 1379 :
args: [frame, doAction + '', ...functionArgs],
- 1380 :
});
- 1381 :
} else {
- 1382 :
if (typeof doAction === 'string') {
- 1383 :
doAction = new Function(`return (${doAction})(...arguments)`);
- 1384 :
}
- 1385 :
- 1386 :
//Personne ouvert
- 1387 :
if ($(`.${frame}-frame`).length === 0) doAction(0, ...functionArgs);
- 1388 :
else if ($(`iframe.${frame}-frame`).length > 0)
- 1389 :
//Frame ouverte
- 1390 :
doAction(1, ...functionArgs);
- 1391 :
//Page ouverte
- 1392 :
else doAction(2, ...functionArgs);
- 1393 :
}
- 1394 :
- 1395 :
return this;
- 1396 :
},
- 1397 :
- 1398 :
update_refresh_thing() {
- 1399 :
let current = (top ?? window).$('.refresh-current-thing');
- 1400 :
let action =
- 1401 :
window.webconf_helper.already() ||
- 1402 :
(top ?? window).rcmail.env.current_frame_name === 'webconf';
- 1403 :
- 1404 :
if (action === true)
- 1405 :
current.addClass('disabled').attr('disabled', 'disabled');
- 1406 :
else current.removeClass('disabled').removeAttr('disabled');
- 1407 :
- 1408 :
return this;
- 1409 :
},
- 1410 :
- 1411 :
isNavigator(symbol) {
- 1412 :
switch (symbol) {
- 1413 :
case mel_metapage.Symbols.navigator.firefox:
- 1414 :
return typeof InstallTrigger !== 'undefined';
- 1415 :
- 1416 :
default:
- 1417 :
throw 'Unknown navigator';
- 1418 :
}
- 1419 :
},
- 1420 :
- 1421 :
/**
- 1422 :
*
- 1423 :
* @param {string|JSON} _params - String sous forme '?dir=PATH&fileid=ID' ou JSON sous forme {path:'', id:''}
- 1424 :
*/
- 1425 :
async change_frame_nextcloud(_params = null) {
- 1426 :
const appfiles = '/apps/files/';
- 1427 :
const urlToAdd =
- 1428 :
_params.id === undefined && _params.includes(appfiles) ? appfiles : '';
- 1429 :
let param = urlToAdd + (_params ?? '');
- 1430 :
let configArgs = null;
- 1431 :
- 1432 :
//si _params n'est pas un string
- 1433 :
if (_params !== null) {
- 1434 :
if (_params.id !== undefined)
- 1435 :
param = `${urlToAdd}?dir=${_params.path}&fileid=${_params.id}`;
- 1436 :
- 1437 :
configArgs = {
- 1438 :
_params: urlencode(param),
- 1439 :
};
- 1440 :
}
- 1441 :
- 1442 :
const url = `${rcmail.env.nextcloud_url}${param ?? ''}`;
- 1443 :
- 1444 :
if (parent.$('iframe.stockage-frame').length > 0)
- 1445 :
parent
- 1446 :
.$('iframe.stockage-frame')[0]
- 1447 :
.contentWindow.$('#mel_nextcloud_frame')[0].src = url;
- 1448 :
- 1449 :
await this.change_frame('stockage', true, true, configArgs);
- 1450 :
- 1451 :
parent.$(
- 1452 :
'iframe.stockage-frame',
- 1453 :
)[0].contentWindow.rcmail.env.nextcloud_gotourl = url;
- 1454 :
- 1455 :
return this;
- 1456 :
},
- 1457 :
- 1458 :
async comment_mail(uid, comment, folder = 'INBOX') {
- 1459 :
let data = uid;
- 1460 :
await this.post(
- 1461 :
mel_metapage.Functions.url('mel_metapage', 'comment_mail'),
- 1462 :
{
- 1463 :
_uid: uid,
- 1464 :
_comment: comment,
- 1465 :
_folder: folder,
- 1466 :
},
- 1467 :
(datas) => {
- 1468 :
if (datas == 'false') {
- 1469 :
rcmail.display_message('Une erreur est survenue!', 'error');
- 1470 :
data = false;
- 1471 :
} else data = datas;
- 1472 :
},
- 1473 :
);
- 1474 :
- 1475 :
return data;
- 1476 :
},
- 1477 :
- 1478 :
calculateObjectSizeInMo(obj) {
- 1479 :
const jsonString = JSON.stringify(obj);
- 1480 :
const blob = new Blob([jsonString]);
- 1481 :
const sizeInBytes = blob.size;
- 1482 :
const sizeInMb = sizeInBytes / (1024 * 1024);
- 1483 :
return sizeInMb;
- 1484 :
},
- 1485 :
- 1486 :
colors: {
- 1487 :
kMel_Luminance(rgb) {
- 1488 :
let R = rgb[0] / 255;
- 1489 :
let G = rgb[1] / 255;
- 1490 :
let B = rgb[2] / 255;
- 1491 :
- 1492 :
if (R <= 0.04045) {
- 1493 :
R = R / 12.92;
- 1494 :
} else {
- 1495 :
R = ((R + 0.055) / 1.055) ** 2.4;
- 1496 :
}
- 1497 :
if (G <= 0.04045) {
- 1498 :
G = G / 12.92;
- 1499 :
} else {
- 1500 :
G = ((G + 0.055) / 1.055) ** 2.4;
- 1501 :
}
- 1502 :
if (B <= 0.04045) {
- 1503 :
B = B / 12.92;
- 1504 :
} else {
- 1505 :
B = ((B + 0.055) / 1.055) ** 2.4;
- 1506 :
}
- 1507 :
- 1508 :
const L = 0.2126 * R + 0.7152 * G + 0.0722 * B;
- 1509 :
- 1510 :
return L;
- 1511 :
},
- 1512 :
- 1513 :
kMel_CompareLuminance(rgb1, rgb2) {
- 1514 :
const l1 = this.kMel_Luminance(rgb1);
- 1515 :
const l2 = this.kMel_Luminance(rgb2);
- 1516 :
- 1517 :
let ratio;
- 1518 :
if (l1 > l2) {
- 1519 :
ratio = (l1 + 0.05) / (l2 + 0.05);
- 1520 :
} else {
- 1521 :
ratio = (l2 + 0.05) / (l1 + 0.05);
- 1522 :
}
- 1523 :
- 1524 :
return ratio;
- 1525 :
},
- 1526 :
- 1527 :
kMel_LuminanceRatioAAA(rgb1, rgb2) {
- 1528 :
const isAAA = this.kMel_CompareLuminance(rgb1, rgb2) > 4.5;
- 1529 :
return isAAA;
- 1530 :
},
- 1531 :
- 1532 :
kMel_extractRGB(color) {
- 1533 :
let regexp = /#[a-fA-F\d]{6}/g;
- 1534 :
let rgbArray = color.match(regexp);
- 1535 :
- 1536 :
if (rgbArray) {
- 1537 :
rgbArray[0] = parseInt(color.slice(1, 3), 16);
- 1538 :
rgbArray[1] = parseInt(color.slice(3, 5), 16);
- 1539 :
rgbArray[2] = parseInt(color.slice(5, 7), 16);
- 1540 :
- 1541 :
return rgbArray;
- 1542 :
}
- 1543 :
- 1544 :
regexp = /#[a-fA-F\d]{3}/g;
- 1545 :
rgbArray = color.match(regexp);
- 1546 :
- 1547 :
if (rgbArray) {
- 1548 :
rgbArray[0] = parseInt(color.slice(1, 2), 16);
- 1549 :
rgbArray[1] = parseInt(color.slice(2, 3), 16);
- 1550 :
rgbArray[2] = parseInt(color.slice(3, 4), 16);
- 1551 :
- 1552 :
return rgbArray;
- 1553 :
}
- 1554 :
- 1555 :
regexp = /\d+/g;
- 1556 :
rgbArray = color.match(regexp);
- 1557 :
- 1558 :
if (rgbArray.length === 3 || rgbArray.length === 4) {
- 1559 :
return rgbArray;
- 1560 :
}
- 1561 :
},
- 1562 :
},
- 1563 :
},
- 1564 :
};
- 1565 :
- 1566 :
window.mel_metapage = mel_metapage;