TP_JO2024/home/dist/analytics/analytics.module.js
2024-03-27 17:19:37 +01:00

4898 lines
113 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*! DSFR v1.11.2 | SPDX-License-Identifier: MIT | License-Filename: LICENSE.md | restricted use (see terms and conditions) */
const config = {
prefix: 'fr',
namespace: 'dsfr',
organisation: '@gouvfr',
version: '1.11.2'
};
const api = window[config.namespace];
const patch = {
namespace: 'a4e35ba2a938ba9d007689dbf3f46acbb9807869'
};
const Collection = {
MANUAL: 'manual',
LOAD: 'load',
FULL: 'full',
HASH: 'hash'
};
const key = '_EA_';
const DISABLED = `${key}disabled`;
const TOGGLE = `${key}toggle`;
class Opt {
constructor () {
this._configure();
}
_configure () {
const scope = this;
window[DISABLED] = () => scope.isDisabled;
window[TOGGLE] = this.toggle.bind(this);
}
get isDisabled () {
return localStorage.getItem(key);
}
toggle () {
if (this.isDisabled) this.enable();
else this.disable();
}
enable () {
if (localStorage.getItem(key)) {
localStorage.removeItem(key);
}
}
disable () {
localStorage.setItem(key, '1');
}
}
const opt = new Opt();
const PUSH = 'EA_push';
class Init {
constructor (domain) {
this._domain = domain;
this._isLoaded = false;
this._promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
}
get id () {
return this._id;
}
get store () {
return this._store;
}
configure () {
this.init();
return this._promise;
}
init () {
let bit = 5381;
for (let i = this._domain.length - 1; i > 0; i--) bit = (bit * 33) ^ this._domain.charCodeAt(i);
bit >>>= 0;
this._id = `_EA_${bit}`;
this._store = [];
this._store.eah = this._domain;
window[this._id] = this._store;
if (!window[PUSH]) window[PUSH] = (...args) => this.store.push(args);
if (opt.isDisabled) {
api.inspector.warn('User opted out, eulerian is disabled');
this._reject('User opted out, eulerian is disabled');
} else this.load();
}
load () {
const stamp = new Date() / 1E7 | 0;
const offset = stamp % 26;
const key = String.fromCharCode(97 + offset, 122 - offset, 65 + offset) + (stamp % 1E3);
this._script = document.createElement('script');
this._script.ea = this.id;
this._script.async = true;
this._script.addEventListener('load', this.loaded.bind(this));
this._script.addEventListener('error', this.error.bind(this));
this._script.src = `//${this._domain}/${key}.js?2`;
const node = document.getElementsByTagName('script')[0];
node.parentNode.insertBefore(this._script, node);
}
error () {
api.inspector.error('unable to load Eulerian script file. the domain declared in your configuration must match the domain provided by the Eulerian interface (tag creation)');
this._reject('eulerian script loading error');
}
loaded () {
if (this._isLoaded) return;
this._isLoaded = true;
this._resolve();
}
}
/*
(function(e, a) {
var i = e.length,
y = 5381,
k = 'script',
s = window,
v = document,
o = v.createElement(k);
for (; i;) {
i -= 1;
y = (y * 33) ^ e.charCodeAt(i)
}
y = '_EA_' + (y >>>= 0);
(function(e, a, s, y) {
s[a] = s[a] || function() {
(s[y] = s[y] || []).push(arguments);
s[y].eah = e;
};
}(e, a, s, y));
i = new Date / 1E7 | 0;
o.ea = y;
y = i % 26;
o.async = 1;
o.src = '//' + e + '/' + String.fromCharCode(97 + y, 122 - y, 65 + y) + (i % 1E3) + '.js?2';
s = v.getElementsByTagName(k)[0];
s.parentNode.insertBefore(o, s);
})
('mon.domainedetracking.com', 'EA_push');
*/
/*
(function(e, a) {
var i = e.length,
y = 5381,
k = 'script',
z = '_EA_',
zd = z + 'disabled',
s = window,
v = document,
o = v.createElement(k),
l = s.localStorage;
for (; i;) {
i -= 1;
y = (y * 33) ^ e.charCodeAt(i)
}
y = z + (y >>>= 0);
(function(e, a, s, y, z, zd, l) {
s[a] = s[a] || function() {
(s[y] = s[y] || []).push(arguments);
s[y].eah = e;
};
s[zd] = function() {
return l.getItem(z);
};
s[z + 'toggle'] = function() {
(s[zd]()) ? l.removeItem(z): l.setItem(z, 1);
}
}(e, a, s, y, z, zd, l));
if (!s[zd]()) {
i = new Date / 1E7 | 0;
o.ea = y;
y = i % 26;
o.async = 1;
o.src = '//' + e + '/' + String.fromCharCode(97 + y, 122 - y, 65 + y) + (i % 1E3) + '.js?2';
s = v.getElementsByTagName(k)[0];
s.parentNode.insertBefore(o, s);
}
})('mon.domainedetracking.com', 'EA_push');
*/
const State = {
UNKNOWN: -1,
CONFIGURING: 0,
CONFIGURED: 1,
INITIATED: 2,
READY: 3
};
class TarteAuCitronIntegration {
constructor (config) {
this._config = config;
this._state = State.UNKNOWN;
this._promise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
}
configure () {
if (this._state >= State.CONFIGURED) return this._promise;
if (this._state === State.UNKNOWN) {
api.inspector.info('analytics configures tarteaucitron');
this._state = State.CONFIGURING;
}
const tarteaucitron = window.tarteaucitron;
if (!tarteaucitron || !tarteaucitron.services) {
window.requestAnimationFrame(this.configure.bind(this));
return;
}
this._state = State.CONFIGURED;
const init = this.init.bind(this);
const data = {
key: 'eulerian',
type: 'analytic',
name: 'Eulerian Analytics',
needConsent: true,
cookies: ['etuix'],
uri: 'https://eulerian.com/vie-privee',
js: init,
fallback: () => { tarteaucitron.services.eulerian.js(); }
};
tarteaucitron.services.eulerian = data;
if (!tarteaucitron.job) tarteaucitron.job = [];
tarteaucitron.job.push('eulerian');
return this._promise;
}
init () {
if (this._state >= State.INITIATED) return;
this._state = State.INITIATED;
window.__eaGenericCmpApi = this.integrate.bind(this);
const update = this.update.bind(this);
window.addEventListener('tac.close_alert', update);
window.addEventListener('tac.close_panel', update);
}
integrate (cmpApi) {
if (this._state >= State.READY) return;
this._state = State.READY;
this._cmpApi = cmpApi;
api.inspector.info('analytics has integrated tarteaucitron');
this._resolve();
this.update();
}
update () {
if (this._state < State.READY) return;
this._cmpApi('tac', window.tarteaucitron, 1);
}
}
class ConsentManagerPlatform {
constructor (config) {
this._config = config;
if (config) {
switch (config.id) {
case 'tarteaucitron':
this.integrateTarteAuCitron();
break;
}
}
}
integrateTarteAuCitron () {
this._tac = new TarteAuCitronIntegration(this._config);
return this._tac.configure();
}
optin () {
}
}
const push = (type, layer) => {
if (typeof window.EA_push !== 'function') {
api.inspector.warn('Analytics datalayer not sent, Eulerian API isn\'t yet avalaible');
return;
}
api.inspector.info('analytics', type, layer);
window.EA_push(type, layer);
};
const PushType = {
COLLECTOR: 'collector',
ACTION: 'action',
ACTION_PARAMETER: 'actionparam'
};
class Renderer {
constructor () {
this._renderables = [];
this._rendering = this.render.bind(this);
requestAnimationFrame(this._rendering);
}
add (renderable) {
const index = this._renderables.indexOf(renderable);
if (index === -1) this._renderables.push(renderable);
}
remove (renderable) {
const index = this._renderables.indexOf(renderable);
if (index > -1) this._renderables.splice(index, 1);
}
render () {
this._renderables.forEach(renderable => renderable.render());
requestAnimationFrame(this._rendering);
}
}
const renderer = new Renderer();
const SLICE = 80;
class Queue {
constructor () {
this._startingActions = [];
this._endingActions = [];
this._handlingVisibilityChange = this._handleVisibilityChange.bind(this);
this._handlingEnd = this._handleEnd.bind(this);
this._isStarted = false;
this._isListening = false;
this.reset();
}
setCollector (collector) {
this._collector = collector;
}
reset (ending = false) {
this._type = PushType.ACTION;
if (!ending) this._startingActions.length = 0;
this._endingActions.length = 0;
this._count = 0;
this._delay = -1;
this._isRequested = false;
this._unlisten();
}
start () {
if (this._isStarted) return;
this._isStarted = true;
renderer.add(this);
}
collect () {
this._type = PushType.COLLECTOR;
this._request();
}
appendStartingAction (action, data) {
if (!this._collector.isActionEnabled && !action.isForced) return;
if (!action || this._startingActions.some(queued => queued.test(action))) {
api.inspector.log('appendStartingAction exists or null', action);
return;
}
const queued = new QueuedAction(action, data);
this._startingActions.push(queued);
this._request();
}
appendEndingAction (action, data) {
if (!this._collector.isActionEnabled && !action.isForced) return;
if (!action || this._endingActions.some(queued => queued.test(action))) {
api.inspector.log('appendEndingAction exists or null', action);
return;
}
const queued = new QueuedAction(action, data);
this._endingActions.push(queued);
this._request();
}
_request () {
this._listen();
this._isRequested = true;
this._delay = 4;
}
_listen () {
if (this._isListening) return;
this._isListening = true;
document.addEventListener('visibilitychange', this._handlingVisibilityChange);
document.addEventListener('unload', this._handlingEnd);
document.addEventListener('beforeunload', this._handlingEnd);
document.addEventListener('pagehide', this._handlingEnd);
}
_unlisten () {
if (!this._isListening) return;
this._isListening = false;
document.removeEventListener('visibilitychange', this._handlingVisibilityChange);
document.removeEventListener('unload', this._handlingEnd);
document.removeEventListener('beforeunload', this._handlingEnd);
document.removeEventListener('pagehide', this._handlingEnd);
}
_handleVisibilityChange (e) {
if (document.visibilityState === 'hidden') this.send();
}
_handleEnd () {
this.send();
}
render () {
if (this._delay <= -1) return;
this._delay--;
this._count++;
switch (true) {
case this._count > 20:
case this._delay === 0:
this.send();
break;
}
}
send (ending = false) {
if (!this._isRequested) return;
const actionLayers = [];
if (!ending) actionLayers.push(...this._startingActions.map(queued => queued.start()).filter(layer => layer.length > 0));
actionLayers.push(...this._endingActions.map(queued => queued.end()).filter(layer => layer.length > 0));
const length = ((actionLayers.length / SLICE) + 1) | 0;
const slices = [];
for (let i = 0; i < length; i++) {
const slice = actionLayers.slice(i * SLICE, (i + 1) * SLICE);
slices.push(slice.flat());
}
if (this._type === PushType.COLLECTOR && this._collector.isCollecting) {
const layer = this._collector.layer;
if (slices.length > 0) {
const slice = slices.splice(0, 1)[0];
if (slice.length > 0) layer.push.apply(layer, slice);
}
layer.flat();
if (layer.length > 0) push(PushType.COLLECTOR, layer);
}
if (slices.length > 0) {
for (let i = 0; i < slices.length; i++) {
const slice = slices[i];
if (slice.length > 0) push(PushType.ACTION, slice);
}
}
this.reset(ending);
}
}
class QueuedAction {
constructor (action, data) {
this._action = action;
this._data = data;
}
test (action) {
return this._action === action;
}
start () {
return this._action.start(this._data);
}
end () {
return this._action.end(this._data);
}
}
const queue = new Queue();
class Debug {
get debugger () {
return window._oEa;
}
get isActive () {
if (!this.debugger) return false;
return this.debugger._dbg === '1';
}
set isActive (value) {
if (!this.debugger || this.isActive === value) return;
this.debugger.debug(value ? 1 : 0);
}
}
const debug = new Debug();
const Status = {
CONNECTED: {
id: 'connected',
value: 'connecté',
isConnected: true,
isDefault: true
},
ANONYMOUS: {
id: 'anonymous',
value: 'anonyme',
isConnected: false,
isDefault: true
},
GUEST: {
id: 'guest',
value: 'invité',
isConnected: false
}
};
const Type$2 = {
INDIVIDUAL: {
id: 'individual',
value: 'part'
},
PROFESSIONNAL: {
id: 'professionnal',
value: 'pro'
}
};
/* '["\'<>*$&~`|\\\\?^~]'; */
var RESTRICTED = {
'0x0022': '',
'0x0024': '',
'0x0026': '',
'0x0027': '',
'0x002a': '',
'0x002c': '',
'0x003c': '',
'0x003e': '',
'0x003f': '',
'0x005c': '',
'0x005e': '',
'0x0060': '',
'0x007c': '',
'0x007e': ''
};
// import TABLE from './unicode-table';
const charCodeHex = (char) => {
const code = char.charCodeAt(0).toString(16);
return '0x0000'.slice(0, -code.length) + code;
};
const normalize = (text) => {
if (!text) return text;
// text = [...text].map(char => TABLE[charCodeHex(char)] || char).join('');
text = [...text].map(char => RESTRICTED[charCodeHex(char)] || char).join('');
text = text.replace(/\s+/g, ' ').replace(/\s/g, '_');
text = text.toLowerCase();
return text;
};
const validateString = (value, name, allowNull = true) => {
switch (true) {
case typeof value === 'number':
return `${value}`;
case typeof value === 'string':
return value;
case value === undefined && allowNull:
case value === null && allowNull:
return '';
}
api.inspector.warn(`unexpected value '${value}' set at analytics.${name}. Expecting a String`);
return null;
};
const validateNumber = (value, name, allowNull = true) => {
switch (true) {
case !isNaN(value):
return value;
case typeof value === 'string' && !isNaN(Number(value)):
return Number(value);
case value === undefined && allowNull:
case value === null && allowNull:
return -1;
}
api.inspector.warn(`unexpected value '${value}' set at analytics.${name}. Expecting a Number`);
return null;
};
const validateBoolean = (value, name) => {
switch (true) {
case typeof value === 'boolean':
return value;
case typeof value === 'string' && value.toLowerCase() === 'true':
case value === '1':
case value === 1:
return true;
case typeof value === 'string' && value.toLowerCase() === 'false':
case value === '0':
case value === 0:
return false;
case value === undefined:
case value === null:
return value;
}
api.inspector.warn(`unexpected value '${value}' set at analytics.${name}. Expecting a Boolean`);
return null;
};
const validateLang = (value, name, allowNull = true) => {
switch (true) {
case typeof value === 'string' && /^[A-Za-z]{2}$|^[A-Za-z]{2}[-_]/.test(value):
return value.split(/[-_]/)[0].toLowerCase();
case value === undefined && allowNull:
case value === null && allowNull:
return '';
}
api.inspector.warn(`unexpected value '${value}' set at analytics.${name}. Expecting language as a String following ISO 639-1 format`);
return null;
};
const validateGeography = (value, name, allowNull = true) => {
switch (true) {
case typeof value === 'string':
if (!/^FR-[A-Z0-9]{2,3}$/.test(value)) api.inspector.warn(`value '${value}' set at analytics.${name} with wrong format. Geographic location should be a String following ISO 3166-2:FR format`);
return value;
case value === undefined && allowNull:
case value === null && allowNull:
return '';
}
api.inspector.warn(`unexpected value '${value}' set at analytics.${name}. Expecting geographic location as a String following ISO 3166-2:FR format`);
return null;
};
const normaliseISODate = (date) => date.toISOString().split('T')[0];
const validateDate = (value, name, allowNull = true) => {
switch (true) {
case value instanceof Date:
return normaliseISODate(value);
case typeof value === 'string': {
const date = new Date(value);
if (date.toString() !== 'Invalid Date') return normaliseISODate(date);
break;
}
case value === undefined && allowNull:
case value === null && allowNull:
return null;
}
api.inspector.warn(`unexpected value '${value}' set at analytics.${name}. Expecting a Date`);
return null;
};
class User {
constructor (config) {
this._config = config || {};
}
reset (clear = false) {
this._isConnected = false;
this.status = Status.ANONYMOUS;
if (!clear && this._config.connect) this.connect(this._config.connect.uid, this._config.connect.email, this._config.connect.isNew);
else {
this._uid = undefined;
this._email = undefined;
this._isNew = false;
}
this.profile = clear ? undefined : this._config.profile;
this.language = clear ? undefined : this._config.language;
this.type = clear ? undefined : this._config.type;
}
connect (uid, email, isNew = false) {
this._uid = validateString(uid, 'user.uid');
if (/^[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]{2,}@[a-zA-Z0-9-]{2,}\.[a-zA-Z]{2,}$/.test(email)) api.inspector.warn('Please check analytics.user.email is properly encrypted ');
this._email = validateString(email, 'user.email');
this._isNew = validateBoolean(isNew);
this._isConnected = true;
this.status = Status.CONNECTED;
}
get uid () {
return this._uid;
}
get email () {
return this._email;
}
get isNew () {
return this._isNew;
}
set status (id) {
const stati = Object.values(Status).filter(status => status.isConnected === this._isConnected);
this._status = stati.filter(status => status.id === id || status.value === id)[0] || stati.filter(status => status.isDefault)[0];
}
get status () {
return this._status.id;
}
set profile (value) {
const valid = validateString(value, 'user.profile');
if (valid !== null) this._profile = valid;
}
get profile () {
return this._profile.id;
}
set language (value) {
const valid = validateLang(value, 'user.language');
if (valid !== null) this._language = valid;
}
get language () {
return this._language || navigator.language;
}
set type (id) {
this._type = Object.values(Type$2).filter(type => type.id === id || type.value === id)[0];
}
get type () {
return this._type.id;
}
get layer () {
const layer = [];
if (this.uid) layer.push('uid', normalize(this.uid));
if (this.email) layer.push('email', normalize(this.email));
if (this.isNew) layer.push('newcustomer', '1');
if (this.language) layer.push('user_language', this.language);
layer.push('user_login_status', this._status.value);
if (this._profile) layer.push('profile', this._profile);
if (this._type) layer.push('user_type', this._type.value);
return layer;
}
}
User.Status = Status;
User.Type = Type$2;
const Environment = {
DEVELOPMENT: {
id: 'development',
value: 'dev'
},
STAGE: {
id: 'stage',
value: 'stage'
},
PRODUCTION: {
id: 'production',
value: 'prod'
}
};
class Site {
constructor (config) {
this._config = config || {};
}
reset (clear = false) {
this.environment = clear ? Environment.DEVELOPMENT.id : this._config.environment;
this.entity = clear ? undefined : this._config.entity;
this.language = clear ? undefined : this._config.language;
this.target = clear ? undefined : this._config.target;
this.type = clear ? undefined : this._config.type;
this.region = clear ? undefined : this._config.region;
this.department = clear ? undefined : this._config.department;
this.version = clear ? undefined : this._config.version;
this._api = api.version;
}
set environment (value) {
switch (value) {
case Environment.PRODUCTION.id:
case Environment.PRODUCTION.value:
this._environment = Environment.PRODUCTION;
break;
case Environment.STAGE.id:
case Environment.STAGE.value:
this._environment = Environment.STAGE;
break;
case Environment.DEVELOPMENT.id:
case Environment.DEVELOPMENT.value:
this._environment = Environment.DEVELOPMENT;
break;
default:
this._environment = Environment.DEVELOPMENT;
}
}
get environment () {
return this._environment ? this._environment.id : Environment.DEVELOPMENT.id;
}
set entity (value) {
const valid = validateString(value, 'site.entity');
if (valid !== null) this._entity = valid;
}
get entity () {
return this._entity;
}
set language (value) {
const valid = validateLang(value, 'site.language');
if (valid !== null) this._language = valid;
}
get language () {
return this._language || document.documentElement.lang;
}
set target (value) {
const valid = validateString(value, 'site.target');
if (valid !== null) this._target = valid;
}
get target () {
return this._target;
}
set type (value) {
const valid = validateString(value, 'site.type');
if (valid !== null) this._type = valid;
}
get type () {
return this._type;
}
set region (value) {
const valid = validateGeography(value, 'site.region');
if (valid !== null) this._region = valid;
}
get region () {
return this._region;
}
set department (value) {
const valid = validateGeography(value, 'site.department');
if (valid !== null) this._department = valid;
}
get department () {
return this._department;
}
set version (value) {
const valid = validateString(value, 'site.version');
if (valid !== null) this._version = valid;
}
get version () {
return this._version;
}
get api () {
return this._api;
}
get layer () {
const layer = [];
layer.push('site_environment', this._environment.value);
if (this.entity) layer.push('site_entity', normalize(this.entity));
else api.inspector.warn('entity is required in analytics.site');
if (this.language) layer.push('site_language', this.language);
if (this.target) layer.push('site_target', normalize(this.target));
if (this.type) layer.push('site_type', normalize(this.type));
if (this.region) layer.push('site_region', this.region);
if (this.department) layer.push('site_department', this.department);
if (this.version) layer.push('site_version', this.version);
if (this.api) layer.push('api_version', this.api);
return layer;
}
}
Site.Environment = Environment;
const Inventory = {
accordion: api.internals.ns.selector('accordion'),
alert: api.internals.ns.selector('alert'),
badge: api.internals.ns.selector('badge'),
breadcrumb: api.internals.ns.selector('breadcrumb'),
button: api.internals.ns.selector('btn'),
callout: api.internals.ns.selector('callout'),
card: api.internals.ns.selector('card'),
checkbox: api.internals.ns.selector('checkbox-group'),
connect: api.internals.ns.selector('connect'),
consent: api.internals.ns.selector('consent-banner'),
content: api.internals.ns.selector('content-media'),
download: api.internals.ns.selector('download'),
follow: api.internals.ns.selector('follow'),
footer: api.internals.ns.selector('footer'),
header: api.internals.ns.selector('header'),
highlight: api.internals.ns.selector('highlight'),
input: api.internals.ns.selector('input-group'),
link: api.internals.ns.selector('link'),
modal: api.internals.ns.selector('modal'),
navigation: api.internals.ns.selector('nav'),
notice: api.internals.ns.selector('notice'),
pagination: api.internals.ns.selector('pagination'),
quote: api.internals.ns.selector('quote'),
radio: api.internals.ns.selector('radio-group'),
search: api.internals.ns.selector('search-bar'),
select: api.internals.ns.selector('select'),
share: api.internals.ns.selector('share'),
sidemenu: api.internals.ns.selector('sidemenu'),
stepper: api.internals.ns.selector('stepper'),
summary: api.internals.ns.selector('summary'),
tab: api.internals.ns.selector('tabs'),
table: api.internals.ns.selector('table'),
tag: api.internals.ns.selector('tag'),
tile: api.internals.ns.selector('tile'),
toggle: api.internals.ns.selector('toggle'),
tooltip: api.internals.ns.selector('tooltip'),
transcription: api.internals.ns.selector('transcription'),
translate: api.internals.ns.selector('translate'),
upload: api.internals.ns.selector('upload-group')
};
const CollectionState = {
COLLECTABLE: 'collectable',
COLLECTING: 'collecting',
COLLECTED: 'collected'
};
class Page {
constructor (config) {
this._config = config || {};
this._state = CollectionState.COLLECTABLE;
}
reset (clear = false) {
this.path = clear ? '' : this._config.path;
this.referrer = clear ? '' : this._config.referrer;
this.title = clear ? '' : this._config.title;
this.name = clear ? '' : this._config.name;
this.id = clear ? '' : this._config.id;
this.author = clear ? '' : this._config.author;
this.date = clear ? '' : this._config.date;
this._labels = clear || !this._config.labels ? ['', '', '', '', ''] : this._config.labels;
this._labels.length = 5;
this._tags = clear || !this._config.tags ? [] : this._config.tags;
this._categories = clear || !this._config.categories ? ['', '', ''] : this._config.categories;
this.isError = !clear && this._config.isError;
this.template = clear ? '' : this._config.template;
this.group = clear ? '' : this._config.group;
this.segment = clear ? '' : this._config.segment;
this.subtemplate = clear ? '' : this._config.subtemplate;
this.theme = clear ? '' : this._config.theme;
this.subtheme = clear ? '' : this._config.subtheme;
this.related = clear ? '' : this._config.related;
this.depth = clear || isNaN(this._config.depth) ? 0 : this._config.depth;
this.current = clear || isNaN(this._config.current) ? -1 : this._config.current;
this.total = clear || isNaN(this._config.total) ? -1 : this._config.total;
this._filters = clear || !this._config.filters ? [] : this._config.filters;
}
collecting () {
if (this._state !== CollectionState.COLLECTABLE) {
api.inspector.warn(`current path '${this.path}' was already collected`);
return false;
}
this._state = CollectionState.COLLECTING;
return true;
}
get isCollecting () {
return this._state === CollectionState.COLLECTING;
}
set path (value) {
const valid = validateString(value, 'page.path');
if (valid !== null) {
this._path = valid;
this._state = CollectionState.COLLECTABLE;
}
}
get path () {
return this._path || `${document.location.pathname}${document.location.search}`;
}
set referrer (value) {
const valid = validateString(value, 'page.referrer');
if (valid !== null) this._referrer = valid;
}
get referrer () {
return this._referrer;
}
set title (value) {
const valid = validateString(value, 'page.title');
if (valid !== null) this._title = valid;
}
get title () {
return this._title || document.title;
}
set id (value) {
const valid = validateString(value, 'page.id');
if (valid !== null) this._id = valid;
}
get id () {
return this._id;
}
set author (value) {
const valid = validateString(value, 'page.author');
if (valid !== null) this._author = valid;
}
get author () {
return this._author;
}
set date (value) {
const valid = validateDate(value, 'page.date');
if (valid !== null) this._date = valid;
}
get date () {
return this._date;
}
get tags () {
return this._tags;
}
set name (value) {
const valid = validateString(value, 'page.name');
if (valid !== null) this._name = valid;
}
get name () {
return this._name || this.title;
}
get labels () {
return this._labels;
}
get categories () {
return this._categories;
}
set isError (value) {
const valid = validateBoolean(value, 'page.isError');
if (valid !== null) this._isError = valid;
}
get isError () {
return this._isError;
}
set template (value) {
const valid = validateString(value, 'page.template');
if (valid !== null) this._template = valid;
}
get template () {
return this._template || 'autres';
}
set segment (value) {
const valid = validateString(value, 'page.segment');
if (valid !== null) this._segment = valid;
}
get segment () {
return this._segment || this.template;
}
set group (value) {
const valid = validateString(value, 'page.group');
if (valid !== null) this._group = valid;
}
get group () {
return this._group || this.template;
}
set subtemplate (value) {
const valid = validateString(value, 'page.subtemplate');
if (valid !== null) this._subtemplate = valid;
}
get subtemplate () {
return this._subtemplate;
}
set theme (value) {
const valid = validateString(value, 'page.theme');
if (valid !== null) this._theme = valid;
}
get theme () {
return this._theme;
}
set subtheme (value) {
const valid = validateString(value, 'page.subtheme');
if (valid !== null) this._subtheme = valid;
}
get subtheme () {
return this._subtheme;
}
set related (value) {
const valid = validateString(value, 'page.related');
if (valid !== null) this._related = valid;
}
get related () {
return this._related;
}
set depth (value) {
const valid = validateNumber(value, 'page.depth');
if (valid !== null) this._depth = valid;
}
get depth () {
return this._depth;
}
set current (value) {
const valid = validateNumber(value, 'page.current');
if (valid !== null) this._current = valid;
}
get current () {
return this._current;
}
set total (value) {
const valid = validateNumber(value, 'page.total');
if (valid !== null) this._total = valid;
}
get total () {
return this._total;
}
get filters () {
return this._filters;
}
get layer () {
this._state = CollectionState.COLLECTED;
const layer = [];
if (this.path) layer.push('path', normalize(this.path));
if (this.referrer) layer.push('referrer', normalize(this.referrer));
if (this.title) layer.push('page_title', normalize(this.title));
if (this.name) layer.push('page_name', normalize(this.name));
if (this.id) layer.push('page_id', normalize(this.id));
if (this.author) layer.push('page_author', normalize(this.author));
if (this.date) layer.push('page_date', normalize(this.date));
const components = Object.keys(Inventory).map(id => document.querySelector(Inventory[id]) !== null ? id : null).filter(id => id !== null).join(',');
if (components) layer.push('page_components', components);
const labels = this._labels.slice(0, 5);
labels.length = 5;
if (labels.some(label => label)) layer.push('pagelabel', labels.map(label => typeof label === 'string' ? normalize(label) : '').join(','));
const tags = this._tags;
if (tags.some(tag => tag)) layer.push('pagetag', tags.map(tag => typeof tag === 'string' ? normalize(tag) : '').join(','));
this._categories.forEach((category, index) => {
if (category) layer.push(`page_category${index + 1}`, category);
});
if (this._isError) layer.push('error', '1');
layer.push('page_template', normalize(this.template));
layer.push('pagegroup', normalize(this.group));
layer.push('site-segment', normalize(this.segment));
if (this.subtemplate) layer.push('page_subtemplate', normalize(this.subtemplate));
if (this.theme) layer.push('page_theme', normalize(this.theme));
if (this.subtheme) layer.push('page_subtheme', normalize(this.subtheme));
if (this.related) layer.push('page_related', normalize(this.related));
if (!isNaN(this.depth)) layer.push('page_depth', this.depth);
if (!isNaN(this.current) && this.current > -1) {
let pagination = `${this.current}`;
if (!isNaN(this.total) && this.total > -1) pagination += `/${this.total}`;
layer.push('page_pagination', pagination);
}
if (this.filters.length && this.filters.some(label => label)) {
const filters = this.filters.map(filter => typeof filter === 'string' ? normalize(filter) : '');
layer.push('page_filters', filters.join(','));
}
return layer;
}
}
const Method = {
STANDARD: {
id: 'standard',
value: 'standard',
isDefault: true
},
AUTOCOMPLETE: {
id: 'autocomplete',
value: 'autocompletion'
}
};
class Search {
constructor (config) {
this._config = config || {};
}
reset (clear = false) {
this.engine = clear ? undefined : this._config.engine;
this.results = clear || isNaN(this._config.results) ? -1 : this._config.results;
this.terms = clear ? undefined : this._config.terms;
this.category = clear ? undefined : this._config.category;
this.theme = clear ? undefined : this._config.theme;
this.type = clear ? undefined : this._config.type;
this.method = clear ? undefined : this._config.method;
}
set engine (value) {
const valid = validateString(value, 'search.engine');
if (valid !== null) this._engine = valid;
}
get engine () {
return this._engine;
}
set results (value) {
const valid = validateNumber(value, 'search.results');
if (valid !== null) this._results = valid;
}
get results () {
return this._results;
}
set terms (value) {
const valid = validateString(value, 'search.terms');
if (valid !== null) this._terms = valid;
}
get terms () {
return this._terms;
}
set category (value) {
const valid = validateString(value, 'search.category');
if (valid !== null) this._category = valid;
}
get category () {
return this._category;
}
set theme (value) {
const valid = validateString(value, 'search.theme');
if (valid !== null) this._theme = valid;
}
get theme () {
return this._theme;
}
set type (value) {
const valid = validateString(value, 'search.type');
if (valid !== null) this._type = valid;
this._type = value;
}
get type () {
return this._type;
}
set method (id) {
const methods = Object.values(Method);
this._method = methods.filter(method => method.id === id || method.value === id)[0] || methods.filter(method => method.isDefault)[0];
}
get method () {
return this._method;
}
get layer () {
const layer = [];
if (this.engine) layer.push('isearchengine', normalize(this.engine));
if (this.results > -1) layer.push('isearchresults', this.results);
if (this.terms) layer.push('isearchkey', 'search_terms', 'isearchdata', normalize(this.terms));
if (this.category) layer.push('isearchkey', 'search_category', 'isearchdata', normalize(this.category));
if (this.theme) layer.push('isearchkey', 'search_theme', 'isearchdata', normalize(this.theme));
if (this.type) layer.push('isearchkey', 'search_type', 'isearchdata', normalize(this.type));
if (this._method && layer.length) layer.push('isearchkey', 'search_method', 'isearchdata', this._method.value);
return layer;
}
}
Search.Method = Method;
class Funnel {
constructor (config) {
this._config = config || {};
}
reset (clear = false) {
this.id = clear ? undefined : this._config.id;
this.type = clear ? undefined : this._config.type;
this.name = clear ? undefined : this._config.name;
this.step = clear ? undefined : this._config.step;
this.current = clear || isNaN(this._config.current) ? -1 : this._config.current;
this.total = clear || isNaN(this._config.total) ? -1 : this._config.total;
this.objective = clear ? undefined : this._config.objective;
this.error = clear ? undefined : this._config.error;
}
set id (value) {
const valid = validateString(value, 'funnel.id');
if (valid !== null) this._id = valid;
}
get id () {
return this._id;
}
set type (value) {
const valid = validateString(value, 'funnel.type');
if (valid !== null) this._type = valid;
}
get type () {
return this._type;
}
set name (value) {
const valid = validateString(value, 'funnel.name');
if (valid !== null) this._name = valid;
}
get name () {
return this._name;
}
set step (value) {
const valid = validateString(value, 'funnel.step');
if (valid !== null) this._step = valid;
}
get step () {
return this._step;
}
set current (value) {
const valid = validateNumber(value, 'funnel.current');
if (valid !== null) this._current = valid;
}
get current () {
return this._current;
}
set total (value) {
const valid = validateNumber(value, 'funnel.total');
if (valid !== null) this._total = valid;
}
get total () {
return this._total;
}
set objective (value) {
const valid = validateString(value, 'funnel.objective');
if (valid !== null) this._objective = valid;
this._objective = value;
}
get objective () {
return this._objective;
}
set error (value) {
const valid = validateString(value, 'funnel.error');
if (valid !== null) this._error = valid;
this._error = value;
}
get error () {
return this._error;
}
get layer () {
const layer = [];
if (this.id) layer.push('funnel_id', normalize(this.id));
if (this.type) layer.push('funnel_type', normalize(this.type));
if (this.name) layer.push('funnel_name', normalize(this.name));
if (this.step) layer.push('funnel_step_name', normalize(this.step));
if (!isNaN(this.current) && this.current > -1) layer.push('funnel_step_number', this.current);
if (!isNaN(this.total) && this.total > -1) layer.push('funnel_step_max', this.total);
if (this.objective) layer.push('funnel_objective', normalize(this.objective));
if (this.error) layer.push('funnel_error', normalize(this.error));
return layer;
}
}
const ActionMode = {
IN: 'in',
OUT: 'out',
NONE: 'none'
};
const ActionStatus = {
UNSTARTED: {
id: 'unstarted',
value: -1
},
STARTED: {
id: 'started',
value: 1
},
SINGULAR: {
id: 'singular',
value: 2
},
ENDED: {
id: 'ended',
value: 3
}
};
const getParametersLayer = (data) => {
return Object.entries(data).map(([key, value]) => ['actionpname', normalize(key), 'actionpvalue', normalize(value)]).flat();
};
class Action {
constructor (name) {
this._isMuted = false;
this._isForced = false;
this._name = name;
this._status = ActionStatus.UNSTARTED;
this._labels = [];
this._parameters = {};
this._sentData = [];
}
get isMuted () {
return this._isMuted;
}
set isMuted (value) {
this._isMuted = value;
}
get isForced () {
return this._isForced;
}
set isForced (value) {
this._isForced = value;
}
get isSingular () {
return this._status === ActionStatus.SINGULAR;
}
get status () {
return this._status;
}
get name () {
return this._name;
}
get labels () {
return this._labels;
}
get reference () {
return this._reference;
}
get parameters () {
return this._parameters;
}
get mode () {
return this._mode;
}
singularize () {
this._status = ActionStatus.SINGULAR;
}
rewind () {
this._sentData = [];
this._status = ActionStatus.UNSTARTED;
}
addParameter (key, value) {
this._parameters[key] = value;
}
removeParameter (key) {
delete this._parameters[key];
}
set reference (value) {
const valid = validateString(value, `action ${this._name}`);
if (valid !== null) this._reference = valid;
}
get _base () {
return ['actionname', this._name];
}
_getLayer (data = {}) {
if (this._isMuted) return [];
if (this._mode !== ActionMode.IN) this._sentData.push(JSON.stringify(data));
const layer = this._base;
switch (this._mode) {
case ActionMode.IN:
case ActionMode.OUT:
layer.push('actionmode', this._mode);
break;
}
const labels = this._labels.slice(0, 5);
labels.length = 5;
if (labels.some(label => label)) layer.push('actionlabel', labels.map(label => typeof label === 'string' ? normalize(label) : '').join(','));
if (this._reference) layer.push('actionref', this._reference);
layer.push.apply(layer, getParametersLayer(Object.assign(this._parameters, data || {})));
return layer;
}
start (data) {
switch (this._status) {
case ActionStatus.UNSTARTED:
this._mode = ActionMode.IN;
this._status = ActionStatus.STARTED;
break;
case ActionStatus.SINGULAR:
this._mode = ActionMode.NONE;
this._status = ActionStatus.ENDED;
break;
default:
api.inspector.error(`unexpected start on action ${this._name} with status ${this._status.id}`);
return [];
}
return this._getLayer(data);
}
end (data) {
switch (this._status) {
case ActionStatus.STARTED:
this._mode = ActionMode.OUT;
this._status = ActionStatus.ENDED;
break;
case ActionStatus.UNSTARTED:
this._mode = ActionMode.NONE;
this._status = ActionStatus.ENDED;
break;
case ActionStatus.SINGULAR:
this._mode = ActionMode.NONE;
this._status = ActionStatus.ENDED;
break;
case ActionStatus.ENDED:
if (this._sentData.includes(JSON.stringify(data))) return [];
this._mode = ActionMode.NONE;
this._status = ActionStatus.ENDED;
break;
default:
return [];
}
return this._getLayer(data);
}
resume (data) {
if (this._isMuted) return [];
if (this._status.value >= ActionStatus.ENDED.value) {
api.inspector.error(`unexpected resuming on action ${this._name} with status ${this._status.id}`);
return [];
}
const layer = this._base;
if (data) layer.push.apply(layer, getParametersLayer(data));
return layer;
}
}
class Actions {
constructor () {
this._actions = [];
}
rewind () {
this._actions.forEach(action => action.rewind());
}
getAction (name) {
let action = this._actions.filter(action => action.name === name)[0];
if (!action) {
action = new Action(name);
this._actions.push(action);
}
return action;
}
hasAction (name) {
return this._actions.some(action => action.name === name);
}
remove (action) {
const index = this._actions.indexOf(action);
if (index === -1) return false;
this._actions.splice(index, 1);
return true;
}
}
Actions.ActionMode = ActionMode;
const actions = new Actions();
Actions.instance = actions;
class Location {
constructor (onRouteChange, isListeningHash = false) {
this._onRouteChange = onRouteChange;
this._isListeningHash = isListeningHash;
this._update();
renderer.add(this);
}
_update () {
this._pathname = document.location.pathname;
this._search = document.location.search;
this._hash = document.location.hash;
this._path = `${this._pathname}${this._search}`;
if (this._isListeningHash) this._path += this._hash;
this._hasTitle = this._title === document.title;
this._title = document.title;
}
render () {
if (this._pathname !== document.location.pathname || this._search !== document.location.search) this.change();
if (this._isListeningHash && this._hash !== document.location.hash) this.change();
}
change () {
this._referrer = this._path;
this._update();
this._onRouteChange();
}
get path () {
return this._path;
}
get hasTitle () {
return this._hasTitle;
}
get title () {
return this._title;
}
get referrer () {
return this._referrer;
}
}
const CollectorEvent = {
COLLECT: api.internals.ns.event('collect')
};
const ActioneeEmission = {
REWIND: api.internals.ns.emission('analytics', 'rewind')
};
class Collector {
constructor (config) {
switch (config.collection) {
case Collection.MANUAL:
case Collection.LOAD:
case Collection.FULL:
case Collection.HASH:
this._collection = config.collection;
break;
default:
/* deprecated start */
if (config.mode) {
switch (config.mode) {
case 'manual':
this._collection = config.collection;
break;
}
}
/* deprecated end */
switch (true) {
/* deprecated */
case config.mode === 'manual':
this._collection = Collection.MANUAL;
break;
case api.mode === api.Modes.ANGULAR:
case api.mode === api.Modes.REACT:
case api.mode === api.Modes.VUE:
this._collection = Collection.FULL;
break;
default:
this._collection = Collection.LOAD;
}
}
this._isActionEnabled = config.isActionEnabled === 'false' || config.isActionEnabled;
this._user = new User(config.user);
this._site = new Site(config.site);
this._page = new Page(config.page);
this._search = new Search(config.search);
this._funnel = new Funnel(config.funnel);
this._delay = -1;
queue.setCollector(this);
}
get page () {
return this._page;
}
get user () {
return this._user;
}
get site () {
return this._site;
}
get search () {
return this._search;
}
get funnel () {
return this._funnel;
}
start () {
const handleRouteChange = this._handleRouteChange.bind(this);
switch (this._collection) {
case Collection.LOAD:
this.collect();
break;
case Collection.FULL:
this.collect();
this._location = new Location(handleRouteChange);
break;
case Collection.HASH:
this.collect();
this._location = new Location(handleRouteChange, true);
break;
}
}
_handleRouteChange () {
queue.send(true);
this._delay = 6;
renderer.add(this);
}
render () {
this._delay--;
if (this._delay < 0) {
renderer.remove(this);
this._routeChanged();
}
}
_routeChanged () {
actions.rewind();
this._page.referrer = this._location.referrer;
if (this._location.hasTitle) this._page.title = this._location.title;
this._page.path = this._location.path;
const event = new CustomEvent(CollectorEvent.COLLECT);
document.documentElement.dispatchEvent(event);
this.collect();
if (api.internals && api.internals.stage && api.internals.stage.root) api.internals.stage.root.descend(ActioneeEmission.REWIND);
}
reset (clear = false) {
this._user.reset(clear);
this._site.reset(clear);
this._page.reset(clear);
this._search.reset(clear);
this._funnel.reset(clear);
}
collect () {
if (!this.page.collecting()) return;
queue.collect();
}
get collection () {
return this._collection;
}
get isCollecting () {
return this._page.isCollecting;
}
get isActionEnabled () {
return this._isActionEnabled;
}
set isActionEnabled (value) {
this._isActionEnabled = value;
}
get layer () {
return [
...this._user.layer,
...this._site.layer,
...this._page.layer,
...this._search.layer,
...this._funnel.layer
];
}
}
class Analytics {
constructor () {
this._isReady = false;
this._readiness = new Promise((resolve, reject) => {
if (this._isReady) resolve();
else {
this._resolve = resolve;
this._reject = reject;
}
});
this._configure();
}
_configure () {
switch (true) {
case window[patch.namespace] !== undefined:
this._config = window[patch.namespace].configuration.analytics;
window[patch.namespace].promise.then(this._build.bind(this), () => {});
break;
case api.internals !== undefined && api.internals.configuration !== undefined && api.internals.configuration.analytics !== undefined && api.internals.configuration.analytics.domain !== undefined:
this._config = api.internals.configuration.analytics;
this._build();
break;
case api.analytics !== undefined && api.analytics.domain !== undefined:
this._config = api.analytics;
this._build();
break;
default:
api.inspector.warn('analytics configuration is incorrect or missing (required : domain)');
}
}
_build () {
this._init = new Init(this._config.domain);
this._init.configure().then(this._start.bind(this), (reason) => this._reject(reason));
}
get isReady () {
return this._isReady;
}
get readiness () {
return this._readiness;
}
_start () {
if (this._isReady) return;
this._cmp = new ConsentManagerPlatform(this._config.cmp);
this._collector = new Collector(this._config);
this._collector.reset();
this._isReady = true;
this._resolve();
queue.start();
this._collector.start();
}
get page () {
return this._collector.page;
}
get user () {
return this._collector.user;
}
get site () {
return this._collector._site;
}
get search () {
return this._collector.search;
}
get funnel () {
return this._collector.funnel;
}
get cmp () {
return this._cmp;
}
get opt () {
return opt;
}
get collection () {
return this._collector.collection;
}
get isActionEnabled () {
return this._collector.isActionEnabled;
}
set isActionEnabled (value) {
this._collector.isActionEnabled = value;
}
get isDebugging () {
return debug.isActive;
}
set isDebugging (value) {
debug.isActive = value;
}
push (type, layer) {
push(type, layer);
}
reset (clear = false) {
this._collector.reset();
}
collect () {
this._collector.collect();
}
}
const analytics = new Analytics();
analytics.Collection = Collection;
analytics.PushType = PushType;
/**
* Copy properties from multiple sources including accessors.
* source : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#copier_des_accesseurs
*
* @param {object} [target] - Target object to copy into
* @param {...objects} [sources] - Multiple objects
* @return {object} A new object
*
* @example
*
* const obj1 = {
* key: 'value'
* };
* const obj2 = {
* get function01 () {
* return a-value;
* }
* set function01 () {
* return a-value;
* }
* };
* completeAssign(obj1, obj2)
*/
const completeAssign = (target, ...sources) => {
sources.forEach(source => {
const descriptors = Object.keys(source).reduce((descriptors, key) => {
descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
return descriptors;
}, {});
Object.getOwnPropertySymbols(source).forEach(sym => {
const descriptor = Object.getOwnPropertyDescriptor(source, sym);
if (descriptor.enumerable) {
descriptors[sym] = descriptor;
}
});
Object.defineProperties(target, descriptors);
});
return target;
};
api.analytics = completeAssign(analytics, {});
const Type$1 = {
// impression
IMPRESSION: {
id: 'impression', // element appeared in the page
isSingular: true,
isBeginning: true,
attributed: false,
type: 'impression'
},
// interaction
CLICK: {
id: 'click', // generic click interaction
isBeginning: true,
attributed: true,
type: 'interaction',
event: 'click',
method: 'eventListener'
},
INTERNAL: {
id: 'internal', // anchor click redirecting on an internal url
isBeginning: true,
attributed: true,
type: 'interaction',
event: 'click',
method: 'eventListener'
},
EXTERNAL: {
id: 'external', // anchor click redirecting on an external url
isBeginning: true,
attributed: true,
type: 'interaction',
event: 'click',
method: 'eventListener'
},
DOWNLOAD: {
id: 'download', // anchor click downloading a file
isBeginning: true,
attributed: true,
type: 'interaction',
event: 'click',
method: 'eventListener'
},
BUTTON: {
id: 'button', // button click
isBeginning: true,
attributed: true,
type: 'interaction',
event: 'click',
method: 'eventListener'
},
DOUBLE_CLICK: {
id: 'dblclick', // double click
isBeginning: true,
attributed: true,
type: 'interaction',
event: 'dblclick',
method: 'eventListener'
},
// event
OPEN: {
id: 'open', // open event
isSingular: true,
attributed: false,
type: 'event',
method: 'eventListener'
},
COMPLETE: {
id: 'complete', // complete event
isSingular: true,
attributed: false,
type: 'event',
method: 'eventListener'
},
FOCUS: {
id: 'focus', // focus event
isSingular: true,
attributed: false,
type: 'event',
method: 'eventListener'
},
ERROR: {
id: 'error', // error event
isSingular: true,
attributed: false,
type: 'event'
},
ADD: {
id: 'add', // add event
isSingular: true,
attributed: false,
type: 'event'
},
REMOVE: {
id: 'remove', // remove event
isSingular: true,
attributed: false,
type: 'event'
},
DISPLAY: {
id: 'display', // display event
isSingular: true,
attributed: false,
type: 'event'
},
CHANGE: {
id: 'change', // input event change
isSingular: true,
attributed: true,
type: 'event',
event: 'change',
method: 'change'
},
PROGRESS: {
id: 'progress', // video retention event with percent of the part reached
isBeginning: true,
attributed: true,
type: 'event'
},
// component interaction
SHARE: {
id: 'share', // component share click (share)
isBeginning: true,
attributed: false,
type: 'interaction'
},
PRESS: {
id: 'press', // component press click (pressable tag)
isBeginning: true,
attributed: false,
type: 'interaction'
},
RELEASE: {
id: 'release', // component release click (pressable tag)
isBeginning: true,
attributed: false,
type: 'interaction'
},
DISMISS: {
id: 'dismiss', // component dismiss click (dismissible tag)
isBeginning: true,
attributed: false,
type: 'interaction'
},
UPLOAD: {
id: 'upload', // component upload click (upload)
isBeginning: true,
attributed: false,
type: 'interaction'
},
CHECK: {
id: 'check', // component check click (checkbox, radio, toggle)
isBeginning: true,
attributed: false,
type: 'interaction'
},
UNCHECK: {
id: 'uncheck', // component uncheck click (checkbox, radio, toggle)
isBeginning: true,
attributed: false,
type: 'interaction'
},
SELECT: {
id: 'select', // component select change (select)
isBeginning: true,
attributed: false,
type: 'interaction'
},
SUBSCRIBE: {
id: 'subscribe', // component subscribe click (follow)
isBeginning: true,
attributed: false,
type: 'interaction'
},
// component event
DISCLOSE: {
id: 'disclose', // component disclose event (accordion, modal, tab)
isBeginning: true,
attributed: false,
type: 'event'
},
SEARCH: {
id: 'search', // component disclose event (accordion, modal, tab)
isBeginning: true,
attributed: false,
type: 'event'
},
SHOW: {
id: 'show', // component show event (tooltip)
isSingular: true,
attributed: false,
type: 'event'
},
HIDE: {
id: 'hide', // component hide event (tooltip)
isSingular: true,
attributed: false,
type: 'event'
},
// video
AUTOPLAY: {
id: 'autoplay', // video autoplay event
isBeginning: true,
attributed: false,
type: 'event'
},
PLAY: {
id: 'play', // video play click
isBeginning: true,
attributed: false,
type: 'interaction'
},
PAUSE: {
id: 'pause', // video pause click
isBeginning: true,
attributed: false,
type: 'interaction'
},
END: {
id: 'end', // video end event
isBeginning: true,
attributed: false,
type: 'event'
}
};
const Type = {
UNDEFINED: 'undefined',
HEADING: 'heading',
COMPONENT: 'component',
CONTENT: 'content'
};
const NODE_POSITION = Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINED_BY;
class Heading {
constructor (heading) {
this._label = heading.textContent.trim();
this._level = Number(heading.tagName.charAt(1));
}
get level () {
return this._level;
}
get label () {
return this._label;
}
}
class Member {
constructor (node, target, level) {
this._type = Type.UNDEFINED;
this._node = node;
this._target = target;
this._level = level;
this._label = '';
this._component = '';
this._isValid = true;
this.analyse();
}
_parseHeadings () {
const selector = Array.from({ length: this._level }, (v, i) => `h${i + 1}`).join(',');
this._headings = Array.from(this._node.querySelectorAll(selector)).filter(heading => heading === this._node || heading.parentNode === this._node || (heading.parentNode != null && heading.parentNode.parentNode === this._node)).filter(heading => (this._target.compareDocumentPosition(heading) & NODE_POSITION) > 0).map(heading => new Heading(heading)).reverse();
}
_getComponent () {
if (typeof api !== 'function') return false;
const element = api(this._node);
if (!element) return false;
const instance = Object.values(element).filter(actionee => actionee.isActionee).sort((a, b) => b.priority - a.priority)[0];
if (!instance) return false;
this._type = Type.COMPONENT;
this._isValid = instance.validate(this._target);
const selector = Array.from({ length: 6 }, (v, i) => `h${i + 1}`).join(',');
const top = Array.from(this._node.querySelectorAll(selector)).map(heading => new Heading(heading)).sort((a, b) => a.level - b.level)[0];
if (top && top.level <= this._level) this._level = top.level - 1;
const hx = this._node.closest(selector);
if (hx) {
const heading = new Heading(hx);
if (heading.level <= this._level) this._level = heading.level - 1;
}
if (!isNaN(instance.level) && instance.level < this._level) this._level = instance.level;
this._label = instance.label;
this._component = instance.component;
return true;
}
_getHeading () {
if (!this._headings.length) return false;
const labels = [];
this._headings.forEach(heading => {
if (heading.level <= this._level) {
if (heading.level > 1) labels.unshift(heading.label);
this._level = heading.level - 1;
}
});
if (!labels.length) return false;
this._type = Type.HEADING;
this._label = labels.join(' ');
return true;
}
analyse () {
this._parseHeadings();
if (this._getComponent()) return;
if (this._getHeading()) return;
if (this._node !== this._target) return;
const label = this._node.textContent.trim();
if (!label) return;
this._type = Type.CONTENT;
this._label = label;
}
get type () {
return this._type;
}
get level () {
return this._level;
}
get label () {
return this._label;
}
get component () {
return this._component;
}
get node () {
return this._node;
}
get target () {
return this._target;
}
get isValid () {
return this._isValid;
}
}
class Hierarchy {
constructor (node) {
this._node = node;
this._process();
}
_process () {
// console.log('_______________ start ____________________');
const member = new Member(this._node, this._node, 6);
// console.log('- FIRST MEMBER', member);
this._level = member.level;
this._members = [member];
let node = this._node.parentNode;
while (document.documentElement.contains(node) && node !== document.documentElement && this._level > 0) {
// console.log('MEMBERS ARRAY', this._members);
// console.log('NODE ANALYSIS', node);
const member = new Member(node, this._node, this._level);
// console.log('NEW MEMBER', member);
switch (true) {
case member.type === Type.UNDEFINED:
// console.log('****UNDEFINED');
break;
case !member.isValid:
// console.log('****INVALID');
break;
case member.label === this._members[0].label && member.type === Type.HEADING && this._members[0].type === Type.COMPONENT:
// console.log('***** SAME');
// do nothing
break;
case member.label === this._members[0].label && member.type === Type.COMPONENT && this._members[0].type === Type.HEADING:
// console.log('***** SAME INVERT');
this._members.splice(0, 1, member);
break;
default:
this._members.unshift(member);
if (member.level < this._level) this._level = member.level;
}
node = node.parentNode;
}
this._label = normalize(this._members[this._members.length - 1].label);
this._title = normalize(this._members.filter(member => member.label).map(member => member.label).join(' '));
const components = this._members.filter(member => member.component).map(member => member.component);
this._component = normalize(components.join(' '));
this._localComponent = components[components.length - 1];
this._globalComponent = components[0];
// console.log('========= end ===========');
}
get localComponent () {
return this._localComponent;
}
get globalComponent () {
return this._globalComponent;
}
get label () {
return this._label;
}
get title () {
return this._title;
}
get component () {
return this._component;
}
}
class ActionElement {
constructor (node, type, id, category = '', title = null, parameters = {}, isRating = false, isForced = false) {
this._node = node;
this._type = type;
this._id = id || this._node.id;
this._isMuted = false;
this._title = title;
this._category = category;
this._parameters = parameters;
this._isRating = isRating;
this._isForced = isForced;
this._hasBegun = false;
// this._init();
requestAnimationFrame(this._init.bind(this));
}
_init () {
this._hierarchy = new Hierarchy(this._node);
let id = '';
let type = '';
if (this._id) id = `_[${this._id}]`;
else api.inspector.warn(`Analytics API requires an id to be set on tracked element. Missing on ${this._node.outerHTML}`);
if (this._type) type = `(${this._type.id})_`;
this._name = `${type}${this._title || this._hierarchy.title}${id}`;
this._action = actions.getAction(this._name, this._type.status);
if (this._type.isSingular) this._action.singularize();
Object.keys(this._parameters).forEach(key => this._action.addParameter(key, this._parameters[key]));
this._action.isMuted = this._isMuted;
this._action.isForced = this._isForced;
this._action.labels[0] = this._type.id;
this._action.labels[1] = this._hierarchy.globalComponent;
this._action.labels[2] = this._hierarchy.localComponent;
this._action.labels[4] = this._category;
if (this._hierarchy.label) this._action.addParameter('component_label', this._hierarchy.label);
if (this._hierarchy.title) this._action.addParameter('heading_hierarchy', this._hierarchy.title);
if (this._hierarchy.component) this._action.addParameter('component_hierarchy', this._hierarchy.component);
this.begin();
}
get isMuted () {
return this._action ? this._action.isMuted : this._isMuted;
}
set isMuted (value) {
this._isMuted = value;
if (this._action) this._action.isMuted = value;
}
get action () {
return this._action;
}
rewind () {
this._hasBegun = false;
this.begin();
}
begin (data = {}) {
if (this._hasBegun) return;
this._hasBegun = true;
if (this._type.isBeginning && (this._type.isSingular || this._isRating)) queue.appendStartingAction(this._action, data);
}
act (data = {}) {
if (this._isMuted) return;
if (!this._action) {
requestAnimationFrame(() => this.act(data));
return;
}
queue.appendEndingAction(this._action, data);
}
dispose () {
actions.remove(this._action);
}
}
const ActionAttributes = {
RATING: api.internals.ns.attr('analytics-rating'),
ACTION: api.internals.ns.attr('analytics-action')
};
class Actionee extends api.core.Instance {
constructor (priority = -1, category = '', title = null, isForced = false) {
super();
this._type = null;
this._priority = priority;
this._category = category;
this._title = title;
this._parameters = {};
this._data = {};
this._isMuted = false;
this._isForced = isForced;
}
static get instanceClassName () {
return 'Actionee';
}
get proxy () {
const scope = this;
const proxy = {
validate: (target, members) => scope.validate(target, members)
};
const proxyAccessors = {
get isActionee () {
return true;
},
get label () {
return scope.label;
},
get priority () {
return scope.priority;
},
get level () {
return scope.level;
},
get node () {
return scope.node; // TODO: remove in v2
}
};
return api.internals.property.completeAssign(super.proxy, proxy, proxyAccessors);
}
get data () {
return this._data;
}
_config (element, registration) {
super._config(element, registration);
if (this._type === null) {
this._sort(element);
this._isMuted = true;
return;
}
this._actionElement = new ActionElement(this.node, this._type, this.id, this._category, this.getAttribute(ActionAttributes.ACTION) || this._title, this._parameters, this.hasAttribute(ActionAttributes.RATING), this.hasAttribute(ActionAttributes.ACTION) || this._isForced);
if (this._isMuted) this._actionElement.isMuted = true;
this.addDescent(ActioneeEmission.REWIND, this.rewind.bind(this));
this._sort(element);
}
_sort (element) {
const actionees = element.instances.filter(instance => instance.isActionee).sort((a, b) => b.priority - a.priority);
if (actionees.length <= 1) return;
actionees.forEach((actionee, index) => { actionee.isMuted = index > 0; });
}
get isMuted () {
return this._actionElement ? this._actionElement.isMuted : this._isMuted;
}
set isMuted (value) {
this._isMuted = value;
if (this._actionElement) this._actionElement.isMuted = value;
}
get priority () {
return this._priority;
}
setPriority (value) {
this._priority = value;
}
get isInteractive () {
return this.node.tagName === 'A' || this.node.tagName === 'BUTTON';
}
detectInteractionType (node) {
if (!node) node = this.node;
const tag = node.tagName;
const href = node.getAttribute('href');
const isDownload = node.hasAttribute('download');
const hostname = node.hostname;
switch (true) {
case tag !== 'A':
this._type = Type$1.CLICK;
break;
case isDownload:
this._type = Type$1.DOWNLOAD;
this.value = href;
break;
case hostname === location.hostname :
this._type = Type$1.INTERNAL;
this.value = href;
break;
case hostname.length > 0 :
this._type = Type$1.EXTERNAL;
this.value = href;
break;
default:
this._type = Type$1.CLICK;
break;
}
}
setClickType () {
this._type = Type$1.CLICK;
}
listenActionClick (target) {
if (target) {
this._clickTarget = target;
this._clickTarget.addEventListener('click', this._handlingClick, { capture: true });
} else this.listenClick({ capture: true });
}
handleClick () {
this.act();
}
setImpressionType () {
this._type = Type$1.IMPRESSION;
}
rewind () {
if (this._actionElement) this._actionElement.rewind();
}
act (data = {}) {
if (this._actionElement !== undefined) {
this._data.component_value = this.value;
this._actionElement.act(Object.assign(this._data, data));
}
}
getFirstText (node) {
if (!node) node = this.node;
if (node.childNodes && node.childNodes.length > 0) {
for (let i = 0; i < node.childNodes.length; i++) {
if (node.childNodes[i].nodeType === Node.TEXT_NODE) {
const text = node.childNodes[i].textContent.trim();
if (text) {
return this.cropText(text);
}
}
}
for (let i = 0; i < node.childNodes.length; i++) {
const text = this.getFirstText(node.childNodes[i]);
if (text) {
return this.cropText(text);
}
}
}
return '';
}
cropText (text, length = 50) {
return text.length > 50 ? `${text.substring(0, 50).trim()}[...]` : text;
}
getInteractionLabel () {
const title = this.getAttribute('title');
if (title) return this.cropText(title);
const text = this.getFirstText();
if (text) return text;
const img = this.node.querySelector('img');
if (img) {
const alt = img.getAttribute('alt');
if (alt) return this.cropText(alt);
}
return null;
}
getHeadingLabel (length = 6) {
const selector = Array.from({ length: length }, (v, i) => `h${i + 1}`).join(',');
const headings = Array.from(this.querySelectorAll(selector)).filter(heading => (this.node.compareDocumentPosition(heading) & Node.DOCUMENT_POSITION_CONTAINED_BY) > 0);
if (headings.length) {
for (const heading of headings) {
const text = this.getFirstText(heading);
if (text) return text;
}
}
}
detectLevel (node) {
if (!node) node = this.node;
const selector = Array.from({ length: 6 }, (v, i) => `h${i + 1}`).join(',');
const levels = Array.from(node.querySelectorAll(selector)).map(heading => Number(heading.tagName.charAt(1)));
if (levels.length) this._level = Math.min.apply(null, levels) - 1;
}
validate (target) {
return true;
}
get actionElement () {
return this._actionElement;
}
get label () {
return null;
}
get value () {
return this._value || this.label;
}
set value (value) {
this._value = value;
}
get isActionee () {
return true;
}
get level () {
return this._level;
}
get type () {
return this._type;
}
dispose () {
if (this._clickTarget) {
this._clickTarget.removeEventListener('click', this._handlingClick);
}
super.dispose();
}
}
class AttributeActionee extends Actionee {
constructor () {
super(100, '', null, true);
}
static get instanceClassName () {
return 'AttributeActionee';
}
init () {
this._attribute = this.registration.selector.replace(/[[\]]/g, '');
const id = this._attribute.split('-').pop();
this._type = Object.values(Type$1).filter(type => type.id === id)[0];
this._title = this.getAttribute(this._attribute);
if (this._type === Type$1.CLICK) this.detectInteractionType();
switch (this._type.method) {
case 'eventListener':
this.listen(this._type.event, this.handleEvent.bind(this));
break;
case 'change':
this.listen(this._type.event, this.handleChange.bind(this));
break;
}
}
handleEvent (e) {
this._actionElement.act();
}
handleChange (e) {
this._actionElement.act({ change_value: e.target.value });
}
dispose () {
this._actionElement.dispose();
super.dispose();
}
}
const integrateAttributes = () => {
Object.values(Type$1)
.filter(type => type.attributed)
.forEach(type => api.internals.register(api.internals.ns.attr.selector(`analytics-${type.id}`), AttributeActionee));
};
const ButtonEmission = {
CLICK: api.internals.ns.emission('button', 'click')
};
class ComponentActionee extends Actionee {
constructor (priority = -1) {
super(priority, 'dsfr_component');
}
static get instanceClassName () {
return 'ComponentActionee';
}
get proxy () {
const scope = this;
const proxyAccessors = {
get component () {
return scope.component;
}
};
return api.internals.property.completeAssign(super.proxy, proxyAccessors);
}
setDiscloseType () {
this._type = Type$1.DISCLOSE;
}
listenDisclose () {
this.listen(api.core.DisclosureEvent.DISCLOSE, this._handleDisclose.bind(this), { capture: true });
}
_handleDisclose () {
this.act();
}
setChangeType () {
this._type = Type$1.CHANGE;
}
listenChange () {
this.listen('change', this._handleChange.bind(this), { capture: true });
}
_handleChange (e) {
if (e.target && e.target.value) {
this.setChangeValue(e);
this.act();
}
}
setChangeValue (e) {
this.value = e.target.value;
}
listenInputValidation (node, type = Type$1.CLICK, isSendingInputValue = false) {
if (!node) node = this.node;
this._type = type;
this._isSendingInputValue = isSendingInputValue;
this.addAscent(ButtonEmission.CLICK, this._actValidatedInput.bind(this));
const button = this.element.getDescendantInstances('ButtonActionee', null, true)[0];
if (button) button.isMuted = true;
this._validatedInput = node.querySelector('input');
this._handlingInputValidation = this._handleInputValidation.bind(this);
if (this._validatedInput) this._validatedInput.addEventListener('keydown', this._handlingInputValidation);
}
_handleInputValidation (e) {
if (e.keyCode === 13) this._actValidatedInput();
}
_actValidatedInput () {
if (this._isActingValidatedInput) return;
this._isActingValidatedInput = true;
if (this._isSendingInputValue) this.value = this._validatedInput.value.trim();
this.act();
this.request(this._actedValidatedInput.bind(this));
}
_actedValidatedInput () {
this._isActingValidatedInput = false;
}
setCheckType () {
this._type = Type$1.CHECK;
}
detectCheckableType () {
const isChecked = this.node.checked;
this._type = isChecked ? Type$1.UNCHECK : Type$1.CHECK;
}
listenCheckable () {
this.listen('change', this._handleCheckable.bind(this), { capture: true });
}
_handleCheckable (e) {
if (e.target && e.target.value !== 'on') {
this.value = e.target.value;
}
switch (true) {
case this._type === Type$1.CHECK && e.target.checked:
case this._type === Type$1.UNCHECK && !e.target.checked:
this.act();
break;
}
}
detectPressableType () {
const isPressable = this.node.hasAttribute('aria-pressed');
if (isPressable) {
const isPressed = this.node.getAttribute('aria-pressed') === 'true';
this._type = isPressed ? Type$1.RELEASE : Type$1.PRESS;
}
return isPressable;
}
listenPressable () {
this.listen('click', this._handlePressable.bind(this), { capture: true });
}
_handlePressable (e) {
switch (true) {
case this._type === Type$1.PRESS && e.target.getAttribute('aria-pressed') === 'false':
case this._type === Type$1.RELEASE && e.target.getAttribute('aria-pressed') === 'true':
this.act();
break;
}
}
setDismissType () {
this._type = Type$1.DISMISS;
}
get component () {
return null;
}
dispose () {
if (this._validatedInput) {
this._validatedInput.removeEventListener('keydown', this._handlingInputValidation);
}
super.dispose();
}
}
const AccordionSelector = {
ACCORDION: api.internals.ns.selector('accordion'),
TITLE: api.internals.ns.selector('accordion__title')
};
const ID$x = 'accordion';
class AccordionButtonActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'AccordionButtonActionee';
}
init () {
this.isMuted = true;
}
get button () {
return this.element.getInstance('CollapseButton');
}
get label () {
const firstText = this.getFirstText();
if (firstText) return firstText;
return 'bouton d\'accordéon';
}
get component () {
return ID$x;
}
}
class AccordionActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'AccordionActionee';
}
init () {
this.setDiscloseType();
this.wrapper = this.node.closest(AccordionSelector.ACCORDION);
this.detectLevel(this.wrapper);
this.register(`[aria-controls="${this.id}"]`, AccordionButtonActionee);
this.listenDisclose();
}
get label () {
if (this.wrapper) {
const title = this.wrapper.querySelector(AccordionSelector.TITLE);
if (title) {
const text = this.getFirstText(title);
if (text) return text;
}
}
const instance = this.element.getInstance('Collapse');
if (instance) {
const button = instance.buttons.filter(button => button.isPrimary)[0];
if (button) {
const text = this.getFirstText(button);
if (text) return text;
}
}
return 'accordéon';
}
get component () {
return ID$x;
}
dispose () {
super.dispose();
}
}
const integrateAccordion = () => {
if (api.accordion) {
api.internals.register(api.accordion.AccordionSelector.COLLAPSE, AccordionActionee);
}
};
const AlertSelector = {
ALERT: api.internals.ns.selector('alert'),
TITLE: api.internals.ns.selector('alert__title')
};
const ID$w = 'alert';
class AlertActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'AlertActionee';
}
get label () {
const alertTitle = this.node.querySelector(AlertSelector.TITLE);
if (alertTitle) {
const text = this.getFirstText(alertTitle);
if (text) return text;
}
return 'alerte';
}
get component () {
return ID$w;
}
}
const integrateAlert = () => {
api.internals.register(AlertSelector.ALERT, AlertActionee);
};
const BreadcrumbSelector = {
LINK: `${api.internals.ns.selector('breadcrumb__link')}:not([aria-current])`,
COLLAPSE: `${api.internals.ns.selector('breadcrumb')} ${api.internals.ns.selector('collapse')}`
};
const ID$v = 'breadcrumb';
class BreadcrumbActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'BreadcrumbActionee';
}
get label () {
return 'fil d\'ariane';
}
get component () {
return ID$v;
}
}
class BreadcrumbLinkActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'BreadcrumbLinkActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
handleClick () {
this.act();
}
get label () {
const firstText = this.getFirstText();
if (firstText) return firstText;
return 'lien fil d\'ariane';
}
get component () {
return null;
}
}
const integrateBreadcrumb = () => {
if (api.breadcrumb) {
api.internals.register(BreadcrumbSelector.COLLAPSE, BreadcrumbActionee);
api.internals.register(BreadcrumbSelector.LINK, BreadcrumbLinkActionee);
}
};
const ButtonSelector = {
BUTTON: `${api.internals.ns.selector('btn')}:not(${api.internals.ns.selector('btn--close')})`
};
const ID$u = 'button';
class ButtonActionee extends ComponentActionee {
constructor () {
super(1);
this._data = {};
}
static get instanceClassName () {
return 'ButtonActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
handleClick () {
this.ascend(ButtonEmission.CLICK);
this.act();
}
get label () {
if (this.node.tagName === 'input') {
switch (this.node.type) {
case 'button':
case 'submit':
if (this.hasAttribute('value')) return this.getAttribute('value');
}
}
const firstText = this.getFirstText();
if (firstText) return firstText;
return 'bouton';
}
get component () {
return ID$u;
}
}
const integrateButton = () => {
api.internals.register(ButtonSelector.BUTTON, ButtonActionee);
};
const CalloutSelector = {
CALLOUT: api.internals.ns.selector('callout'),
TITLE: api.internals.ns.selector('callout__title')
};
const ID$t = 'callout';
class CalloutActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'CalloutActionee';
}
get label () {
const calloutTitle = this.node.querySelector(CalloutSelector.TITLE);
if (calloutTitle) {
const text = this.getFirstText(calloutTitle);
if (text) return text;
}
return 'mise en avant';
}
get component () {
return ID$t;
}
}
const integrateCallout = () => {
api.internals.register(CalloutSelector.CALLOUT, CalloutActionee);
};
const CardSelector = {
CARD: api.internals.ns.selector('card'),
LINK: `${api.internals.ns.selector('card__title')} a, ${api.internals.ns.selector('card__title')} button`,
TITLE: api.internals.ns.selector('card__title')
};
const ID$s = 'card';
class CardActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'CardActionee';
}
init () {
const link = this.node.querySelector(CardSelector.LINK);
if (link) {
this.link = link;
this.detectInteractionType(link);
this.listenActionClick(link);
}
}
get label () {
const cardTitle = this.node.querySelector(CardSelector.TITLE);
if (cardTitle) {
const text = this.getFirstText(cardTitle);
if (text) return text;
}
const heading = this.getHeadingLabel();
if (heading) return heading;
return 'carte';
}
get component () {
return ID$s;
}
}
const integrateCard = () => {
api.internals.register(CardSelector.CARD, CardActionee);
};
const CheckboxSelector = {
INPUT: api.internals.ns.selector('checkbox-group [type="checkbox"]')
};
const ID$r = 'checkbox';
class CheckboxActionee extends ComponentActionee {
constructor () {
super(1);
this._data = {};
}
static get instanceClassName () {
return 'CheckboxActionee';
}
init () {
this.detectCheckableType();
this.listenCheckable();
}
get label () {
const label = this.node.parentNode.querySelector(api.internals.ns.selector('label'));
if (label) {
const text = this.getFirstText(label);
if (text) return text;
}
return 'case à cocher';
}
get component () {
return ID$r;
}
}
const integrateCheckbox = () => {
api.internals.register(CheckboxSelector.INPUT, CheckboxActionee);
};
const ConnectSelector = {
CONNECT: api.internals.ns.selector('connect'),
LINK: api.internals.ns.selector('connect + * a, connect + a')
};
const ID$q = 'connect';
class ConnectActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'ConnectActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
get label () {
if (this.node.classList.contains('fr-connect--plus')) return 'FranceConnect+';
return 'FranceConnect';
}
get component () {
return ID$q;
}
}
class ConnectLinkActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'ConnectLinkActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
get label () {
return this.getFirstText() || 'qu\'est-ce que FranceConnect ?';
}
get component () {
return ID$q;
}
}
const integrateConnect = () => {
api.internals.register(ConnectSelector.CONNECT, ConnectActionee);
api.internals.register(ConnectSelector.LINK, ConnectLinkActionee);
};
const ConsentSelector = {
BANNER: api.internals.ns.selector('consent-banner')
};
const ID$p = 'consent';
class ConsentActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'ConsentActionee';
}
get label () {
return 'gestionnaire de consentement';
}
get component () {
return ID$p;
}
}
const integrateConsent = () => {
api.internals.register(ConsentSelector.BANNER, ConsentActionee);
};
const DownloadSelector = {
LINK: api.internals.ns.selector('download__link')
};
const ID$o = 'download';
class DownloadActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'DownloadActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
get label () {
const text = this.getFirstText();
if (text) return text;
return 'téléchargement';
}
get component () {
return ID$o;
}
}
const integrateDownload = () => {
api.internals.register(DownloadSelector.LINK, DownloadActionee);
};
const FollowSelector = {
FOLLOW: api.internals.ns.selector('follow'),
NEWSLETTER_INPUT_GROUP: api.internals.ns.selector('follow__newsletter') + ' ' + api.internals.ns.selector('input-group')
};
const ID$n = 'follow';
class FollowActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'FollowActionee';
}
init () {
this._inputGroup = this.querySelector(FollowSelector.NEWSLETTER_INPUT_GROUP);
if (this._inputGroup) {
this.listenInputValidation(this._inputGroup, Type$1.SUBSCRIBE);
const input = this.element.getDescendantInstances('InputActionee', null, true)[0];
if (input) input.isMuted = true;
}
}
get label () {
return 'lettre d\'information et réseaux sociaux';
}
get component () {
return ID$n;
}
}
const integrateFollow = () => {
api.internals.register(FollowSelector.FOLLOW, FollowActionee);
};
const FooterSelector = {
FOOTER: api.internals.ns.selector('footer'),
FOOTER_LINKS: `${api.internals.ns.selector('footer')} a[href], ${api.internals.ns.selector('footer')} button`
};
const ID$m = 'footer';
class FooterActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'FooterActionee';
}
get label () {
return 'pied de page';
}
get component () {
return ID$m;
}
}
class FooterLinkActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'FooterLinkActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
get label () {
const label = this.getInteractionLabel();
if (label) return label;
return 'lien pied de page';
}
}
const integrateFooter = () => {
api.internals.register(FooterSelector.FOOTER, FooterActionee);
api.internals.register(FooterSelector.FOOTER_LINKS, FooterLinkActionee);
};
const ID$l = 'header';
class HeaderActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'HeaderActionee';
}
get label () {
return 'en-tête';
}
get component () {
return ID$l;
}
}
class HeaderModalButtonActionee extends ComponentActionee {
constructor () {
super(4);
}
static get instanceClassName () {
return 'HeaderModalButtonActionee';
}
}
class HeaderModalActionee extends ComponentActionee {
constructor () {
super(0);
}
static get instanceClassName () {
return 'HeaderModalActionee';
}
init () {
if (this.isBreakpoint(api.core.Breakpoints.LG)) {
this.setPriority(4);
this.register(`[aria-controls="${this.id}"]`, HeaderModalButtonActionee);
}
}
}
const HeaderSelector = {
TOOLS_BUTTON: `${api.internals.ns.selector('header__tools-links')} ${api.internals.ns.selector('btns-group')} ${api.internals.ns.selector('btn')}`,
MENU_BUTTON: `${api.internals.ns.selector('header__menu-links')} ${api.internals.ns.selector('btns-group')} ${api.internals.ns.selector('btn')}`
};
class HeaderToolsButtonActionee extends ComponentActionee {
constructor () {
super(4);
}
static get instanceClassName () {
return 'HeaderToolsButtonActionee';
}
init () {
if (this.isBreakpoint(api.core.Breakpoints.LG)) this._priority = -1;
}
}
class HeaderMenuButtonActionee extends ComponentActionee {
static get instanceClassName () {
return 'HeaderMenuButtonActionee';
}
init () {
if (this.isBreakpoint(api.core.Breakpoints.LG)) this.setPriority(4);
}
}
const integrateHeader = () => {
if (api.header) {
api.internals.register(api.header.HeaderSelector.HEADER, HeaderActionee);
api.internals.register(api.header.HeaderSelector.MODALS, HeaderModalActionee);
api.internals.register(HeaderSelector.TOOLS_BUTTON, HeaderToolsButtonActionee);
api.internals.register(HeaderSelector.MENU_BUTTON, HeaderMenuButtonActionee);
}
};
const HighlightSelector = {
HIGHLIGHT: api.internals.ns.selector('highlight')
};
const ID$k = 'highlight';
class HighlightActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'HighlightActionee';
}
get label () {
return 'mise en exergue';
}
get component () {
return ID$k;
}
}
const integrateHighlight = () => {
api.internals.register(HighlightSelector.HIGHLIGHT, HighlightActionee);
};
const LinkSelector = {
LINK: api.internals.ns.selector('link')
};
const ID$j = 'link';
class LinkActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'LinkActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
get label () {
const firstText = this.getFirstText();
if (firstText) return firstText;
return 'lien';
}
get component () {
return ID$j;
}
}
const integrateLink = () => {
api.internals.register(LinkSelector.LINK, LinkActionee);
};
const InputSelector = {
INPUT: api.internals.ns.selector('input-group')
};
const ID$i = 'input';
class InputActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'InputActionee';
}
init () {
this._input = this.querySelector(api.internals.ns.selector('input'));
this._label = this.querySelector(api.internals.ns.selector('label'));
this._inputWrap = this.querySelector(api.internals.ns.selector('input-wrap'));
if (this._inputWrap) this.listenInputValidation(this._inputWrap);
}
get label () {
if (this._label) {
const text = this.getFirstText(this._label);
if (text) return text;
}
return 'champ de saisie';
}
get component () {
return ID$i;
}
}
const integrateInput = () => {
api.internals.register(InputSelector.INPUT, InputActionee);
};
const ModalSelector = {
TITLE: api.internals.ns.selector('modal__title')
};
const ID$h = 'modal';
class ModalActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'ModalActionee';
}
init () {
this.setDiscloseType();
this.detectLevel();
this.listenDisclose();
}
get label () {
const title = this.node.querySelector(ModalSelector.TITLE);
if (title) {
const text = this.getFirstText(title);
if (text) return text;
}
const heading = this.getHeadingLabel(2);
if (heading) return heading;
const instance = this.element.getInstance('Modal');
if (instance) {
const button = instance.buttons.filter(button => button.isPrimary)[0];
if (button) {
const text = this.getFirstText(button.node);
if (text) return text;
}
}
return 'modale';
}
get component () {
return ID$h;
}
}
const integrateModal = () => {
if (api.modal) {
api.internals.register(api.modal.ModalSelector.MODAL, ModalActionee);
}
};
class NavigationActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'NavigationActionee';
}
get label () {
return 'navigation';
}
}
const NavigationSelector = {
LINK: api.internals.ns.selector('nav__link'),
BUTTON: api.internals.ns.selector('nav__btn')
};
const ID$g = 'navigation';
class NavigationLinkActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'NavigationLinkActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
get label () {
const firstText = this.getFirstText();
if (firstText) return firstText;
return 'lien de navigation';
}
get component () {
return ID$g;
}
}
class NavigationSectionActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'NavigationSectionActionee';
}
init () {
this._wrapper = this.node.closest(api.navigation.NavigationSelector.ITEM);
}
get label () {
if (this._wrapper) {
const button = this._wrapper.querySelector(NavigationSelector.BUTTON);
if (button) {
const text = this.getFirstText(button);
if (text) return text;
}
}
const instance = this.element.getInstance('Collapse');
if (instance) {
const button = instance.buttons.filter(button => button.isPrimary)[0];
if (button) {
const text = this.getFirstText(button);
if (text) return text;
}
}
return 'section de navigation';
}
}
const integrateNavigation = () => {
if (api.navigation) {
api.internals.register(api.navigation.NavigationSelector.NAVIGATION, NavigationActionee);
api.internals.register(NavigationSelector.LINK, NavigationLinkActionee);
api.internals.register(api.navigation.NavigationSelector.COLLAPSE, NavigationSectionActionee);
}
};
const PaginationSelector = {
PAGINATION: api.internals.ns.selector('pagination'),
LINK: api.internals.ns.selector('pagination__link'),
NEXT_LINK: api.internals.ns.selector('pagination__link--next'),
LAST_LINK: api.internals.ns.selector('pagination__link--last'),
ANALYTICS_TOTAL: api.internals.ns.attr('analytics-page-total'),
CURRENT: '[aria-current="page"]'
};
const ID$f = 'pagination';
class PaginationActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'PaginationActionee';
}
init () {
this.setPagination();
}
get label () {
return 'pagination';
}
get component () {
return ID$f;
}
setPagination () {
const currentLink = this.node.querySelector(PaginationSelector.CURRENT);
if (!currentLink) return;
const currentLabel = this.getFirstText(currentLink);
if (!currentLabel) return;
const current = this.getInt(currentLabel);
if (isNaN(current)) return;
api.analytics.page.current = current;
const total = this.getTotalPage();
if (isNaN(total)) return;
api.analytics.page.total = total;
}
getTotalPage () {
const attr = parseInt(this.node.getAttribute(PaginationSelector.ANALYTICS_TOTAL));
if (!isNaN(attr)) return attr;
const links = this.node.querySelectorAll(`${PaginationSelector.LINK}:not(${PaginationSelector.NEXT_LINK}):not(${PaginationSelector.LAST_LINK})`);
if (!links) return null;
const totalLabel = this.getFirstText(links[links.length - 1]);
if (!totalLabel) return null;
return this.getInt(totalLabel);
}
getInt (val) {
const ints = val.match(/\d+/);
if (!ints || ints.length === 0) return null;
return parseInt(ints[0]);
}
}
class PaginationLinkActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'PaginationLinkActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
get label () {
const firstText = this.getFirstText();
if (firstText) return firstText;
return 'lien pagination';
}
get component () {
return null;
}
}
const integratePagination = () => {
api.internals.register(PaginationSelector.PAGINATION, PaginationActionee);
api.internals.register(PaginationSelector.LINK, PaginationLinkActionee);
};
const QuoteSelector = {
QUOTE: api.internals.ns.selector('quote')
};
const ID$e = 'quote';
class QuoteActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'QuoteActionee';
}
get label () {
const blockquote = this.node.querySelector('blockquote');
if (blockquote) {
const firstText = this.getFirstText(blockquote);
if (firstText) {
return firstText;
}
}
return 'citation';
}
get component () {
return ID$e;
}
}
const integrateQuote = () => {
api.internals.register(QuoteSelector.QUOTE, QuoteActionee);
};
const RadioSelector = {
INPUT: api.internals.ns.selector('radio-group [type="radio"]')
};
const FormSelector = {
LABEL: api.internals.ns.selector('label'),
FIELDSET: api.internals.ns.selector('fieldset'),
LEGEND: api.internals.ns.selector('fieldset__legend')
};
const ID$d = 'radio';
class RadioActionee extends ComponentActionee {
constructor () {
super(1);
this._data = {};
}
static get instanceClassName () {
return 'RadioActionee';
}
init () {
this.setCheckType();
this.listenCheckable();
}
get label () {
const parts = [];
const fieldset = this.node.closest(FormSelector.FIELDSET);
if (fieldset) {
const legend = fieldset.querySelector(FormSelector.LEGEND);
if (legend) {
const firstTextLegend = this.getFirstText(legend);
if (firstTextLegend) parts.push(firstTextLegend);
}
}
const label = this.node.parentNode.querySelector(api.internals.ns.selector('label'));
if (label) {
const firstTextLabel = this.getFirstText(label);
if (firstTextLabel) parts.push(firstTextLabel);
}
return parts.join(' ');
}
get component () {
return ID$d;
}
}
const integrateRadio = () => {
api.internals.register(RadioSelector.INPUT, RadioActionee);
};
const SearchSelector = {
SEARCH_BAR: api.internals.ns.selector('search-bar')
};
const ID$c = 'search';
class SearchActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'SearchActionee';
}
init () {
this.listenInputValidation(this.node, Type$1.SEARCH, true);
}
get label () {
return 'barre de recherche';
}
get component () {
return ID$c;
}
}
const integrateSearch = () => {
api.internals.register(SearchSelector.SEARCH_BAR, SearchActionee);
};
const SelectSelector = {
SELECT: api.internals.ns.selector('select')
};
const ID$b = 'select';
class SelectActionee extends ComponentActionee {
constructor () {
super(1);
this._data = {};
}
static get instanceClassName () {
return 'SelectActionee';
}
init () {
this.setChangeType();
this.listenChange();
}
setChangeValue (e) {
if (!e.target || !e.target.selectedOptions) return;
const value = Array.from(e.target.selectedOptions).map(option => option.text).join(' - ');
if (value) this.value = value;
}
get label () {
const label = this.node.parentNode.querySelector(api.internals.ns.selector('label'));
if (label) {
const firstText = this.getFirstText(label);
if (firstText) return firstText;
}
return 'liste déroulante';
}
get component () {
return ID$b;
}
}
const integrateSelect = () => {
api.internals.register(SelectSelector.SELECT, SelectActionee);
};
const ShareSelector = {
SHARE: api.internals.ns.selector('share'),
TITLE: api.internals.ns.selector('share__title')
};
const ID$a = 'share';
class ShareActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'ShareActionee';
}
get label () {
const title = this.querySelector(ShareSelector.TITLE);
if (title) {
const firstText = this.getFirstText(title);
if (firstText) return firstText;
}
return 'boutons de partage';
}
get component () {
return ID$a;
}
}
const integrateShare = () => {
api.internals.register(ShareSelector.SHARE, ShareActionee);
};
const SidemenuSelector = {
SIDEMENU: api.internals.ns.selector('sidemenu'),
ITEM: api.internals.ns.selector('sidemenu__item'),
LINK: api.internals.ns.selector('sidemenu__link'),
BUTTON: api.internals.ns.selector('sidemenu__btn'),
TITLE: api.internals.ns.selector('sidemenu__title')
};
class SidemenuActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'SidemenuActionee';
}
get label () {
const sidemenu = this.node.closest(SidemenuSelector.SIDEMENU);
if (sidemenu) {
const title = sidemenu.querySelector(SidemenuSelector.TITLE);
if (title) {
const firstText = this.getFirstText(title);
if (firstText) return firstText;
}
}
return 'menu Latéral';
}
}
const ID$9 = 'sidemenu';
class SidemenuLinkActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'SidemenuLinkActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
get label () {
const firstText = this.getFirstText();
if (firstText) return firstText;
return 'lien menu latéral';
}
get component () {
return ID$9;
}
}
class SidemenuSectionActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'SidemenuSectionActionee';
}
init () {
this._wrapper = this.node.closest(SidemenuSelector.ITEM);
}
get label () {
if (this._wrapper) {
const button = this._wrapper.querySelector(SidemenuSelector.BUTTON);
if (button) {
const firstText = this.getFirstText(button);
if (firstText) return firstText;
}
}
const instance = this.element.getInstance('Collapse');
if (instance) {
const button = instance.buttons.filter(button => button.isPrimary)[0];
if (button) {
const firstTextBtn = this.getFirstText(button);
if (firstTextBtn) return firstTextBtn;
}
}
return 'section menu latéral';
}
}
const integrateSidemenu = () => {
if (api.sidemenu) {
api.internals.register(SidemenuSelector.SIDEMENU, SidemenuActionee);
api.internals.register(SidemenuSelector.LINK, SidemenuLinkActionee);
api.internals.register(api.sidemenu.SidemenuSelector.COLLAPSE, SidemenuSectionActionee);
}
};
const SummarySelector = {
SUMMARY: api.internals.ns.selector('summary'),
LINK: api.internals.ns.selector('summary__link'),
TITLE: api.internals.ns.selector('summary__title'),
ITEM: `${api.internals.ns.selector('summary')} li`
};
class SummaryActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'SummaryActionee';
}
get label () {
const title = this.node.querySelector(SummarySelector.TITLE);
if (title) {
const firstText = this.getFirstText(title);
if (firstText) return firstText;
}
return 'sommaire';
}
}
const ID$8 = 'summary';
class SummaryLinkActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'SummaryLinkActionee';
}
init () {
this.detectInteractionType();
this.listenActionClick();
}
get label () {
const firstText = this.getFirstText();
if (firstText) return firstText;
return 'lien sommaire';
}
get component () {
return ID$8;
}
}
class SummarySectionActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'SummarySectionActionee';
}
init () {
this._link = this.querySelector(SummarySelector.LINK);
}
validate (target) {
return this._link !== target;
}
get label () {
if (!this._link) return null;
const firstText = this.getFirstText(this._link);
if (firstText) return firstText;
return 'section sommaire';
}
}
const integrateSummary = () => {
api.internals.register(SummarySelector.SUMMARY, SummaryActionee);
api.internals.register(SummarySelector.LINK, SummaryLinkActionee);
api.internals.register(SummarySelector.ITEM, SummarySectionActionee);
};
const ID$7 = 'tab';
class TabButtonActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'TabButtonActionee';
}
init () {
this.isMuted = true;
}
get label () {
const text = this.getFirstText();
if (text) return text;
return 'bouton onglet';
}
get component () {
return ID$7;
}
}
class TabActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'TabActionee';
}
init () {
this.setDiscloseType();
this.register(`[aria-controls="${this.id}"]`, TabButtonActionee);
this._instance = this.element.getInstance('TabPanel');
this.listenDisclose();
}
get label () {
const tabs = this.node.closest(api.tab.TabSelector.GROUP);
if (tabs) {
const tab = tabs.querySelector(`${api.tab.TabSelector.LIST} [aria-controls="${this.id}"]${api.tab.TabSelector.TAB}`);
if (tab) {
const firstTextTab = this.getFirstText(tab);
if (firstTextTab) return firstTextTab;
}
}
const button = this._instance.buttons.filter(button => button.isPrimary)[0];
if (button) {
const firstTextBtn = this.getFirstText(button);
if (firstTextBtn) return firstTextBtn;
}
return 'onglet';
}
get component () {
return ID$7;
}
}
const integrateTab = () => {
if (api.tab) {
api.internals.register(api.tab.TabSelector.PANEL, TabActionee);
}
};
const TableSelector = {
TABLE: api.internals.ns.selector('table')
};
const ID$6 = 'table';
class TableActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'TableActionee';
}
get label () {
const caption = this.node.querySelector('caption');
if (caption) {
const firstText = this.getFirstText(caption);
if (firstText) return firstText;
}
return 'tableau';
}
get component () {
return ID$6;
}
}
const integrateTable = () => {
api.internals.register(TableSelector.TABLE, TableActionee);
};
const TagSelector = {
TAG: api.internals.ns.selector('tag'),
PRESSABLE: '[aria-pressed]',
DISMISSIBLE: `${api.internals.ns.selector('tag--dismiss', '')}`
};
const ID$5 = 'tag';
class TagActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'TagActionee';
}
init () {
switch (true) {
case this.detectPressableType():
this.listenPressable();
break;
case this.isInteractive && this.node.classList.contains(TagSelector.DISMISSIBLE):
this.setDismissType();
this.listenActionClick();
break;
case this.isInteractive:
this.detectInteractionType();
this.listenActionClick();
break;
}
}
get label () {
const firstText = this.getFirstText();
if (firstText) return firstText;
return 'tag';
}
get component () {
return ID$5;
}
}
const integrateTag = () => {
api.internals.register(TagSelector.TAG, TagActionee);
};
const TileSelector = {
TILE: api.internals.ns.selector('tile'),
LINK: `${api.internals.ns.selector('tile__title')} a, ${api.internals.ns.selector('tile__title')} button`,
TITLE: api.internals.ns.selector('tile__title')
};
const ID$4 = 'tile';
class TileActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'TileActionee';
}
init () {
const link = this.node.querySelector(TileSelector.LINK);
if (link) {
this.link = link;
this.detectInteractionType(link);
this.listenActionClick(link);
}
}
get label () {
const tileTitle = this.node.querySelector(TileSelector.TITLE);
if (tileTitle) return this.getFirstText(tileTitle);
const heading = this.getHeadingLabel();
if (heading) return heading;
return 'tuile';
}
get component () {
return ID$4;
}
}
const integrateTile = () => {
api.internals.register(TileSelector.TILE, TileActionee);
};
const ToggleSelector = {
INPUT: api.internals.ns.selector('toggle [type="checkbox"]')
};
const ID$3 = 'toggle';
class ToggleActionee extends ComponentActionee {
constructor () {
super(1);
this._data = {};
}
static get instanceClassName () {
return 'ToggleActionee';
}
init () {
this.detectCheckableType();
this.listenCheckable();
}
get label () {
const label = this.node.parentNode.querySelector(api.internals.ns.selector('toggle__label'));
if (label) {
const firstText = this.getFirstText(label);
if (firstText) return firstText;
}
return 'interrupteur';
}
get component () {
return ID$3;
}
}
const integrateToggle = () => {
api.internals.register(ToggleSelector.INPUT, ToggleActionee);
};
const TRANSCRIPTION = api.internals.ns.selector('transcription');
const COLLAPSE$1 = api.internals.ns.selector('collapse');
const TranscriptionSelector = {
TRANSCRIPTION: TRANSCRIPTION,
COLLAPSE: `${TRANSCRIPTION} > ${COLLAPSE$1}, ${TRANSCRIPTION} > *:not(${TRANSCRIPTION}):not(${COLLAPSE$1}) > ${COLLAPSE$1}, ${TRANSCRIPTION} > *:not(${TRANSCRIPTION}):not(${COLLAPSE$1}) > *:not(${TRANSCRIPTION}):not(${COLLAPSE$1}) > ${COLLAPSE$1}`,
COLLAPSE_LEGACY: `${TRANSCRIPTION} ${COLLAPSE$1}`,
TITLE: `${TRANSCRIPTION}__title`
};
const ID$2 = 'transcription';
class TranscriptionButtonActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'TranscriptionButtonActionee';
}
init () {
this.isMuted = true;
}
get button () {
return this.element.getInstance('CollapseButton');
}
get label () {
const text = this.getFirstText();
if (text) return text;
return 'bouton transcription';
}
get component () {
return ID$2;
}
}
class TranscriptionActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'TranscriptionActionee';
}
init () {
this.setDiscloseType();
this.wrapper = this.node.closest(TranscriptionSelector.ACCORDION);
this.detectLevel(this.wrapper);
this.register(`[aria-controls="${this.id}"]`, TranscriptionButtonActionee);
this.listenDisclose();
}
get label () {
if (this.wrapper) {
const title = this.wrapper.querySelector(TranscriptionSelector.TITLE);
if (title) {
const firstTextTitle = this.getFirstText(title);
if (firstTextTitle) return firstTextTitle;
}
}
const instance = this.element.getInstance('Collapse');
if (instance) {
const button = instance.buttons.filter(button => button.isPrimary)[0];
if (button) {
const firstTextBtn = this.getFirstText(button);
if (firstTextBtn) return firstTextBtn;
}
}
return 'transcription';
}
get component () {
return ID$2;
}
}
const integrateTranscription = () => {
api.internals.register(TranscriptionSelector.COLLAPSE, TranscriptionActionee);
};
const TRANSLATE = api.internals.ns.selector('translate');
const COLLAPSE = api.internals.ns.selector('collapse');
const TranslateSelector = {
BUTTON: `${TRANSLATE}__btn`,
COLLAPSE: `${TRANSLATE} > ${COLLAPSE}, ${TRANSLATE} > *:not(${TRANSLATE}):not(${COLLAPSE}) > ${COLLAPSE}, ${TRANSLATE} > *:not(${TRANSLATE}):not(${COLLAPSE}) > *:not(${TRANSLATE}):not(${COLLAPSE}) > ${COLLAPSE}`,
COLLAPSE_LEGACY: `${TRANSLATE} ${COLLAPSE}`
};
const ID$1 = 'translate';
class TranslateActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'TranslateActionee';
}
get label () {
const button = this.node.querySelector(TranslateSelector.BUTTON);
if (button) {
const title = button.getAttribute('title');
if (title) return title;
}
return 'sélecteur de langue';
}
get component () {
return ID$1;
}
}
class TranslateButtonActionee extends ComponentActionee {
constructor () {
super(2);
}
static get instanceClassName () {
return 'TranslateButtonActionee';
}
init () {
this.isMuted = true;
}
get button () {
return this.element.getInstance('CollapseButton');
}
get label () {
const label = this.getInteractionLabel();
if (label) return label;
return 'bouton sélecteur de langue';
}
get component () {
return ID$1;
}
}
const integrateTranslate = () => {
api.internals.register(TranslateSelector.COLLAPSE, TranslateActionee);
api.internals.register(TranslateSelector.BUTTON, TranslateButtonActionee);
};
const UploadSelector = {
UPLOAD: api.internals.ns.selector('upload')
};
const ID = 'upload';
class UploadActionee extends ComponentActionee {
constructor () {
super(1);
}
static get instanceClassName () {
return 'UploadActionee';
}
init () {
this.setChangeType();
this._label = this.node.parentNode.querySelector(api.internals.ns.selector('label'));
this.listenChange();
}
setChangeValue (e) {
if (!e.target || !e.target.files) return;
const value = Array.from(e.target.files).map(file => /(?:\.([^.]+))?$/.exec(file.name)[1]).filter((name, index, array) => array.indexOf(name) === index).join(' - ');
if (value) this.value = value;
}
get label () {
if (this._label) {
const text = this.getFirstText(this._label);
if (text) return text;
}
return 'ajout de fichier';
}
get component () {
return ID;
}
}
const integrateUpload = () => {
api.internals.register(UploadSelector.UPLOAD, UploadActionee);
};
const integrateComponents = () => {
integrateAccordion();
integrateBreadcrumb();
integrateAlert();
// integrateBadge();
integrateButton();
integrateCallout();
integrateConnect();
integrateConsent();
// integrateContent();
integrateCard();
integrateInput();
integrateCheckbox();
integrateDownload();
integrateFooter();
integrateFollow();
integrateHeader();
integrateHighlight();
integrateLink();
integrateModal();
integrateNavigation();
// integrateNotice();
integratePagination();
integrateQuote();
integrateRadio();
integrateSearch();
integrateSelect();
integrateShare();
integrateSidemenu();
// integrateStepper();
integrateSummary();
integrateTab();
integrateTable();
integrateTag();
integrateTile();
integrateToggle();
// integrateTooltip();
integrateTranscription();
integrateTranslate();
integrateUpload();
};
// import './core/core';
const integration = () => {
integrateAttributes();
integrateComponents();
};
api.analytics.readiness.then(() => integration(), () => {});
//# sourceMappingURL=analytics.module.js.map