diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 16:37:47 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-20 16:37:47 +0300 |
commit | aee0a117a889461ce8ced6fcf73207fe017f1d99 (patch) | |
tree | 891d9ef189227a8445d83f35c1b0fc99573f4380 /app/assets/javascripts/lib/utils | |
parent | 8d46af3258650d305f53b819eabf7ab18d22f59e (diff) |
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'app/assets/javascripts/lib/utils')
-rw-r--r-- | app/assets/javascripts/lib/utils/common_utils.js | 11 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/constants.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/dom_utils.js | 14 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/intersection_observer.js | 28 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/navigation_utility.js | 39 | ||||
-rw-r--r-- | app/assets/javascripts/lib/utils/url_utility.js | 2 |
6 files changed, 94 insertions, 1 deletions
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index a82dad7e2c9..7235b38848c 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -735,3 +735,14 @@ export const isFeatureFlagEnabled = (flag) => window.gon.features?.[flag]; export const convertArrayToCamelCase = (array) => array.map((i) => convertToCamelCase(i)); export const isLoggedIn = () => Boolean(window.gon?.current_user_id); + +/** + * This method takes in array of objects with snake_case + * property names and returns a new array of objects with + * camelCase property names + * + * @param {Array[Object]} array - Array to be converted + * @returns {Array[Object]} Converted array + */ +export const convertArrayOfObjectsToCamelCase = (array) => + array.map((o) => convertObjectPropsToCamelCase(o)); diff --git a/app/assets/javascripts/lib/utils/constants.js b/app/assets/javascripts/lib/utils/constants.js index 36c6545164e..a108b02bcbf 100644 --- a/app/assets/javascripts/lib/utils/constants.js +++ b/app/assets/javascripts/lib/utils/constants.js @@ -17,6 +17,7 @@ export const BV_HIDE_MODAL = 'bv::hide::modal'; export const BV_HIDE_TOOLTIP = 'bv::hide::tooltip'; export const BV_DROPDOWN_SHOW = 'bv::dropdown::show'; export const BV_DROPDOWN_HIDE = 'bv::dropdown::hide'; +export const BV_COLLAPSE_STATE = 'bv::collapse::state'; export const DEFAULT_TH_CLASSES = 'gl-bg-transparent! gl-border-b-solid! gl-border-b-gray-100! gl-p-5! gl-border-b-1!'; diff --git a/app/assets/javascripts/lib/utils/dom_utils.js b/app/assets/javascripts/lib/utils/dom_utils.js index f7687a929de..b52a736f153 100644 --- a/app/assets/javascripts/lib/utils/dom_utils.js +++ b/app/assets/javascripts/lib/utils/dom_utils.js @@ -89,3 +89,17 @@ export const getParents = (element) => { return parents; }; + +/** + * This method takes a HTML element and an object of attributes + * to save repeated calls to `setAttribute` when multiple + * attributes need to be set. + * + * @param {HTMLElement} el + * @param {Object} attributes + */ +export const setAttributes = (el, attributes) => { + Object.keys(attributes).forEach((key) => { + el.setAttribute(key, attributes[key]); + }); +}; diff --git a/app/assets/javascripts/lib/utils/intersection_observer.js b/app/assets/javascripts/lib/utils/intersection_observer.js new file mode 100644 index 00000000000..0959df9a186 --- /dev/null +++ b/app/assets/javascripts/lib/utils/intersection_observer.js @@ -0,0 +1,28 @@ +import { memoize } from 'lodash'; + +import { uuids } from './uuids'; + +export const create = memoize((options = {}) => { + const id = uuids()[0]; + + return { + id, + observer: new IntersectionObserver((entries) => { + entries.forEach((entry) => { + entry.target.dispatchEvent( + new CustomEvent(`IntersectionUpdate`, { detail: { entry, observer: id } }), + ); + + if (entry.isIntersecting) { + entry.target.dispatchEvent( + new CustomEvent(`IntersectionAppear`, { detail: { observer: id } }), + ); + } else { + entry.target.dispatchEvent( + new CustomEvent(`IntersectionDisappear`, { detail: { observer: id } }), + ); + } + }); + }, options), + }; +}); diff --git a/app/assets/javascripts/lib/utils/navigation_utility.js b/app/assets/javascripts/lib/utils/navigation_utility.js index 1579b225e44..029e9f5fd9f 100644 --- a/app/assets/javascripts/lib/utils/navigation_utility.js +++ b/app/assets/javascripts/lib/utils/navigation_utility.js @@ -13,3 +13,42 @@ export default function findAndFollowLink(selector) { visitUrl(link); } } + +export function prefetchDocument(url) { + const newPrefetchLink = document.createElement('link'); + newPrefetchLink.rel = 'prefetch'; + newPrefetchLink.href = url; + newPrefetchLink.setAttribute('as', 'document'); + document.head.appendChild(newPrefetchLink); +} + +export function initPrefetchLinks(selector) { + document.querySelectorAll(selector).forEach((el) => { + let mouseOverTimer; + + const mouseOutHandler = () => { + if (mouseOverTimer) { + clearTimeout(mouseOverTimer); + mouseOverTimer = undefined; + } + }; + + const mouseOverHandler = () => { + el.addEventListener('mouseout', mouseOutHandler, { once: true, passive: true }); + + mouseOverTimer = setTimeout(() => { + if (el.href) prefetchDocument(el.href); + + // Only execute once + el.removeEventListener('mouseover', mouseOverHandler, true); + + mouseOverTimer = undefined; + }, 100); + }; + + el.addEventListener('mouseover', mouseOverHandler, { + capture: true, + passive: true, + }); + }); +} diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js index e53a39cde06..12462a2575e 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js +++ b/app/assets/javascripts/lib/utils/url_utility.js @@ -1,6 +1,6 @@ export const DASH_SCOPE = '-'; -const PATH_SEPARATOR = '/'; +export const PATH_SEPARATOR = '/'; const PATH_SEPARATOR_LEADING_REGEX = new RegExp(`^${PATH_SEPARATOR}+`); const PATH_SEPARATOR_ENDING_REGEX = new RegExp(`${PATH_SEPARATOR}+$`); const SHA_REGEX = /[\da-f]{40}/gi; |