Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-04-14 00:09:57 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-04-14 00:09:57 +0300
commit08d684dcf589c730a2a9d021451c72efa14d1911 (patch)
tree42296df77d988aefd0e77e3b5a4dfab886ac0812 /app/assets/javascripts/user_popovers.js
parent953eb09e086c8f2842512a62e56e32223b5bf974 (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.js121
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;
});
- }
}