diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-20 11:43:02 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-10-20 11:43:02 +0300 |
commit | d9ab72d6080f594d0b3cae15f14b3ef2c6c638cb (patch) | |
tree | 2341ef426af70ad1e289c38036737e04b0aa5007 /app/assets/javascripts/search_settings | |
parent | d6e514dd13db8947884cd58fe2a9c2a063400a9b (diff) |
Add latest changes from gitlab-org/gitlab@14-4-stable-eev14.4.0-rc42
Diffstat (limited to 'app/assets/javascripts/search_settings')
-rw-r--r-- | app/assets/javascripts/search_settings/components/search_settings.vue | 58 | ||||
-rw-r--r-- | app/assets/javascripts/search_settings/constants.js | 3 |
2 files changed, 49 insertions, 12 deletions
diff --git a/app/assets/javascripts/search_settings/components/search_settings.vue b/app/assets/javascripts/search_settings/components/search_settings.vue index 116967a62c8..3e23b8a3435 100644 --- a/app/assets/javascripts/search_settings/components/search_settings.vue +++ b/app/assets/javascripts/search_settings/components/search_settings.vue @@ -1,7 +1,13 @@ <script> import { GlSearchBoxByType } from '@gitlab/ui'; -import { uniq } from 'lodash'; -import { EXCLUDED_NODES, HIDE_CLASS, HIGHLIGHT_CLASS, TYPING_DELAY } from '../constants'; +import { uniq, escapeRegExp } from 'lodash'; +import { + EXCLUDED_NODES, + HIDE_CLASS, + HIGHLIGHT_CLASS, + NONE_PADDING_CLASS, + TYPING_DELAY, +} from '../constants'; const origExpansions = new Map(); @@ -37,9 +43,13 @@ const resetSections = ({ sectionSelector }) => { }; const clearHighlights = () => { - document - .querySelectorAll(`.${HIGHLIGHT_CLASS}`) - .forEach((element) => element.classList.remove(HIGHLIGHT_CLASS)); + document.querySelectorAll(`.${HIGHLIGHT_CLASS}`).forEach((element) => { + const { parentNode } = element; + const textNode = document.createTextNode(element.textContent); + parentNode.replaceChild(textNode, element); + + parentNode.normalize(); + }); }; const hideSectionsExcept = (sectionSelector, visibleSections) => { @@ -50,17 +60,41 @@ const hideSectionsExcept = (sectionSelector, visibleSections) => { }); }; -const highlightElements = (elements = []) => { - elements.forEach((element) => element.classList.add(HIGHLIGHT_CLASS)); +const transformMatchElement = (element, searchTerm) => { + const textStr = element.textContent; + const escapedSearchTerm = new RegExp(`(${escapeRegExp(searchTerm)})`, 'gi'); + + const textList = textStr.split(escapedSearchTerm); + const replaceFragment = document.createDocumentFragment(); + textList.forEach((text) => { + let addElement = document.createTextNode(text); + if (escapedSearchTerm.test(text)) { + addElement = document.createElement('mark'); + addElement.className = `${HIGHLIGHT_CLASS} ${NONE_PADDING_CLASS}`; + addElement.textContent = text; + escapedSearchTerm.lastIndex = 0; + } + replaceFragment.appendChild(addElement); + }); + + return replaceFragment; +}; + +const highlightElements = (elements = [], searchTerm) => { + elements.forEach((element) => { + const replaceFragment = transformMatchElement(element, searchTerm); + element.innerHTML = ''; + element.appendChild(replaceFragment); + }); }; -const displayResults = ({ sectionSelector, expandSection }, matches) => { +const displayResults = ({ sectionSelector, expandSection, searchTerm }, matches) => { const elements = matches.map((match) => match.parentElement); const sections = uniq(elements.map((element) => findSettingsSection(sectionSelector, element))); hideSectionsExcept(sectionSelector, sections); sections.forEach(expandSection); - highlightElements(elements); + highlightElements(elements, searchTerm); }; const clearResults = (params) => { @@ -116,21 +150,21 @@ export default { }, methods: { search(value) { + this.searchTerm = value; const displayOptions = { sectionSelector: this.sectionSelector, expandSection: this.expandSection, collapseSection: this.collapseSection, isExpanded: this.isExpandedFn, + searchTerm: this.searchTerm, }; - this.searchTerm = value; - clearResults(displayOptions); if (value.length) { saveExpansionState(document.querySelectorAll(this.sectionSelector), displayOptions); - displayResults(displayOptions, search(this.searchRoot, value)); + displayResults(displayOptions, search(this.searchRoot, this.searchTerm)); } else { restoreExpansionState(displayOptions); } diff --git a/app/assets/javascripts/search_settings/constants.js b/app/assets/javascripts/search_settings/constants.js index 9452d149122..a49351dc7b0 100644 --- a/app/assets/javascripts/search_settings/constants.js +++ b/app/assets/javascripts/search_settings/constants.js @@ -7,5 +7,8 @@ export const HIDE_CLASS = 'gl-display-none'; // used to highlight the text that matches the * search term export const HIGHLIGHT_CLASS = 'gl-bg-orange-100'; +// used to remove padding for text that matches the * search term +export const NONE_PADDING_CLASS = 'gl-p-0'; + // How many seconds to wait until the user * stops typing export const TYPING_DELAY = 400; |