diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-14 00:09:57 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-14 00:09:57 +0300 |
commit | 08d684dcf589c730a2a9d021451c72efa14d1911 (patch) | |
tree | 42296df77d988aefd0e77e3b5a4dfab886ac0812 /app/assets/javascripts/user_popovers.js | |
parent | 953eb09e086c8f2842512a62e56e32223b5bf974 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/user_popovers.js')
-rw-r--r-- | app/assets/javascripts/user_popovers.js | 121 |
1 files changed, 49 insertions, 72 deletions
diff --git a/app/assets/javascripts/user_popovers.js b/app/assets/javascripts/user_popovers.js index 597b96ae18c..4544373d8aa 100644 --- a/app/assets/javascripts/user_popovers.js +++ b/app/assets/javascripts/user_popovers.js @@ -57,35 +57,41 @@ const populateUserInfo = (user) => { ); }; -function initPopover(el, user, mountPopover) { - const preloadedUserInfo = getPreloadedUserInfo(el.dataset); +const initializedPopovers = new Map(); +let domObservedForChanges = false; - Object.assign(user, preloadedUserInfo); +const addPopoversToModifiedTree = new MutationObserver(() => { + const userLinks = document?.querySelectorAll('.js-user-link, .gfm-project_member'); - if (preloadedUserInfo.userId) { - populateUserInfo(user); + if (userLinks) { + addPopovers(userLinks); /* eslint-disable-line no-use-before-define */ + } +}); + +function observeBody() { + if (!domObservedForChanges) { + addPopoversToModifiedTree.observe(document.body, { + subtree: true, + childList: true, + }); + + domObservedForChanges = true; } - const UserPopoverComponent = Vue.extend(UserPopover); - const popoverInstance = new UserPopoverComponent({ - propsData: { - target: el, - user, - }, - }); - mountPopover(popoverInstance); - // wait for component to actually mount - setTimeout(() => { - // trigger an event to force tooltip to show - const event = new MouseEvent('mouseenter'); - event.isSelfTriggered = true; - el.dispatchEvent(event); - }); } -function initPopovers(userLinks, mountPopover) { - userLinks - .filter(({ dataset, user }) => !user && (dataset.user || dataset.userId)) - .forEach((el) => { +export default function addPopovers(elements = document.querySelectorAll('.js-user-link')) { + const userLinks = Array.from(elements); + const UserPopoverComponent = Vue.extend(UserPopover); + + observeBody(); + + return userLinks + .filter(({ dataset }) => dataset.user || dataset.userId) + .map((el) => { + if (initializedPopovers.has(el)) { + return initializedPopovers.get(el); + } + const user = { location: null, bio: null, @@ -93,60 +99,31 @@ function initPopovers(userLinks, mountPopover) { status: null, loaded: false, }; - el.user = user; - const init = initPopover.bind(null, el, user, mountPopover); - el.addEventListener('mouseenter', init, { once: true }); - el.addEventListener('mouseenter', ({ target, isSelfTriggered }) => { - if (!isSelfTriggered) return; - removeTitle(target); + const renderedPopover = new UserPopoverComponent({ + propsData: { + target: el, + user, + }, }); - el.addEventListener('mouseleave', ({ target }) => { - target.removeAttribute('aria-describedby'); - }); - }); -} -const userLinkSelector = 'a.js-user-link, a.gfm-project_member'; + initializedPopovers.set(el, renderedPopover); -const getUserLinkNodes = (node) => { - if (!('matches' in node)) return null; - if (node.matches(userLinkSelector)) return [node]; - return Array.from(node.querySelectorAll(userLinkSelector)); -}; + renderedPopover.$mount(); -let observer; + el.addEventListener('mouseenter', ({ target }) => { + removeTitle(target); + const preloadedUserInfo = getPreloadedUserInfo(target.dataset); -export default function addPopovers( - elements = document.querySelectorAll('.js-user-link'), - mountPopover = (popoverInstance) => popoverInstance.$mount(), -) { - const userLinks = Array.from(elements); + Object.assign(user, preloadedUserInfo); - initPopovers(userLinks, mountPopover); - - if (!observer) { - observer = new MutationObserver((mutationsList) => { - const newUserLinks = mutationsList - .filter((mutation) => mutation.type === 'childList' && mutation.addedNodes) - .reduce((acc, mutation) => { - const userLinkNodes = Array.from(mutation.addedNodes) - .flatMap(getUserLinkNodes) - .filter(Boolean); - acc.push(...userLinkNodes); - return acc; - }, []); - - if (newUserLinks.length !== 0) { - initPopovers(newUserLinks, mountPopover); - } - }); - observer.observe(document.body, { - subtree: true, - childList: true, - }); + if (preloadedUserInfo.userId) { + populateUserInfo(user); + } + }); + el.addEventListener('mouseleave', ({ target }) => { + target.removeAttribute('aria-describedby'); + }); - document.addEventListener('beforeunload', () => { - observer.disconnect(); + return renderedPopover; }); - } } |