{"version":3,"file":"bundle.js","sources":["../../../src/refactoring/js/dropdown-menu.js","../../../src/refactoring/js/eng-main-navigation.js","../../../src/refactoring/js/eng-keyboard-navigation.js","../../../src/refactoring/js/eng-search.js","../../../src/refactoring/js/eng-sticky-navigation.js","../../../src/refactoring/js/eng-expand-collapse.js","../../../src/refactoring/js/eng-timeline-filter.js","../../../src/refactoring/js/eng-newshub.js","../../../src/refactoring/js/eng-footer.js","../../../src/refactoring/js/_main.js"],"sourcesContent":["/* eslint-env browser */\n/**\n *\n * Mini Dropdown menu\n * \n
\n
\n \n \n
\n
\n *\n * Original by T.M.K\n * Adaptation by Edwin Joassart\n */\n\nclass Dropdown {\n constructor(dropdownButtonElement) {\n this.buttonElement = dropdownButtonElement;\n this.menuElement =\n dropdownButtonElement.closest('div').querySelector('.menu-content') || // for simple dropdown\n dropdownButtonElement\n .closest('.menuWrapper')\n .querySelector('.menu-content'); // for complex one like `other website`s\n\n this.buttonElement.addEventListener('click', this.toggleMenu.bind(this));\n\n // reference to document click event listener (exists only if dropdown is open, so we don't polute document)\n this.clickOutsideEventListener = null;\n }\n\n /**\n * Click event handler\n * Open dropdown\n */\n openMenu() {\n this.buttonElement.setAttribute('aria-expanded', 'true');\n this.menuElement.classList.remove('no-display');\n this.menuElement.classList.remove('invisible');\n this.menuElement.style.display = 'block';\n this.menuElement.setAttribute('aria-expanded', 'true');\n\n // add document click eventListener\n this.clickOutsideEventListener = this.closeMenuFromOutsideClick.bind(this);\n document.addEventListener('click', this.clickOutsideEventListener);\n }\n\n /**\n * Click event handler\n * Close dropdown\n */\n closeMenu() {\n this.buttonElement.setAttribute('aria-expanded', 'false');\n this.menuElement.classList.add('no-display');\n this.menuElement.style.display = 'none';\n this.menuElement.setAttribute('aria-expanded', 'false');\n\n // clear document click eventListener\n document.removeEventListener('click', this.clickOutsideEventListener);\n }\n\n /**\n * Click event handler\n * Close menu if click happens outside the dropdown\n */\n closeMenuFromOutsideClick(event_) {\n if (!event_.target.closest('.dropdown')) this.closeMenu.bind(this)();\n }\n\n /**\n * Click event handler\n * Tooggle menu open/close\n */\n toggleMenu(event_) {\n event_.preventDefault();\n if (this.menuElement.classList.contains('no-display'))\n this.openMenu.bind(this)();\n else this.closeMenu.bind(this)();\n }\n\n static init() {\n document\n .querySelectorAll('#dropdown, .dropdownBtn')\n .forEach((dropdown) => new Dropdown(dropdown));\n\n console.info('Dropdown : 1.0');\n }\n}\n\nexport default Dropdown;\n","/* \n * Europarl ENG Main Navigation\n *\n * This support the opening and closing in the header menu section of the ENG Europarl websbite \n * - Main Navigation\n * - Other Websites\n * - Main Navigation in \"compact\" mode\n * - Other Websites in \"compact\" mode\n * \n * The navigation dropdown are built using the \":focus-within\" css pseudo class\n *\n * Principle is unusual but works great : \n * - a div contains the menu element (hidden) and the link to open it (visible)\n * - when any children of the div have the focus, the pseudo-class is active and \n * the menu dropdown is visible\n * - when the focus is released or placed elsewhere, the menu is closed\n * \n * - Clicking / Taping on an element place the focus on it, as does tabbing to it.\n * - Clicking / Taping elsewhere or tabbing out if it remove the focus from the element.\n * - Moving the focus to another element within the same _focus-within container_ \n * keeps it active (thus open/visible)\n * \n * Main issue with this approach are :\n * - Clicking/Tapping multiple times on an element doesn't toggle the focus \n * (its added on first tap then don't change) -> no way to close the menu by taping again\n * - Simply removing the focus on an element with Javascript while enough to close an element is\n * problematic when there is submenu (as the parent will close as well).\n * Workaround is to move the focus passed that element to an anchor point injected after it \n * (which is still in the parent focus-within scope).\n *\n * DOM structure :\n \n\n\n * \n * Javascript will:\n * - Target all `.navigationFocusWithin` div\n * - Attach a listener to the focus-within pseudo class to track opening / close\n * - Set and toggle aria-expended accordingly\n * - Improve keyboard navigation\n * - Move a \"current\" class on the currently open menu element ?\n *\n * Notes : Using the resting anchor is prefered to simple \"blur of focus\" (which would work in simpler scenarios) \n * because of the submenu. Blurring would close main menu when closing sub ones.\n * If it becomes an issue, we'll have to complexify a little bit and when closing a submenu, \n * move the focus on the upper level header link, which might seems weird as well...\n * \n * \n * @author Edwin Joassart \n * @copyright Europarl (c) 2021\n * \n */\nclass ENGMainNavigation {\n constructor(menuElement) {\n if (!menuElement) {\n return;\n }\n\n // get elments\n this.menuElement = menuElement;\n this.button = document.querySelector('.menu-icon');\n\n // inject resting anchor after the menu element\n this.focusRestingAnchor = document.createElement('a');\n this.focusRestingAnchor.classList.add('focusRestingAnchor');\n this.focusRestingAnchor.setAttribute('tabindex', '-1');\n this.focusRestingAnchor.setAttribute('aria-hidden', 'true');\n\n // if part of a list we need to put the anchor into a list element\n if (this.menuElement.tagName === 'LI') {\n this.focusRestingContainer = document.createElement('li');\n this.focusRestingContainer.classList.add('level-0');\n this.focusRestingContainer.classList.add('resting'); // ie11 doesn't support more than 1 class per add\n this.focusRestingContainer.height = 0;\n this.focusRestingContainer.width = 0;\n // this.focusRestingContainer.style =\n // 'height: 0px; width: 0px; color: transparent';\n this.focusRestingContainer.setAttribute('tabindex', '-1');\n this.focusRestingContainer.setAttribute('aria-hidden', 'true');\n this.focusRestingContainer.appendChild(this.focusRestingAnchor); // eslint-disable-line unicorn/prefer-dom-node-append\n this.menuElement.after(this.focusRestingContainer);\n } else {\n this.menuElement.after(this.focusRestingAnchor);\n }\n\n // get the menu opening link (it's the first one)\n this.link = menuElement.querySelector('a');\n\n // are we the otherwebsite link ?\n this.isOtherWebsite = this.link.closest('ul')?.id === 'other-website-menu';\n //handle other websites link in bigger dimension\n this.otherWebsitesLink = this.link.id === 'otherWebsitesLink'\n \n // add aria-expended to the link\n this.link.setAttribute('aria-expanded', 'false');\n\n // attach listener to the link to track status\n\n /* WORKAROUND : we had to decouple `mousedown` and `mouseup` from `click` \n and add this weird delegated event flag.\n\n Click event fire only if mousedown is followed by mouseup on the *same* element\n As in compact mode menu is acting as a accordion (by CSS) and browser apply CSS on mousedown,\n in some edgecase we miss the mouseup and so miss the click entirely.\n\n To avoid that, we need to use mousedown, but it creates another issue where browser will\n refocus the element on mouseup. So we can't close the menu with js (as closing means we \n programatically move the focus away from the element)\n\n So workaround is to defer moving the focus, by raising a flag `shouldMoveFocusOnClickRelease` on `mousedown`\n and move the focus on `mouseup`.\n */\n\n // track clicks\n document.addEventListener(\n 'mousedown',\n this.documentClickEventHandler.bind(this)\n );\n\n document.addEventListener(\n 'mouseup',\n this.linkClickReleaseEventHandler.bind(this)\n );\n\n this.shouldMoveFocusOnClickRelease = false;\n\n // Attach hover event handler\n if (!document.querySelector('.nav-top')?.contains(this.link)) {\n //Mouse focus\n menuElement.addEventListener('mouseenter', this.focusOnHover.bind(this));\n menuElement.addEventListener('mouseleave', this.blurOnLeave.bind(this));\n }\n }\n\n focusOnHover(_event) {\n if (\n this.button &&\n window.getComputedStyle(this.button).display !== 'none'\n ) {\n return;\n }\n\n this.linkOpen();\n this.link.focus();\n }\n\n blurOnLeave(_event) {\n if (\n this.button &&\n window.getComputedStyle(this.button).display !== 'none'\n ) {\n return;\n }\n\n this.linkClose({ noBlur: true });\n\n // move focus to next element if we're in a list (usefull when there's a second level)\n if (\n _event.target.classList.contains('level-1') &&\n _event.target.nextSibling\n ) {\n _event.target.nextSibling.querySelector('a').focus();\n return;\n }\n\n document.activeElement.blur();\n }\n\n linkOpen() {\n // css will handle opening for us\n this.link.setAttribute('aria-expanded', 'true');\n\n // add the grey background on the link and the list and remove from all others\n // unless we're on the compact menu button\n for (const element of document.querySelectorAll('.backgrey')) {\n element.classList.remove('backgrey');\n }\n\n if (!this.link.classList.contains('menu-icon')) {\n this.link.classList.add('backgrey');\n this.menuElement.querySelector('ul')?.classList.add('backgrey');\n }\n\n if (\n this.link.classList.contains('menu-icon') &&\n document.querySelector('.back-overlay')\n ) {\n document.querySelector('.back-overlay').style.display = 'block';\n }\n\n // add active class on link\n this.link.classList.add('active');\n }\n\n linkClose(options) {\n this.link.setAttribute('aria-expanded', 'false');\n\n // remove the grey backgroun and active on the link and the list\n this.link.classList.remove('backgrey');\n\n // remove class active\n this.link.classList.remove('active');\n\n if (\n this.link.classList.contains('menu-icon') &&\n document.querySelector('.back-overlay')\n ) {\n document.querySelector('.back-overlay').style.display = 'none';\n }\n\n // defer focus setting to mouseup event handler (cf notes in constructor)\n if (!options?.noBlur) {\n this.shouldMoveFocusOnClickRelease = true;\n }\n }\n\n // /** move focus on mouseup if flag is set (cf notes in constructor) */\n linkClickReleaseEventHandler(_event) {\n // _event.preventDefault() //prevent mouseup to put back the focus on the element\n if (!this.shouldMoveFocusOnClickRelease) {\n return;\n }\n\n this.focusRestingAnchor.focus();\n this.shouldMoveFocusOnClickRelease = false;\n }\n\n /**\n * open / close for compact menu\n * nb : main menu is opened/closed with hover\n */\n documentClickEventHandler(_event) {\n // only act if compact mode\n if (\n this.button &&\n window.getComputedStyle(this.button).display === 'none' &&\n !this.isOtherWebsite && !this.otherWebsitesLink\n ) {\n return;\n }\n\n // open/close when clicking a link\n if (\n _event.target.closest('a') === this.link ||\n _event.target === this.link\n ) {\n if (this.link.getAttribute('aria-expanded') === 'true') {\n // open -> close\n this.linkClose();\n return;\n }\n\n // close -> open\n this.linkOpen();\n return;\n }\n\n // close on \"click outside\" unless it's a parent of clicked link\n // aka \"close everything else\"\n if (\n !this.link.closest('li, nav').contains(_event.target) &&\n this.link.getAttribute('aria-expanded') === 'true'\n ) {\n this.linkClose({ noBlur: true });\n }\n }\n\n static init() {\n // load for compact other websites\n for (const element of document.querySelectorAll('div.menu-container')) {\n // eslint-disable-next-line no-new\n new ENGMainNavigation(element);\n }\n\n // load for all menu dropdown content (both other webistes and main nav)\n for (const element of document.querySelectorAll('li.has-menu-dropdown')) {\n // eslint-disable-next-line no-new\n new ENGMainNavigation(element);\n }\n\n console.info('ENG Main Navigation : 0.6');\n }\n}\n\nexport default ENGMainNavigation;\n","/**\n * Handles keyboard navigation on the main nav\n *\n * We follow recommandation from\n * https://developer.mozilla.org/en-US/docs/Web/Accessibility/Keyboard-navigable_JavaScript_widgets\n *\n * Currently we :\n * - only track key up, down, left, right\n * - only act on main navigation\n *\n * TODO :\n * - track [ESC] and close menu\n */\n\nexport default class ENGKeyboardNav {\n constructor(mainNav) {\n this.mainNav = mainNav;\n\n if (!mainNav) return;\n\n // attach keyDownEventHandler on mainNav\n this.mainNav.addEventListener(\n 'keydown',\n this.handleKeyDownEvent.bind(this)\n );\n\n // setup accessibility attributes on links (set every link to tabindex -1) except level0\n this.mainNav.querySelectorAll('a').forEach((linkElement) => {\n if (linkElement.classList.contains('menu-icon')) return;\n\n const menuItem = linkElement.closest('li'); // Get the closest
  • parent\n if (!menuItem) return;\n\n const hasSubmenu = menuItem.querySelector('ul');\n if (!hasSubmenu) {\n // Remove aria-haspopup and aria-expanded if not submenu\n linkElement.removeAttribute('aria-haspopup');\n menuItem.classList.remove('has-menu-dropdown');\n if (!menuItem.classList.contains('resting')) {\n linkElement.setAttribute('tabindex', '0');\n } \n }\n\n this.releaseLink(linkElement);\n });\n\n this.mainList = Array.from(\n this.mainNav.querySelectorAll('ul.menu-level-0 > li:not(.resting)')\n );\n }\n\n /**\n * Release link\n * Set tabIndex = -1 (if not a top level link, or not moving to a top level)\n * Removes `active` class\n */\n releaseLink(linkElement) {\n const target =\n linkElement.tagName === 'A'\n ? linkElement\n : linkElement.querySelector('a');\n\n if (!target) return; // we didn't found a link to target\n\n // if (shouldResetTabindex && target.getAttribute('aria-haspopup') !== 'true')\n if (!target.closest('li')?.classList?.contains('level-0'))\n target.setAttribute('tabindex', -1);\n\n target.classList.remove('active');\n\n if(target.getAttribute('aria-haspopup') === 'true')\n target.setAttribute('aria-expanded', 'false');\n }\n\n /**\n * Focus link\n * Add `active class\n * Set tabIndex = 0\n * Set Focus\n * If link is TopLevel, focus on the first link in the dropdown list\n */\n focusLink(linkElement) {\n //Change attribute 'aria-expanded' to 'true'\n const focusParentMenuEntry = (closestLi) => {\n if (closestLi && closestLi.querySelector('ul')) {\n setTimeout(() => {\n const _linkElement = closestLi?.tagName === 'A' ? closestLi : closestLi?.querySelector('a');\n _linkElement?.setAttribute('aria-expanded', 'true');\n }, 0);\n }\n\n if (!closestLi) return;\n\n const classList = closestLi?.classList ?? [];\n const level = classList.contains('level-0') ? 0\n : classList.contains('level-1') ? 1\n : classList.contains('level-2') ? 2\n : classList.contains('level-3') ? 3 : null;\n\n if (!level || level === 0) return;\n\n const closestParent = closestLi.closest(`li.level-${level - 1}`);\n\n focusParentMenuEntry(closestParent);\n };\n\n // get the link inside if target is not a link (i.e. targeting a li or span containing the link of interest)\n const target =\n linkElement?.tagName === 'A'\n ? linkElement\n : linkElement?.querySelector('a');\n\n if (!target) return; // we didn't found a link to target\n\n // target.setAttribute('tabindex', '0');\n target.classList.add('active');\n target.focus({ preventScroll: true });\n\n const menuEntry = target.closest('li');\n focusParentMenuEntry(menuEntry);\n }\n\n /** Handle KeyDown Event */\n handleKeyDownEvent(_event) {\n // continues only for tab, esc, up, down, left and right keypress\n const allowedKeys = [9, 27, 37, 38, 39, 40];\n if (!allowedKeys.includes(_event.keyCode)) return;\n\n switch (_event.keyCode) {\n case 9:\n if (_event.shiftKey)\n this.processLeft.bind(this)(_event);\n else\n this.processRight.bind(this)(_event);\n break;\n\n case 27:\n this.processEsc.bind(this)();\n break;\n\n case 37:\n this.processLeft.bind(this)();\n break;\n\n case 38:\n this.processUp.bind(this)();\n break;\n\n case 39:\n this.processRight.bind(this)();\n break;\n\n case 40:\n this.processDown.bind(this)();\n break;\n }\n\n // prevent default so we don't scroll\n _event.preventDefault();\n }\n\n /** Process ESC Keypress */\n processEsc() {\n document\n .querySelectorAll('nav a[aria-expanded=true]')\n .forEach((element) => {\n element.classList.remove('active');\n element.setAttribute('aria-expanded', 'false');\n });\n document.querySelector('.back-overlay')?.classList.remove('display');\n document.activeElement.blur();\n }\n\n /** Process Down Keypress */\n processDown() {\n const previouslyActive = document.activeElement;\n\n if (\n document.activeElement.getAttribute('aria-haspopup') &&\n !document.activeElement.nextElementSibling\n )\n return; // we're at the end\n\n const level =\n document.activeElement.closest('li').classList.contains('level-1') ||\n document.activeElement.closest('li').classList.contains('level-0')\n ? 'level-1'\n : 'level-2';\n\n // if we're on the toplevel link, the list is below\n const menuList = document.activeElement\n .closest('li')\n .classList.contains('level-0')\n ? Array.from(\n // list li of the next ul\n document.activeElement.nextElementSibling.querySelectorAll(\n `li.${level}:not(.resting) > a`\n )\n )\n : Array.from(\n // list li of the parent ul\n document.activeElement\n .closest('ul')\n .querySelectorAll(`li.${level}:not(.resting) > a`)\n );\n\n const previousPosition = menuList.indexOf(document.activeElement);\n\n // are we at the end of menu?\n if (previousPosition === menuList.length - 1) {\n // and in a level-2 ?\n if (document.activeElement.closest('li').classList.contains('level-2')) {\n // yes go back to upper level and down\n this.focusLink(\n document.activeElement\n ?.closest('ul')\n ?.closest('li')\n ?.nextElementSibling?.nextElementSibling?.querySelector('a')\n );\n this.releaseLink(previouslyActive, true);\n } else {\n this.processRight(); // no go to next tab\n }\n\n return;\n }\n\n // if we're outside list (toplevel link), we need to go to the first element of the list\n const targetActive =\n menuList[previousPosition < 0 ? 0 : previousPosition + 1];\n\n this.focusLink(targetActive);\n this.releaseLink(previouslyActive, true);\n }\n\n /** Process Up Keypress */\n processUp() {\n const previouslyActive = document.activeElement;\n\n // if we're on the toplevel link, the list is below\n\n // if (!document.activeElement.closest('li').classList.contains('level-0')) {\n // this.processLeft({ end: true });\n // return;\n // }\n\n const level =\n document.activeElement.closest('li').classList.contains('level-1') ||\n document.activeElement.closest('li').classList.contains('level-0')\n ? 'level-1'\n : 'level-2';\n\n const menuList = Array.from(\n // list li of the parent ul\n document.activeElement.closest('ul').querySelectorAll(`li.${level}`)\n );\n\n const previousPosition = menuList.indexOf(\n document.activeElement.closest('li')\n );\n\n // we're outside or at the first position, can't go up so let's go left (to the end)\n if (previousPosition <= 0) {\n this.processLeft({ end: true }); // comment this line to prevent jumping to previous tab\n return;\n }\n\n const targetActive = menuList[previousPosition - 1];\n\n this.focusLink(targetActive.querySelector('a'));\n this.releaseLink(previouslyActive, true);\n }\n\n /**\n * Process Left Keypress\n * Move to previous top level menu element (if there's none do nothing)\n * Target the element with a tabindex=0 inside the menu, if none, target first element\n * */\n processLeft(_event) {\n let previouslyActive = document.activeElement;\n\n // if we're at level 2, get back on level 1\n if (previouslyActive.closest('li').classList.contains('level-2')) {\n this.focusLink(previouslyActive.closest('li.level-1').querySelector('a'));\n this.releaseLink(previouslyActive, true);\n return;\n }\n\n // if we're in the menu dropdown instead of topLevel link, get the corresponding toplevel link\n previouslyActive = document.activeElement.closest('li.level-0');\n const previousPosition = this.mainList.indexOf(previouslyActive);\n\n if (previousPosition === 0) {\n if (_event.keyCode === 9 && _event.shiftKey) {\n this.releaseLink(previouslyActive, true);\n this.processEsc();\n // Focus on previous element outside the menu bar\n const prevElm = document.querySelector('.toolbar.toolbar_bottom')?.previousElementSibling;\n const focusableElems = prevElm.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n const toBeFocusedElem = focusableElems[focusableElems.length - 1];\n toBeFocusedElem?.focus();\n }\n return; // We're at first position, can't go left\n }\n\n const targetActive = this.mainList[previousPosition - 1];\n\n this.focusLink(targetActive);\n this.releaseLink(previouslyActive, true);\n }\n\n /**\n * Process Right Keypress\n * Move to next top level menu element (if there's none do nothing)\n * Target the element with a tabindex=0 inside the menu, if none, target first element\n * */\n processRight(_event) {\n let previouslyActive = document.activeElement;\n\n // if on a level-1 with children go deeper\n if (\n document.activeElement.getAttribute('aria-haspopup') === 'true' &&\n !document.activeElement.closest('li').classList.contains('level-0')\n ) {\n this.focusLink(\n document.activeElement.nextElementSibling.querySelector('a')\n );\n this.releaseLink(previouslyActive, true);\n return;\n }\n\n // if we're in the menu dropdown instead of topLevel link, get the corresponding toplevel link (previous element is the related link)\n previouslyActive = document.activeElement.closest('li.level-0');\n const previousPosition = this.mainList.indexOf(previouslyActive);\n\n if (previousPosition === this.mainList.length - 1) {\n if (_event.keyCode === 9) {\n this.releaseLink(previouslyActive, true);\n this.processEsc();\n // Focus on next element outside the menu bar\n const nextElm = document.querySelector('.toolbar.toolbar_bottom')?.nextElementSibling;\n const focusableElems = nextElm.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n const toBeFocusedElem = focusableElems[0];\n toBeFocusedElem?.focus();\n }\n return; // We're at the end, can't go further\n }\n\n const targetActive = this.mainList[previousPosition + 1];\n\n this.focusLink(targetActive);\n this.releaseLink(previouslyActive, true);\n }\n\n static init() {\n // we currently only target the main navigation\n new ENGKeyboardNav(document.querySelector('nav.nav-main'));\n\n console.info('ENG keyboard navigation : 0.2');\n }\n}\n","/**\n * ENG Search Management\n *\n * Augment search behaviour in ENG-News\n *\n * This script replace functionalities previously found in behaviour.js\n *\n * This class currently so simple we kept it static\n *\n * TODO:\n * - [ ] close search when click outside\n *\n * @author Edwin Joassart \n * @copyright European Parliament 2021 All rights reserved\n */\n\nexport default class ENGSearch {\n static onSearchFieldChange(_event, searchButtonElement) {\n if (_event.target?.value.length > 0) {\n // field contains something so activate the button\n searchButtonElement.removeAttribute('disabled');\n return;\n }\n\n // field does not contains anything, deactivate the button\n searchButtonElement.setAttribute('disabled', 'true');\n }\n\n static toggleMobileSearch(_event, searchFormElement) {\n if (searchFormElement.classList.contains('posinit')) {\n // open\n const link = _event.target.closest('.search-icon');\n link.classList.add('active');\n link.setAttribute('aria-expanded', true);\n searchFormElement.classList.remove('posinit');\n\n // focus in newly opened form input\n searchFormElement.querySelector('input').focus();\n\n // attach document click event to close\n document.addEventListener(\n 'click',\n ENGSearch.closeOnClickOutsideEventHandler\n );\n\n return;\n }\n\n // close\n ENGSearch.closeSearch();\n }\n\n /** close on click outside */\n static closeOnClickOutsideEventHandler(_event) {\n if (_event.target.closest('a.search-icon')) return; // prevent opening\n\n if (!document.querySelector('#search').contains(_event.target))\n ENGSearch.closeSearch();\n }\n\n /** Close search on esc keypress */\n static escKeyPressEventListner(_event) {\n if (_event.keyCode !== 27) return; // we only tracking the [esc] key\n ENGSearch.closeSearch();\n }\n\n /** toggle mobile on spacebar keypress */\n static spacebarKeyPressEventListner(_event, searchFormElement) {\n if (_event.keyCode !== 32) return; // only tracking [spacebar] keyCode\n ENGSearch.toggleMobileSearch(_event, searchFormElement);\n }\n\n static closeSearch() {\n const link = document.querySelector('.search-icon');\n link.classList.remove('active');\n link.setAttribute('aria-expanded', false);\n\n document.querySelector('form#search').classList.add('posinit');\n\n // detach click outside eventHandler\n document.removeEventListener(\n 'click',\n ENGSearch.closeOnClickOutsideEventHandler\n );\n }\n\n static init() {\n // locate search elements\n const searchFieldElement = document.querySelector('#search-field');\n const searchMobileIcon = document.querySelector('a.search-icon');\n const searchButtonElement = document.querySelector('form#search button');\n const searchFormElement = document.querySelector('form#search');\n\n if (!searchFormElement) return;\n\n // attach event handlers to search input\n searchFieldElement.addEventListener('keyup', (_event) =>\n ENGSearch.onSearchFieldChange(_event, searchButtonElement)\n );\n\n // attach event handler to mobile icon\n searchMobileIcon.addEventListener('click', (_event) =>\n ENGSearch.toggleMobileSearch(_event, searchFormElement)\n );\n\n // add .posinit to #search in order to hide search form when js is active\n document.querySelector('#search').classList.add('posinit');\n\n // attach event handler to close search on [esc] key press\n document.addEventListener('keydown', ENGSearch.escKeyPressEventListner);\n\n // attach event handler to open search on spacebar press on compact view\n searchMobileIcon.addEventListener('keydown', (_event) =>\n ENGSearch.spacebarKeyPressEventListner(_event, searchFormElement)\n );\n\n console.info('ENG Search : 0.3');\n }\n}\n","/**\n * ENG Sticky Navigation\n *\n * The main header is a sticky header, meaning on scoll it will \"stick\" to the top of the screen.\n * When it happens, main nav will act in a compact mode (hamburger menu)\n * with a small dropdown on desktop / tablet and full height menu on mobile\n *\n * http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport\n *\n * @author Edwin Joassart \n * @copyright European Parliament 2021 All rights reserved\n *\n */\n\nexport default class ENGFixedHeader {\n constructor({ trackerSelector, targetSelector }) {\n // get elements\n this.tracker = document.querySelector(trackerSelector);\n this.target = document.querySelector(targetSelector);\n this.hamburger = document.querySelector('.menu-icon');\n this.backdrop = document.querySelector('.back-overlay');\n this.menuLevel0 = document.querySelector('nav.nav-main .menu-level-0');\n\n if (!this.tracker || !this.target) return;\n\n // attach scroll event handler to document\n document.addEventListener('scroll', this.scrollEventHandler.bind(this));\n\n // attach click evnet handler on hamburger menu to force-scroll to the top when it is clicked\n if (this.hamburger)\n this.hamburger.addEventListener(\n 'click',\n this.scrollToTopAndAddBackdrop.bind(this)\n );\n\n // check a first time\n this.scrollEventHandler();\n\n // pre-compute usefull values\n const { top: targetTop, height: targetHeight } =\n this.target.getBoundingClientRect();\n const { top: trackerTop } = this.tracker.getBoundingClientRect();\n\n this.trackerTreshold = trackerTop - targetTop; // used to decide if we need to stick\n this.targetHeight = targetHeight; // use to offset the removal of the target from the flow (prevent page jump)\n\n this.trackerTop = trackerTop; // use to force stick\n\n // test once to catch page which are already scrolled down (ie: following a link to some part of the content)\n this.scrollEventHandler.bind(this)();\n }\n\n /** scroll view so menu stick */\n scrollToTopAndAddBackdrop(_event) {\n // add backdrop and if in mobile view set menu to full-height\n if (this.hamburger.getAttribute('aria-expanded') === 'true') {\n this.backdrop?.classList.add('display');\n\n /* set menu to full height (only for smaller breakpoints)\n this should only apply on smaller breakpoint, so css override \n this on bigger breakpoints with :\n ```\n height: auto !important;\n max-height: inherit !important;\n ```\n this prevent hardcoding the breakpoint here\n */\n const { height } = this.target.getBoundingClientRect();\n this.menuLevel0.style.height = `${window.innerHeight - height}px`;\n this.menuLevel0.style.maxHeight = `${window.innerHeight - height}px`;\n } else {\n this.backdrop?.classList?.remove('display');\n\n // reset height to default\n this.menuLevel0.style.height = '';\n this.menuLevel0.style.maxHeight = '';\n }\n\n if (!this.target.classList.contains('sticking'))\n window.scrollTo(0, this.trackerTop - 1);\n }\n\n /** on scroll, check position of the navbar */\n scrollEventHandler(_event) {\n const { top } = this.tracker.getBoundingClientRect();\n if (top < this.trackerTreshold) this.stick();\n else this.unstick();\n\n // prevent scroll if menu is open\n // (NOTE : I hate to do this but it's needed to stay coherent with previous implementation)\n // FIXME : BAD UX!!\n // If expanded & on mobile style (sticking)\n if (this.hamburger?.getAttribute('aria-expanded') === 'true' && this.target.classList.contains('sticking')) {\n if (!this.offset) this.offset = window.pageYOffset;\n window.scrollTo(0, this.offset);\n } else this.offset = null;\n }\n\n /** stick (if not sticking) */\n stick() {\n if (!this.target.classList.contains('sticking')) {\n this.target.classList.add('sticking');\n\n // prevent page jump\n this.tracker.style.paddingTop = `${\n Number(this.tracker.style.paddingTop) + this.targetHeight\n }px`;\n }\n }\n\n /** unstick (if sticking) */\n unstick() {\n if (this.target.classList.contains('sticking')) {\n this.target.classList.remove('sticking');\n\n // revert page jump prevention\n this.tracker.style.paddingTop = '';\n }\n }\n\n static init() {\n const trackerSelector = '#website-body'; // select which element you want to track\n const targetSelector = '.sticky'; // add a \"sticking\" class to this element when the tracker is out of the viewport\n\n new ENGFixedHeader({ targetSelector, trackerSelector }); // eslint-disable-line no-new\n\n // prevent default on all links without target url (href=\"#\") (this might be too much)\n document\n .querySelectorAll('a[href=\"#\"]')\n .forEach((link) =>\n link.addEventListener('click', (_event) => _event.preventDefault())\n );\n\n console.info('ENG Sticky Navigation : 0.4');\n }\n}\n","/** Behaviour Expand/Collapse with Accordion\n * Extracted and refactored from behaviour.js by Edwin Joassart in october 2020 \n *\n * Respect the HTML structre below\n * Build to be backward compatible with NEWS behaviour.js implementation\n * Tightly coupled to NEWS atomicdesign.css and struture.css\n * \n * HTML Structure for an expand collapse is\n * \n
    \n
      \n
    • \n

      \n \n

      \n
      \n Content 1\n
      \n
    • \n
    • \n

      \n \n

      \n
      \n Content 2\n \n <-- Sub expand/collapse works exactly as the top one -->\n
      \n
        \n
      • \n

        \n \n

        \n
        \n Content 2 Sub Content 1\n
        \n
      • \n
      \n
      \n \n
      \n
    • \n
    \n
    \n\n *\n * Refactoring notes : \n * - Original was calling init on scroll event ?!\n * - Original had some polyfill for IE. Shouldn't be needed with babel\n * - Accordion is a new feature which didn't exist in original implementation\n * \n */\n\nconst DEFAULT_SELECTOR = '.expand-collapse';\n\nclass ExpandCollapse {\n /** Create an Expand Collapse\n * @param {Selector} ECContainer - Selector to the Expand Collapse main div\n */\n constructor(ECContainer) {\n this.ECContainer = ECContainer;\n this.isAccordion = ECContainer.classList.contains(\n 'expand-collapse-accordion'\n );\n this.attachEC(this.ECContainer);\n }\n\n /** Init Expand Collapse For The Container\n * @param {Selector} ECContainer\n */\n attachEC(ECContainer) {\n /*\n * ECs targets ECContainer > ul > li.list-item\n * It's written like to limit scope when there's nested Expand/Collapse (ie. usage in Pegasus/Enotification or FAQ)\n *\n * Or ECs targets ECContainer > div.list-item (for simpler single E/C) (ie. used in timeline)\n *\n * FIXME: if we're in the second case (using a div instead of a ul) but the div contains an ul,\n * the expand collapse is broken (it wrongly tries to target the ul instead of the div)\n *\n */\n const ECUl = ECContainer.querySelector('ul');\n // look for list-items in list\n let ECs =\n ECUl &&\n Array.from(ECUl.children).filter((child) =>\n child.classList.contains('list-item')\n );\n\n // look for list-items in div\n if (!ECs || ECs.length === 0)\n ECs = ECContainer.querySelectorAll('div.list-item');\n\n const fragment = window.location.hash.substring(1);\n // Check if there is a fragment identifier in the URL\n //Use css escape to handle numbers in the fragment\n const escapedFragment = fragment && CSS.escape(fragment);\n const targetItem = escapedFragment && ECContainer.querySelector(`#${escapedFragment}`);\n \n ECs.forEach((epItem) => {\n if (epItem.classList.contains('ECloaded')) return; // expand already set up\n \n const content = epItem.querySelector('.expand-content');\n content.dataset.height = window.getComputedStyle(content).height;\n \n // Calculate the height of images within .expand-content\n var imageHeight = 0;\n content.querySelectorAll('img').forEach((img) => {\n const rect = img.getBoundingClientRect();\n imageHeight += rect.height;\n });\n content.dataset.imageHeight = imageHeight;\n\n //calculate total height with text and image\n const totalHeight = parseFloat(content.dataset.height) + imageHeight;\n content.style.height = totalHeight\n\n this.initializeCopyUrlFunctionality(epItem);\n if (targetItem) { \n this.handleFragmentExistence(epItem, fragment);\n }else{\n this.attachBtnTrigger(epItem, { isAccordion: this.isAccordion });\n epItem.classList.add('ECloaded');\n this.defaultOpen(epItem);\n }\n\n });\n }\n initializeCopyUrlFunctionality(epItem) {\n const copyContainer = epItem.querySelector('[data-copy-code-url]');\n const shareButton = copyContainer ? copyContainer.querySelector('button.sharing') : '';\n const embedUrlContainer = copyContainer ? copyContainer.querySelector('.link-embed') : ''\n const copyUrlButton = copyContainer ? copyContainer.querySelector('.copyurl') : ''; //copy url on button click to share\n const textAreaToCopy = copyContainer ? copyContainer.querySelector('textarea') : ''\n const tooltipElement = copyContainer ? copyContainer.querySelector('[data-add-tooltip]') : ''\n\n //Hide Url container on page load\n if(embedUrlContainer){\n embedUrlContainer.classList.add('hidden');\n tooltipElement.style.visibility = 'hidden';\n }\n if (shareButton) {\n shareButton.addEventListener('click', () => {\n if (embedUrlContainer) {\n embedUrlContainer.classList.toggle('slideUp');\n embedUrlContainer.classList.toggle('hidden');\n tooltipElement.style.opacity = 0;\n tooltipElement.style.visibility = 'hidden';\n }\n });\n }\n //copy url on button click to share\n if (copyUrlButton) {\n copyUrlButton.addEventListener('click', () => this.copyUrl(textAreaToCopy, tooltipElement));\n }\n }\n copyUrl = (textAreaToCopy, tooltipElement) => {\n if(textAreaToCopy){\n textAreaToCopy.select();\n textAreaToCopy.setSelectionRange(0, 99999); \n }\n // Copy text with the click of a button\n navigator.clipboard.writeText(textAreaToCopy.value);\n \n if(tooltipElement){\n tooltipElement.style.opacity = 1;\n tooltipElement.style.visibility = 'visible';\n // Hide the tooltip after 3 seconds\n setTimeout(() => {\n tooltipElement.style.opacity = 0;\n tooltipElement.style.visibility = 'hidden';\n }, 1000);\n }\n }\n\n handleFragmentExistence(epItem, fragment) {\n if (epItem.querySelector('.expand-title')?.id === fragment) {\n epItem.scrollIntoView({ behavior: 'smooth', block: 'start' }); //scrolls to the section\n epItem.classList.add('ECloaded');\n this.attachBtnTrigger(epItem, { isAccordion: this.isAccordion });\n this.openClose(epItem, { opening: true });\n } else {\n this.openClose(epItem, { opening: false });\n this.attachBtnTrigger(epItem, { isAccordion: this.isAccordion });\n }\n }\n\n /** Start opened\n * Will start open in two cases :\n * - epItem has a \"expand\" class\n * - one of epItem children has a `aria-curent=\"true\"` property\n */\n defaultOpen(epItem) {\n this.openClose(epItem, {\n opening: epItem.classList.contains('expand'),\n });\n\n //target [aria-curent]\n epItem.querySelectorAll('[aria-curent=\"true\"').forEach((element) => {\n this.openClose(element.closest('.ECloaded'), { opening: true });\n });\n\n //target [aria-current]\n epItem.querySelectorAll('[aria-current=\"true\"').forEach((element) => {\n this.openClose(element.closest('.ECloaded'), { opening: true });\n }); \n }\n\n /** Attach Event Listener to the button\n * @param {Selector} btn - Selector to the button we'll attach to\n * @param {Selector} target - - Selector to the div for the expand/collapse\n * @param {Object} params - Object w/ EC parameters { isAccordion (bool) }\n */\n attachBtnTrigger(epItem, { isAccordion }) {\n const btn = epItem.querySelector('.expand-trigger');\n if (!btn || btn.classList.contains('has-click-handler')) return;\n\n btn.classList.add('has-click-handler');\n\n btn.addEventListener('click', (event) => {\n event.preventDefault();\n\n const isExpanded = epItem.getAttribute('data-expanded') === 'true';\n\n if (!isExpanded && isAccordion) {\n // close the open one\n const openedEpItems = this.ECContainer.querySelectorAll(\n '[data-expanded=\"true\"]'\n );\n openedEpItems.forEach((opened) =>\n this.openClose(opened, { opening: false })\n );\n }\n\n this.openClose(epItem, { opening: !isExpanded });\n });\n }\n\n /** Open/Close Collapsable\n * @param {Selector} epItem - ? expand-collapse wrapper ?\n * @param {Object} options.opening - direction : true = expanding; false = collapsing\n */\n openClose(epItem, { opening }) {\n const btn = epItem.querySelector('.expand-trigger');\n const target = epItem.querySelector('.expand-content');\n btn.setAttribute('aria-expanded', opening);\n epItem.dataset.expanded = opening;\n target.hidden = !opening;\n //calculate content and image height\n var imageHeight = 0;\n target.querySelectorAll('img').forEach((img) => {\n const rect = img.getBoundingClientRect();\n imageHeight += rect.height;\n });\n target.dataset.imageHeight = imageHeight; \n\n const totalHeight = parseFloat(target.dataset.height) + imageHeight;\n target.dataset.height = opening ? totalHeight : '0px';\n\n // if exists, change visibility of the button span content\n const btnContentExpanded = btn.querySelector('span.toggle-btn-expanded');\n const btnContentCollapsed = btn.querySelector('span.toggle-btn-collapsed');\n\n if (btnContentExpanded && btnContentCollapsed) {\n btnContentExpanded.hidden = !opening;\n btnContentCollapsed.hidden = opening;\n }\n }\n\n /**\n * Find all dom elements matching our main selector and attach the behaviour\n * @param {DOMSelector} selector - DOM Selector to search for, defaults to DEFAULT_SELECTOR (const)\n */\n static init(selector) {\n document.onreadystatechange = function () {\n if (document.readyState === \"complete\") {\n document\n .querySelectorAll(selector || DEFAULT_SELECTOR)\n .forEach((ECElement) => new ExpandCollapse(ECElement));\n }\n }\n\n console.info('Expand-Collapse : 1.0');\n }\n}\n\nexport default ExpandCollapse;\n","/**\n * Timeline component filter\n *\n * @author Edwin Joassart \n * @copyright Europarl 2021 (c) All rights reserved\n *\n * This handle the filtering by tags of the timeline component\n *\n */\n\n/**\n * filter on each checkbox changes\n * this is quite expensive\n * We could do some pre-computation but we're not sure\n * it's worth it (is the filter used enough to justify the expense at every load ?)\n * Alternatively we could do some caching (compute only first time)\n */\n\nconst filterTimeline = () => {\n // get active filter name\n const activeFiltersElements = document.querySelectorAll(\n 'input[type=\"checkbox\"].a11y-issue:checked'\n );\n\n // extract id of active filters\n const activeFilters = [...activeFiltersElements].map((filter) =>\n filter.getAttribute('name').trim().toLowerCase()\n );\n\n // reset color for active elements or all elements\n const resetColorElements =\n activeFiltersElements.length > 0\n ? activeFiltersElements\n : document.querySelectorAll('input[type=\"checkbox\"].a11y-issue');\n\n resetColorElements.forEach((filter) => {\n const wrapper = filter.closest('div');\n wrapper.style.borderColor = wrapper.dataset.borderColor;\n });\n\n // remove border color for all but the checked if there's at least 1 checked\n if (activeFiltersElements.length > 0)\n document\n .querySelectorAll('input[type=\"checkbox\"].a11y-issue:not(:checked)')\n .forEach((filter) => {\n filter.closest('div').style.borderColor = '';\n });\n\n document\n .querySelectorAll('.timeline-container article')\n .forEach((article) => {\n const articleTags = new Set(\n [\n ...article.querySelectorAll('.ep_toggle-timeline-footer abbr'),\n ].map((tag) => tag.getAttribute('title').trim().toLowerCase())\n );\n\n // if no filters are selected, display all articles\n if (activeFilters.length === 0) {\n article.style.display = 'block';\n return;\n }\n\n // check if any filters match tags on the current article and toogle visibility\n article.style.display = activeFilters.some((filterTag) =>\n articleTags.has(filterTag.toLowerCase())\n )\n ? 'block'\n : 'none';\n });\n};\n\nexport default function timeLineFilter() {\n const tagsCheckboxes = document.querySelectorAll(\n 'input[type=\"checkbox\"].a11y-issue'\n );\n\n // filter on check/unckeck\n tagsCheckboxes.forEach((tagCheckbox) =>\n tagCheckbox.addEventListener('change', filterTimeline)\n );\n\n // filter once on start\n filterTimeline();\n}\n","/**\n * EPNewshub 3.0\n *\n * @author Edwin Joassart \n * @copyright Europarl 2022 (c) All rights reserved\n *\n * This is V3 of the NewsHub Component.\n * It handles the newshub feed of the pressroom (right column) box.\n *\n * If you add '?newshub=beta' to url of the page you integrated the newshub in, this script will use the beta API (https://new.newshub.eu) instead of production API.\n *\n * The API lives at https://new.epnewshub.eu/v1/\n *\n * API reference ( at the time of writing ) is https://docs.google.com/document/d/1cC5S897ZC6jINu7BMKKEyfRDR1R4kN3vZZPkUyNDbSg/edit#heading=h.bvgwhpy9fhjk\n *\n * JIRA : ENG-33568\n *\n * \"The live documentation for the API is temporarily hosted here: http://169.51.160.201/swagger-ui.html#/ However it will soon be moved to the new.newshub.eu server.\n * This document will be updated accordingly to point out the new location.\"\n *\n *\n * Server info\n * Old newshub New newshub\n * IP 3.121.75.186 3.126.81.200\n *\n * Current URL epnewshub.eu and new.epnewshub.eu\n * old.epnewshub.eu\n *\n * URL after the 10th of Jan\n * old.epnewshub.eu epnewshub.eu\n *\n * \"IP addresses will remain the same. It is therefore safe to use the new 3.126.81.200 as of today for new developments requiring a specific IP.\n * It is worth mentioning that after the release date, new.epnewshub.eu will be used for later betas.\"\n *\n */\n\n/**\n * @description Helper function to get query parameters\n * @param {String} param - parameter of interests\n * @return Value of the query parameter if exist (null if it doesn't)\n */\nconst getQueryParameter = (parameter) => {\n const parameters = new URLSearchParams(window.location.search);\n\n const result = parameters.get(parameter);\n return result ?? null;\n};\n\n/**\n * @description API Endpoint constant. Configurable at run time to switch to beta.\n */\nconst QUERY_PARAMETERS =\n '?contributorType=mep%2Cpresident%2Ccommittee%2Ceppress&pageNo=0&pageSize=25&sortBy=create_time';\nconst ENDPOINT =\n getQueryParameter('newshub') === 'beta'\n ? `https://new.epnewshub.eu/v1/social-item/${QUERY_PARAMETERS}`\n : `https://epnewshub.eu/v1/social-item/${QUERY_PARAMETERS}`;\nconst REFRESH_TIMER = 15000; // ms\n\n/**\n * @description Helper function to turn an HTML String into a DOM Element\n * @param {String} html - Html String Template\n * @returns DOMElement - Ready to be append in DOM\n */\nconst template = (html) => {\n const temporary = document.createElement('template');\n temporary.innerHTML = html.trim();\n return temporary.content.firstChild;\n};\n\n/** NewsHub V3 For ENG */\nexport default function ENGNewshub() {\n /** Get injectable html from template & data */\n const newsPartial = (template, data) => {\n let html = template.innerHTML;\n for (const key of Object.keys(data)) {\n html = html.replace(new RegExp(`{{${key}}}`, 'gmi'), data[key]);\n }\n\n return html;\n };\n\n /** API fetcher */\n const fetcher = async (url) => {\n try {\n const response = await fetch(`${url}`);\n if (response.code > 399 || !response.ok) {\n throw new Error('error : not ok');\n }\n\n return await response.json();\n } catch (error) {\n console.error(error);\n }\n };\n\n /**\n * Return url for Poster Picture with fallback for Commission or General EP\n *\n * Commission account are deprecated and will not be returned from API in the future\n * API request is filtered and shouldn't EC accounts anyway\n *\n * API maintainer consider adding fallback images on their side.\n * This function might become useless soon\n * */\n const choosePosterPicture = ({ pictureLink, type }) => {\n // we got a picture, return it\n if (pictureLink) return pictureLink;\n\n // related to the commission, fallback to commission logo\n if (type === 'commission' || type === 'ec_corporate')\n return '/news/img/ec-logo.jpg';\n\n // fallback to an EP logo\n return '/news/img/ep-logo.svg';\n };\n\n /**\n * DOM injector\n * Will create and insert element for each articles in wrapper\n */\n const injector = async (data) => {\n data?.data?.items?.forEach(({ content, contributor, source, postedAt }) => {\n /** map data to fit template */\n\n const data = {\n posterName: source.name,\n group: contributor?.politicalGroup?.eparty || '',\n groupFull: contributor?.politicalGroup?.party || '',\n postDate: new Date(postedAt * 1000),\n postDateLocalized: Intl.DateTimeFormat(navigator.language, {\n year: 'numeric',\n month: 'numeric',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n }).format(new Date(postedAt * 1000)),\n postChannel: source.type,\n postContent: content,\n };\n\n // duplicate template and return injectable html\n const newElement = newsPartial(newsTemplate, data);\n\n const newEltemplate = template(newElement)\n // set img src for avoid wrong loading data \n newEltemplate.querySelector('.posterPicture').src = choosePosterPicture(contributor)\n // set link href for avoid wrong loading data\n newEltemplate.querySelector('.poster').href = source.url\n // inject new article in wrapper\n wrapperElement.append(newEltemplate);\n });\n };\n\n /**\n * Cleaner\n * Will remove all articles from wrapper\n * */\n const cleaner = () => {\n const elements = wrapperElement.querySelectorAll('li');\n elements.forEach((element) => element.remove());\n };\n\n /**\n * Updater\n * Handles timer and refresh\n */\n const updater = async () => {\n const data = await fetcher(ENDPOINT);\n cleaner();\n injector(data);\n };\n\n /** Select \"template\" to duplicate for future article injection */\n const newsTemplate = document.querySelector('template#newshub_element');\n if (!newsTemplate) return; // We're not on a page with a NewsHub\n\n /** Select \"wrapper\" container for future article injection */\n const wrapperElement = newsTemplate.parentElement;\n\n /** update at laucnh */ \n updater();\n\n /** subsequent update at interval */\n setInterval(updater, REFRESH_TIMER);\n}\n","class Footer {\n constructor(wrapperSelector, triggerSelector, contentSelector) {\n this.wrapperSelector = wrapperSelector\n this.triggerSelector = triggerSelector\n this.contentSelector = contentSelector\n this.initialize();\n }\n\n initialize() {\n const buttons = document.querySelectorAll(this.triggerSelector);\n const contents = document.querySelectorAll(this.contentSelector);\n // Close all content by default\n contents.forEach(content => this.collapse(content));\n buttons.forEach(button => this.attachExpandCollapseEventListener(button));\n }\n\n attachExpandCollapseEventListener(button) {\n const wrapper = button.closest(this.wrapperSelector)\n const content = wrapper.querySelector(this.contentSelector)\n button.addEventListener(\"click\", () => {\n this.checkAndCloseOpenedContent(content)\n if (content.classList.contains('expanded')) {\n this.collapse(content)\n } else {\n this.expand(content)\n }\n });\n }\n\n checkAndCloseOpenedContent(content) {\n const openedContent = document.querySelector(this.contentSelector + '.expanded')\n if (openedContent && openedContent !== content) this.collapse(openedContent)\n }\n\n collapse(content) {\n content.style.height = \"0\";\n content.classList.remove('expanded')\n this.toggleAriaExpanded(content, false)\n setTimeout(() => content.style.display = \"none\", 300)\n }\n\n expand(content) {\n content.style = \"display: block; height: 0\";\n content.style.height = content.scrollHeight + \"px\";\n content.classList.add('expanded')\n this.toggleAriaExpanded(content, true)\n }\n\n toggleAriaExpanded(content, expanded) {\n const wrapper = content.closest(this.wrapperSelector)\n const button = wrapper.querySelector(this.triggerSelector)\n button.setAttribute('aria-expanded', expanded);\n }\n\n static init() {\n new Footer('.footer-expand-wrapper', '.footer-expand-trigger', '.footer-expand-content');\n console.info('Footer : 1.0');\n }\n}\n\nexport default Footer;\n","import Dropdown from './dropdown-menu.js';\nimport ENGMainNavigation from './eng-main-navigation.js';\nimport ENGKeyboardNavigation from './eng-keyboard-navigation.js';\nimport ENGSearch from './eng-search.js';\nimport ENGStickyNavigation from './eng-sticky-navigation.js';\nimport ENGExpandCollapse from './eng-expand-collapse.js';\nimport ENGTimelineFilter from './eng-timeline-filter.js';\nimport ENGNewshub from './eng-newshub.js';\nimport ENGFooter from './eng-footer.js';\n\n\nfunction init() {\n try {\n Dropdown.init();\n } catch (error) {\n console.error('Error loading Dropdown', error);\n }\n\n try {\n ENGMainNavigation.init();\n } catch (error) {\n console.error('Error loading MainNavigation', error);\n }\n\n try {\n ENGKeyboardNavigation.init();\n } catch (error) {\n console.error('Error loading KeyboardNavigation', error);\n }\n\n try {\n ENGSearch.init();\n } catch (error) {\n console.error('Error loading Search', error);\n }\n\n try {\n ENGStickyNavigation.init();\n } catch (error) {\n console.error('Error loading StickyNavigation', error);\n }\n\n try {\n ENGExpandCollapse.init();\n } catch (error) {\n console.error('Error loading ExpandCollapse', error);\n }\n\n try {\n ENGFooter.init();\n } catch (error) {\n console.error('Error loading Footer', error);\n }\n\n try {\n ENGTimelineFilter();\n } catch (error) {\n console.error('Error loading TimelineFilter', error);\n }\n\n try {\n ENGNewshub();\n } catch (error) {\n console.error('Error loading Newshub', error);\n }\n\n console.info('ENG bundle build 10');\n}\n\nconsole.info('Bundle loaded');\n\n// https://javascript.info/onload-ondomcontentloaded#readystate\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', init);\n} else {\n init();\n}\n"],"names":["Dropdown","constructor","dropdownButtonElement","this","buttonElement","menuElement","closest","querySelector","addEventListener","toggleMenu","bind","clickOutsideEventListener","openMenu","setAttribute","classList","remove","style","display","closeMenuFromOutsideClick","document","closeMenu","add","removeEventListener","event_","target","preventDefault","contains","static","querySelectorAll","forEach","dropdown","console","info","ENGMainNavigation","button","focusRestingAnchor","createElement","tagName","focusRestingContainer","height","width","appendChild","after","link","isOtherWebsite","id","otherWebsitesLink","documentClickEventHandler","linkClickReleaseEventHandler","shouldMoveFocusOnClickRelease","focusOnHover","blurOnLeave","_event","window","getComputedStyle","linkOpen","focus","linkClose","noBlur","nextSibling","activeElement","blur","element","options","getAttribute","ENGKeyboardNav","mainNav","handleKeyDownEvent","linkElement","menuItem","removeAttribute","releaseLink","mainList","Array","from","focusLink","focusParentMenuEntry","closestLi","setTimeout","_linkElement","level","closestParent","preventScroll","menuEntry","includes","keyCode","shiftKey","processLeft","processRight","processEsc","processUp","processDown","previouslyActive","nextElementSibling","menuList","previousPosition","indexOf","length","targetActive","end","prevElm","previousElementSibling","focusableElems","toBeFocusedElem","nextElm","ENGSearch","searchButtonElement","value","searchFormElement","closeOnClickOutsideEventHandler","closeSearch","toggleMobileSearch","searchFieldElement","searchMobileIcon","onSearchFieldChange","escKeyPressEventListner","spacebarKeyPressEventListner","ENGFixedHeader","_ref","trackerSelector","targetSelector","tracker","hamburger","backdrop","menuLevel0","scrollEventHandler","scrollToTopAndAddBackdrop","top","targetTop","targetHeight","getBoundingClientRect","trackerTop","trackerTreshold","innerHeight","maxHeight","scrollTo","stick","unstick","offset","pageYOffset","paddingTop","Number","ExpandCollapse","ECContainer","_defineProperty","textAreaToCopy","tooltipElement","select","setSelectionRange","navigator","clipboard","writeText","opacity","visibility","isAccordion","attachEC","ECUl","ECs","children","filter","child","fragment","location","hash","substring","escapedFragment","CSS","escape","targetItem","epItem","content","dataset","imageHeight","img","rect","totalHeight","parseFloat","initializeCopyUrlFunctionality","handleFragmentExistence","attachBtnTrigger","defaultOpen","copyContainer","shareButton","embedUrlContainer","copyUrlButton","toggle","copyUrl","scrollIntoView","behavior","block","openClose","opening","btn","event","isExpanded","opened","_ref2","expanded","hidden","btnContentExpanded","btnContentCollapsed","selector","onreadystatechange","readyState","ECElement","filterTimeline","activeFiltersElements","activeFilters","map","trim","toLowerCase","wrapper","borderColor","article","articleTags","Set","tag","some","filterTag","has","QUERY_PARAMETERS","ENDPOINT","parameter","URLSearchParams","search","get","REFRESH_TIMER","template","html","temporary","innerHTML","firstChild","ENGNewshub","injector","async","data","items","contributor","source","postedAt","posterName","name","group","politicalGroup","eparty","groupFull","party","postDate","Date","postDateLocalized","Intl","DateTimeFormat","language","year","month","day","hour","minute","format","postChannel","type","postContent","newElement","newsPartial","key","Object","keys","replace","RegExp","newsTemplate","newEltemplate","src","pictureLink","choosePosterPicture","href","url","wrapperElement","append","updater","response","fetch","code","ok","Error","json","error","fetcher","parentElement","setInterval","Footer","wrapperSelector","triggerSelector","contentSelector","initialize","buttons","collapse","attachExpandCollapseEventListener","checkAndCloseOpenedContent","expand","openedContent","toggleAriaExpanded","scrollHeight","init","ENGKeyboardNavigation","ENGStickyNavigation","ENGExpandCollapse","ENGFooter","tagCheckbox"],"mappings":"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"}