Refreshing sib-displays in absence of reactive store
This commit is contained in:
		
				
					committed by
					
						
						Jean-Baptiste Pasquier
					
				
			
			
				
	
			
			
			
						parent
						
							c15afa496f
						
					
				
				
					commit
					7f227bfc57
				
			@ -2,11 +2,16 @@
 | 
			
		||||
  sib-router(default-route='admin-circle-list', hidden)
 | 
			
		||||
    sib-route(name='admin-circle-list')
 | 
			
		||||
    sib-route(name='admin-circle-create')
 | 
			
		||||
    sib-route(name='circle-left')
 | 
			
		||||
 | 
			
		||||
  div.content-box__header.with-description
 | 
			
		||||
    h1.title-left.without-margin Administration
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  #circle-left(hidden)
 | 
			
		||||
    include page-circle-left.pug
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  #admin-circle-list(hidden)
 | 
			
		||||
 | 
			
		||||
    include templates/hd-user-avatar.pug
 | 
			
		||||
 | 
			
		||||
@ -2,10 +2,14 @@
 | 
			
		||||
  sib-router(default-route='admin-project-list', hidden)
 | 
			
		||||
    sib-route(name='admin-project-list')
 | 
			
		||||
    sib-route(name='admin-project-create')
 | 
			
		||||
    sib-route(name='project-left')
 | 
			
		||||
 | 
			
		||||
  div.content-box__header.with-description
 | 
			
		||||
    h1.title-left.without-margin Administration
 | 
			
		||||
 | 
			
		||||
  #project-left(hidden)
 | 
			
		||||
    include page-project-left.pug
 | 
			
		||||
 | 
			
		||||
  #admin-project-list(hidden)
 | 
			
		||||
    include templates/hd-user-avatar.pug
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								src/page-circle-left.pug
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/page-circle-left.pug
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
#circle-left
 | 
			
		||||
  div.content-box__info(style="padding: 15px")
 | 
			
		||||
 | 
			
		||||
    p You have successfully left this circle
 | 
			
		||||
    p This is a private group, to join again, go to the <sib-link next="admin-circle-list">administration</sib-link> panel and ask for an invite
 | 
			
		||||
							
								
								
									
										5
									
								
								src/page-project-left.pug
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/page-project-left.pug
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
			
		||||
#project-left
 | 
			
		||||
  div.content-box__info(style="padding: 15px")
 | 
			
		||||
 | 
			
		||||
    p You have successfully left this project
 | 
			
		||||
    p This is a private group, to join again, go to the <sib-link next="admin-project-list">administration</sib-link> panel and ask for an invite
 | 
			
		||||
@ -2,41 +2,50 @@ function recursiveAdaptWidgets(prefix, element, user) {
 | 
			
		||||
  //- This function is a workaround for the currently unworking populate
 | 
			
		||||
  //- Feel free to see examples on page-circles-
 | 
			
		||||
 | 
			
		||||
  element.querySelectorAll('[' + prefix + '-user-id]').forEach((el) => {
 | 
			
		||||
    el.setAttribute(el.getAttribute(prefix + '-user-id'), user['@id']);
 | 
			
		||||
  element.querySelectorAll("[" + prefix + "-user-id]").forEach(el => {
 | 
			
		||||
    el.setAttribute(el.getAttribute(prefix + "-user-id"), user["@id"]);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (element != document) {
 | 
			
		||||
 | 
			
		||||
    //- Allow to bind-user on selected attribute
 | 
			
		||||
    if (element.getAttribute(prefix + '-user-id')) {
 | 
			
		||||
      element.setAttribute(element.getAttribute(prefix + '-user-id'), user['@id']);
 | 
			
		||||
    if (element.getAttribute(prefix + "-user-id")) {
 | 
			
		||||
      element.setAttribute(
 | 
			
		||||
        element.getAttribute(prefix + "-user-id"),
 | 
			
		||||
        user["@id"]
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //- Allow to set data-src to a children sib-form
 | 
			
		||||
    if (element.getAttribute(prefix + '-bind-resources')) {
 | 
			
		||||
      let form = element.querySelector(element.getAttribute(prefix + '-bind-resources') + " sib-form");
 | 
			
		||||
    if (element.getAttribute(prefix + "-bind-resources")) {
 | 
			
		||||
      let form = element.querySelector(
 | 
			
		||||
        element.getAttribute(prefix + "-bind-resources") + " sib-form"
 | 
			
		||||
      );
 | 
			
		||||
      if (form) {
 | 
			
		||||
        form.setAttribute('data-src', element.component.resourceId.replace('members/', ''));
 | 
			
		||||
        form.setAttribute(
 | 
			
		||||
          "data-src",
 | 
			
		||||
          element.component.resourceId.replace("members/", "")
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //- Allow to put user on a targetted search field
 | 
			
		||||
    if (element.getAttribute(prefix + '-bind-user2input')) {
 | 
			
		||||
      element.querySelector(element.getAttribute(prefix + '-bind-user2input')).value = user['@id'];
 | 
			
		||||
    if (element.getAttribute(prefix + "-bind-user2input")) {
 | 
			
		||||
      element.querySelector(
 | 
			
		||||
        element.getAttribute(prefix + "-bind-user2input")
 | 
			
		||||
      ).value = user["@id"];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //- In case your sib-display use a multiple, you have to target sub-sib-display auto-generated
 | 
			
		||||
    if (element.getAttribute(prefix + '-widgets-multiple') !== null) {
 | 
			
		||||
      element.querySelectorAll('div > sib-display').forEach((el) => {
 | 
			
		||||
        el.setAttribute(prefix + '-widgets', "");
 | 
			
		||||
    if (element.getAttribute(prefix + "-widgets-multiple") !== null) {
 | 
			
		||||
      element.querySelectorAll("div > sib-display").forEach(el => {
 | 
			
		||||
        el.setAttribute(prefix + "-widgets", "");
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //- This function is hooked every time a sib-something with prefix+"-widgets" is populated
 | 
			
		||||
  element.querySelectorAll('[' + prefix + '-widgets]').forEach((elementChild) => {
 | 
			
		||||
    elementChild.addEventListener('populate', () => {
 | 
			
		||||
  element.querySelectorAll("[" + prefix + "-widgets]").forEach(elementChild => {
 | 
			
		||||
    elementChild.addEventListener("populate", () => {
 | 
			
		||||
      recursiveAdaptWidgets(prefix, elementChild, user);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
@ -44,118 +53,237 @@ function recursiveAdaptWidgets(prefix, element, user) {
 | 
			
		||||
 | 
			
		||||
// auxiliary function closes the user profile menu
 | 
			
		||||
function closeUserControls() {
 | 
			
		||||
  let userControls = document.querySelector('#user-controls');
 | 
			
		||||
  let userControls = document.querySelector("#user-controls");
 | 
			
		||||
  if (userControls) userControls.removeAttribute("open");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function closeLeftMenu() {
 | 
			
		||||
  let leftMenu = document.querySelector('#main__menu');
 | 
			
		||||
  let leftMenu = document.querySelector("#main__menu");
 | 
			
		||||
  if (leftMenu) leftMenu.removeAttribute("open");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function closeRightMenu() {
 | 
			
		||||
  let rightMenu = document.querySelectorAll('.jsRightMenu');
 | 
			
		||||
  if(Array.from(rightMenu).filter(el=>el.hasAttribute('open')).length > 0) {
 | 
			
		||||
    Array.from(document.querySelectorAll('.views-container')).forEach(vC => vC.classList.toggle('sidebar-is-closed'));
 | 
			
		||||
    Array.from(rightMenu).forEach(el => el.removeAttribute('open'));
 | 
			
		||||
  let rightMenu = document.querySelectorAll(".jsRightMenu");
 | 
			
		||||
  if (Array.from(rightMenu).filter(el => el.hasAttribute("open")).length > 0) {
 | 
			
		||||
    Array.from(document.querySelectorAll(".views-container")).forEach(vC =>
 | 
			
		||||
      vC.classList.toggle("sidebar-is-closed")
 | 
			
		||||
    );
 | 
			
		||||
    Array.from(rightMenu).forEach(el => el.removeAttribute("open"));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function openRightMenu() {
 | 
			
		||||
  let rightMenu = document.querySelectorAll('.jsRightMenu');
 | 
			
		||||
  Array.from(rightMenu).forEach(el => el.setAttribute('open', ''));
 | 
			
		||||
  Array.from(document.querySelectorAll('.views-container')).forEach(vC => vC.classList.toggle('sidebar-is-closed'));
 | 
			
		||||
  let rightMenu = document.querySelectorAll(".jsRightMenu");
 | 
			
		||||
  Array.from(rightMenu).forEach(el => el.setAttribute("open", ""));
 | 
			
		||||
  Array.from(document.querySelectorAll(".views-container")).forEach(vC =>
 | 
			
		||||
    vC.classList.toggle("sidebar-is-closed")
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
document.addEventListener('DOMContentLoaded', function (event) {
 | 
			
		||||
  const menuWrappers = Array.from(document.querySelectorAll('.menu-wrapper'));
 | 
			
		||||
//auxiliary function clears cache & refreshes sib-displays for a given resource ID
 | 
			
		||||
function refreshSibDisplays(resourceId, clearCache = true) {
 | 
			
		||||
  let cacheCleared = false;
 | 
			
		||||
 | 
			
		||||
  Array.from(document.querySelectorAll("sib-display"))
 | 
			
		||||
    .filter(sibDisplay => sibDisplay.component.resourceId == resourceId) // keep only elements with resource == edited resource
 | 
			
		||||
    .forEach(e => {
 | 
			
		||||
      //clear cache if we were unable to before
 | 
			
		||||
      if ((clearCache && !cacheCleared) && e.component.resource != null) {
 | 
			
		||||
        e.component.resource.clearCache();
 | 
			
		||||
        cacheCleared = true;
 | 
			
		||||
      }
 | 
			
		||||
      e.dataset.src = e.dataset.src;
 | 
			
		||||
    }); // and update them
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//auxiliary function updates displays using a given resource
 | 
			
		||||
//NOTE: this is a temporary workaround and should be replaced by a reactive storage
 | 
			
		||||
//https://git.happy-dev.fr/startinblox/framework/sib-core/issues/524
 | 
			
		||||
async function refreshResource(event) {
 | 
			
		||||
 | 
			
		||||
  // if of the edited resource || id of the container of the created resource
 | 
			
		||||
  const resourceId = event.detail.resource["@id"] || event.target.dataset.src;
 | 
			
		||||
  let resource = document
 | 
			
		||||
    .querySelector('[data-src="' + resourceId + '"]')
 | 
			
		||||
    .component.resource.getResourceData();
 | 
			
		||||
 | 
			
		||||
  //special case: refresh circles/X/ from circle-members/Y/
 | 
			
		||||
  let partnerId = null;
 | 
			
		||||
  if (resourceId.includes("circle-members")) {
 | 
			
		||||
    partnerId = resource["http://happy-dev.fr/owl/#circle"]["@id"];
 | 
			
		||||
  } else if (resourceId.includes("project-members"))
 | 
			
		||||
    partnerId = resource["http://happy-dev.fr/owl/#project"]["@id"];
 | 
			
		||||
  
 | 
			
		||||
  //refresh all resources using the partner ID
 | 
			
		||||
  if (partnerId != null) {
 | 
			
		||||
    refreshSibDisplays(partnerId);
 | 
			
		||||
    refreshSibDisplays(partnerId + "members/");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //special cases updating users/X/circles for the left-side-menu (leaving or joining circle)
 | 
			
		||||
  let user = await document.querySelector('sib-auth').getUser();
 | 
			
		||||
  if(resourceId.includes('circle') && user != null) {
 | 
			
		||||
    let userId = user['@id'];
 | 
			
		||||
    refreshSibDisplays(userId + "circles/");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //clear cache on this resource
 | 
			
		||||
  //NOTE: this is required because the cache is not refreshed after POSTing changes on the resource
 | 
			
		||||
  let cacheCleared = false;
 | 
			
		||||
  if (event.target.component.resource != null) {
 | 
			
		||||
    event.target.component.resource.clearCache();
 | 
			
		||||
    cacheCleared = true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //update all displays which use this resource
 | 
			
		||||
  refreshSibDisplays(resourceId, cacheCleared);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//auxiliary function performs a redirect
 | 
			
		||||
//NOTE: currently a sib-display is required to dispatch the requestNavigation event
 | 
			
		||||
function performRedirect(route) {
 | 
			
		||||
  document.dispatchEvent(
 | 
			
		||||
    new CustomEvent("requestNavigation", {
 | 
			
		||||
      bubbles: true,
 | 
			
		||||
      detail: { route: route }
 | 
			
		||||
    })
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//auxiliary function redirects after leaving a project/circle
 | 
			
		||||
//NOTE: this is a temporary workaround until the following issues are resolved:
 | 
			
		||||
//https://git.happy-dev.fr/startinblox/framework/sib-core/issues/476
 | 
			
		||||
//https://git.happy-dev.fr/startinblox/framework/sib-core/issues/546
 | 
			
		||||
async function checkForPostLeaveRedirect(event) {
 | 
			
		||||
  //a redirect will only be required if I left in the information page of the resource
 | 
			
		||||
  if(!window.location.href.includes('-information')) return;
 | 
			
		||||
  //first need to get a sib-display with this resource id (to have access to the target Proxy, containing model fields)
 | 
			
		||||
  const resourceId = event.detail.resource['@id'] || event.target.dataset.src;
 | 
			
		||||
  let target = document.querySelector('[data-src="' + resourceId + '"]');
 | 
			
		||||
  let resource = target.component.resource.getResourceData();
 | 
			
		||||
 | 
			
		||||
  //no redirect is required for public circles
 | 
			
		||||
  let targetCircleId = resource["http://happy-dev.fr/owl/#circle"]["@id"];
 | 
			
		||||
  if(targetCircleId != undefined) {
 | 
			
		||||
    let targetCircle = document.querySelector('[data-src="' + targetCircleId + '"]');
 | 
			
		||||
    let targetCircleResource = targetCircle.component.resource.getResourceData();
 | 
			
		||||
    if(targetCircleResource['http://happy-dev.fr/owl/#status'] == 'Public') return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //a redirect will only be required if I've deleted myself
 | 
			
		||||
  let targetUser = resource['http://happy-dev.fr/owl/#user'];
 | 
			
		||||
 | 
			
		||||
  //compare with current user
 | 
			
		||||
  let user = await document.querySelector('sib-auth').getUser();
 | 
			
		||||
  if(targetUser['@id'] != user['@id'] && targetUser['@id'] != undefined) return;
 | 
			
		||||
 | 
			
		||||
  //perform the redirect
 | 
			
		||||
  if(resourceId.includes('circle')) performRedirect('circle-left');
 | 
			
		||||
  else if(resourceId.includes('project')) performRedirect('project-left');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
document.addEventListener("DOMContentLoaded", function(event) {
 | 
			
		||||
  const menuWrappers = Array.from(document.querySelectorAll(".menu-wrapper"));
 | 
			
		||||
 | 
			
		||||
  //- View change event
 | 
			
		||||
  window.addEventListener('navigate', (event) => {
 | 
			
		||||
  window.addEventListener("navigate", event => {
 | 
			
		||||
    closeLeftMenu();
 | 
			
		||||
    closeUserControls();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  //- Toggle sub-menus
 | 
			
		||||
  menuWrappers.forEach(menuWrapper => {
 | 
			
		||||
    const menu = menuWrapper.querySelector('.menu');
 | 
			
		||||
    menu.addEventListener('click', e => {
 | 
			
		||||
      menuWrapper.classList.toggle('is-closed');
 | 
			
		||||
    const menu = menuWrapper.querySelector(".menu");
 | 
			
		||||
    menu.addEventListener("click", e => {
 | 
			
		||||
      menuWrapper.classList.toggle("is-closed");
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  //- Watch every sib-forms & update data-src of linked sib-display
 | 
			
		||||
  document.querySelectorAll('sib-form').forEach(function (el) {
 | 
			
		||||
    el.addEventListener("save", function (event) {
 | 
			
		||||
      //clear cache on this resource
 | 
			
		||||
      //NOTE: this is required because the cache is not refreshed after POSTing changes on the resource
 | 
			
		||||
      if (el.component.resource != null) el.component.resource.clearCache();
 | 
			
		||||
 | 
			
		||||
      // if of the edited resource || id of the container of the created resource
 | 
			
		||||
      const resourceId = event.detail.resource['@id'] || el.dataset.src;
 | 
			
		||||
 | 
			
		||||
      //update all displays which use this resource
 | 
			
		||||
      Array.from(document.querySelectorAll('sib-display'))
 | 
			
		||||
        .filter(sibDisplay => sibDisplay.component.resourceId == resourceId) // keep only elements with resource == edited resource
 | 
			
		||||
        .forEach(e => e.dataset.src = e.dataset.src); // and update them
 | 
			
		||||
    });
 | 
			
		||||
  document.querySelector("body").addEventListener("save", event => {
 | 
			
		||||
    refreshResource(event);
 | 
			
		||||
  });
 | 
			
		||||
  document.querySelector("body").addEventListener("resourceDeleted", event => {
 | 
			
		||||
    //I might need to be redirected from this page
 | 
			
		||||
    checkForPostLeaveRedirect(event).then(refreshResource(event));
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  document.querySelector('sib-auth').getUser().then(user => {
 | 
			
		||||
    if (user !== null) {
 | 
			
		||||
      document.querySelectorAll('.notLoggedIn').forEach(el => el.style.visibility = 'visible');
 | 
			
		||||
      // Hide login button if already logged
 | 
			
		||||
      document.querySelector('button[role="log in"]').setAttribute('style', 'display:none !important');
 | 
			
		||||
      // Set current user id on set-user-id of sib-display
 | 
			
		||||
      recursiveAdaptWidgets("hd-inherit", document, user);
 | 
			
		||||
      for (leaveBtn of document.querySelectorAll('admin-circle-leave > sib-ac-checker:not([hidden])')) {
 | 
			
		||||
        leaveBtn.parentNode.parentNode.parentNode.nextElementSibling.setAttribute('style', 'display:none !important'); // Hide Join button
 | 
			
		||||
  document
 | 
			
		||||
    .querySelector("sib-auth")
 | 
			
		||||
    .getUser()
 | 
			
		||||
    .then(user => {
 | 
			
		||||
      if (user !== null) {
 | 
			
		||||
        document
 | 
			
		||||
          .querySelectorAll(".notLoggedIn")
 | 
			
		||||
          .forEach(el => (el.style.visibility = "visible"));
 | 
			
		||||
        // Hide login button if already logged
 | 
			
		||||
        document
 | 
			
		||||
          .querySelector('button[role="log in"]')
 | 
			
		||||
          .setAttribute("style", "display:none !important");
 | 
			
		||||
        // Set current user id on set-user-id of sib-display
 | 
			
		||||
        recursiveAdaptWidgets("hd-inherit", document, user);
 | 
			
		||||
        for (leaveBtn of document.querySelectorAll(
 | 
			
		||||
          "admin-circle-leave > sib-ac-checker:not([hidden])"
 | 
			
		||||
        )) {
 | 
			
		||||
          leaveBtn.parentNode.parentNode.parentNode.nextElementSibling.setAttribute(
 | 
			
		||||
            "style",
 | 
			
		||||
            "display:none !important"
 | 
			
		||||
          ); // Hide Join button
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }).catch(error => console.log(error));
 | 
			
		||||
    })
 | 
			
		||||
    .catch(error => console.log(error));
 | 
			
		||||
 | 
			
		||||
  // Document -> close menu
 | 
			
		||||
  document.addEventListener("click", event => {
 | 
			
		||||
    if (!event.target.closest('#user-controls')) {
 | 
			
		||||
    if (!event.target.closest("#user-controls")) {
 | 
			
		||||
      closeUserControls();
 | 
			
		||||
    }
 | 
			
		||||
    if (!event.target.closest('#main__menu') && event.target.id != "toggleMainMenu") {
 | 
			
		||||
    if (
 | 
			
		||||
      !event.target.closest("#main__menu") &&
 | 
			
		||||
      event.target.id != "toggleMainMenu"
 | 
			
		||||
    ) {
 | 
			
		||||
      closeLeftMenu();
 | 
			
		||||
    }
 | 
			
		||||
    if (!event.target.className.includes('jsMobileSidebarOpenButton') && !event.target.className.includes('jsOffsiteToggle')) {
 | 
			
		||||
    if (
 | 
			
		||||
      !event.target.className.includes("jsMobileSidebarOpenButton") &&
 | 
			
		||||
      !event.target.className.includes("jsOffsiteToggle")
 | 
			
		||||
    ) {
 | 
			
		||||
      closeRightMenu();
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  document.querySelector('#toggleMainMenu').addEventListener('click', event => {
 | 
			
		||||
    let leftMenu = document.querySelector('#main__menu');
 | 
			
		||||
    if (leftMenu.hasAttribute('open')) {
 | 
			
		||||
  document.querySelector("#toggleMainMenu").addEventListener("click", event => {
 | 
			
		||||
    let leftMenu = document.querySelector("#main__menu");
 | 
			
		||||
    if (leftMenu.hasAttribute("open")) {
 | 
			
		||||
      closeLeftMenu();
 | 
			
		||||
    } else {
 | 
			
		||||
      leftMenu.setAttribute('open', '');
 | 
			
		||||
      leftMenu.setAttribute("open", "");
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  Array.from(document.querySelectorAll('.jsMobileSidebarOpenButton')).forEach(el => {
 | 
			
		||||
    el.addEventListener('click', event => {
 | 
			
		||||
      openRightMenu();
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  Array.from(document.querySelectorAll(".jsMobileSidebarOpenButton")).forEach(
 | 
			
		||||
    el => {
 | 
			
		||||
      el.addEventListener("click", event => {
 | 
			
		||||
        openRightMenu();
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const rightMenus = Array.from(document.querySelectorAll('nav.jsRightMenu'));
 | 
			
		||||
  const rightMenus = Array.from(document.querySelectorAll("nav.jsRightMenu"));
 | 
			
		||||
  rightMenus.forEach(rightMenu => {
 | 
			
		||||
    const btnRightMenu = rightMenu.querySelector("li.jsOffsiteToggle");
 | 
			
		||||
    btnRightMenu.addEventListener('click', e => {
 | 
			
		||||
      if (rightMenu.hasAttribute('open')) {
 | 
			
		||||
    btnRightMenu.addEventListener("click", e => {
 | 
			
		||||
      if (rightMenu.hasAttribute("open")) {
 | 
			
		||||
        closeRightMenu();
 | 
			
		||||
      } else {
 | 
			
		||||
        openRightMenu();
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // listen for keypress
 | 
			
		||||
  document.onkeydown = (e) => {
 | 
			
		||||
  document.onkeydown = e => {
 | 
			
		||||
    e = e || window.event;
 | 
			
		||||
    if (e.key === "Escape" || e.key === "Esc") {
 | 
			
		||||
      closeUserControls();
 | 
			
		||||
@ -163,5 +291,4 @@ document.addEventListener('DOMContentLoaded', function (event) {
 | 
			
		||||
      closeRightMenu();
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user