Skip to content

Commit

Permalink
refactor: Move getElementFromSelector & getSelectorFromElement
Browse files Browse the repository at this point in the history
Move `getElementFromSelector` & getSelectorFromElement` inside selector-engine.js, in order to use SelectorEngine methods, avoiding raw querySelector usage

Feature: add `getMultipleElementsFromSelector` helper
  • Loading branch information
GeoSot committed May 10, 2022
1 parent 3cac119 commit d98e376
Show file tree
Hide file tree
Showing 16 changed files with 235 additions and 185 deletions.
3 changes: 1 addition & 2 deletions js/src/carousel.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import {
defineJQueryPlugin,
getElementFromSelector,
getNextActiveElement,
isRTL,
isVisible,
Expand All @@ -16,7 +15,7 @@ import {
} from './util/index'
import EventHandler from './dom/event-handler'
import Manipulator from './dom/manipulator'
import SelectorEngine from './dom/selector-engine'
import { getElementFromSelector, SelectorEngine } from './dom/selector-engine'
import Swipe from './util/swipe'
import BaseComponent from './base-component'

Expand Down
16 changes: 6 additions & 10 deletions js/src/collapse.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
* --------------------------------------------------------------------------
*/

import { defineJQueryPlugin, getElement, reflow } from './util/index'
import EventHandler from './dom/event-handler'
import {
defineJQueryPlugin,
getElement,
getElementFromSelector,
getMultipleElementsFromSelector,
getSelectorFromElement,
reflow
} from './util/index'
import EventHandler from './dom/event-handler'
import SelectorEngine from './dom/selector-engine'
SelectorEngine
} from './dom/selector-engine'
import BaseComponent from './base-component'

/**
Expand Down Expand Up @@ -285,10 +284,7 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (
event.preventDefault()
}

const selector = getSelectorFromElement(this)
const selectorElements = SelectorEngine.find(selector)

for (const element of selectorElements) {
for (const element of getMultipleElementsFromSelector(this)) {
Collapse.getOrCreateInstance(element, { toggle: false }).toggle()
}
})
Expand Down
54 changes: 53 additions & 1 deletion js/src/dom/selector-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,56 @@ const SelectorEngine = {
}
}

export default SelectorEngine
const getSelector = element => {
let selector = element.getAttribute('data-bs-target')

if (!selector || selector === '#') {
let hrefAttribute = element.getAttribute('href')

// The only valid content that could double as a selector are IDs or classes,
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
// `document.querySelector` will rightfully complain it is invalid.
// See https://github.com/twbs/bootstrap/issues/32273
if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) {
return null
}

// Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
hrefAttribute = `#${hrefAttribute.split('#')[1]}`
}

selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null
}

return selector
}

const getSelectorFromElement = element => {
const selector = getSelector(element)

if (selector) {
return SelectorEngine.findOne(selector) ? selector : null
}

return null
}

const getElementFromSelector = element => {
const selector = getSelector(element)

return selector ? SelectorEngine.findOne(selector) : null
}

const getMultipleElementsFromSelector = element => {
const selector = getSelector(element)

return selector ? SelectorEngine.find(selector) : []
}

export {
SelectorEngine,
getElementFromSelector,
getMultipleElementsFromSelector,
getSelectorFromElement
}
2 changes: 1 addition & 1 deletion js/src/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from './util/index'
import EventHandler from './dom/event-handler'
import Manipulator from './dom/manipulator'
import SelectorEngine from './dom/selector-engine'
import { SelectorEngine } from './dom/selector-engine'
import BaseComponent from './base-component'

/**
Expand Down
4 changes: 2 additions & 2 deletions js/src/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* --------------------------------------------------------------------------
*/

import { defineJQueryPlugin, getElementFromSelector, isRTL, isVisible, reflow } from './util/index'
import { defineJQueryPlugin, isRTL, isVisible, reflow } from './util/index'
import EventHandler from './dom/event-handler'
import SelectorEngine from './dom/selector-engine'
import { getElementFromSelector, SelectorEngine } from './dom/selector-engine'
import ScrollBarHelper from './util/scrollbar'
import BaseComponent from './base-component'
import Backdrop from './util/backdrop'
Expand Down
3 changes: 1 addition & 2 deletions js/src/offcanvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@

import {
defineJQueryPlugin,
getElementFromSelector,
isDisabled,
isVisible
} from './util/index'
import ScrollBarHelper from './util/scrollbar'
import EventHandler from './dom/event-handler'
import BaseComponent from './base-component'
import SelectorEngine from './dom/selector-engine'
import { getElementFromSelector, SelectorEngine } from './dom/selector-engine'
import Backdrop from './util/backdrop'
import FocusTrap from './util/focustrap'
import { enableDismissTrigger } from './util/component-functions'
Expand Down
2 changes: 1 addition & 1 deletion js/src/scrollspy.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { defineJQueryPlugin, getElement, isDisabled, isVisible } from './util/index'
import EventHandler from './dom/event-handler'
import SelectorEngine from './dom/selector-engine'
import { SelectorEngine } from './dom/selector-engine'
import BaseComponent from './base-component'

/**
Expand Down
4 changes: 2 additions & 2 deletions js/src/tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
* --------------------------------------------------------------------------
*/

import { defineJQueryPlugin, getElementFromSelector, getNextActiveElement, isDisabled } from './util/index'
import { defineJQueryPlugin, getNextActiveElement, isDisabled } from './util/index'
import EventHandler from './dom/event-handler'
import SelectorEngine from './dom/selector-engine'
import { getElementFromSelector, SelectorEngine } from './dom/selector-engine'
import BaseComponent from './base-component'

/**
Expand Down
3 changes: 2 additions & 1 deletion js/src/util/component-functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
*/

import EventHandler from '../dom/event-handler'
import { getElementFromSelector, isDisabled } from './index'
import { isDisabled } from './index'
import { getElementFromSelector } from '../dom/selector-engine'

const enableDismissTrigger = (component, method = 'hide') => {
const clickEvent = `click.dismiss${component.EVENT_KEY}`
Expand Down
2 changes: 1 addition & 1 deletion js/src/util/focustrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import EventHandler from '../dom/event-handler'
import SelectorEngine from '../dom/selector-engine'
import { SelectorEngine } from '../dom/selector-engine'
import Config from './config'

/**
Expand Down
43 changes: 0 additions & 43 deletions js/src/util/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,47 +30,6 @@ const getUID = prefix => {
return prefix
}

const getSelector = element => {
let selector = element.getAttribute('data-bs-target')

if (!selector || selector === '#') {
let hrefAttribute = element.getAttribute('href')

// The only valid content that could double as a selector are IDs or classes,
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
// `document.querySelector` will rightfully complain it is invalid.
// See https://github.com/twbs/bootstrap/issues/32273
if (!hrefAttribute || (!hrefAttribute.includes('#') && !hrefAttribute.startsWith('.'))) {
return null
}

// Just in case some CMS puts out a full URL with the anchor appended
if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
hrefAttribute = `#${hrefAttribute.split('#')[1]}`
}

selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null
}

return selector
}

const getSelectorFromElement = element => {
const selector = getSelector(element)

if (selector) {
return document.querySelector(selector) ? selector : null
}

return null
}

const getElementFromSelector = element => {
const selector = getSelector(element)

return selector ? document.querySelector(selector) : null
}

const getTransitionDurationFromElement = element => {
if (!element) {
return 0
Expand Down Expand Up @@ -318,10 +277,8 @@ export {
executeAfterTransition,
findShadowRoot,
getElement,
getElementFromSelector,
getjQuery,
getNextActiveElement,
getSelectorFromElement,
getTransitionDurationFromElement,
getUID,
isDisabled,
Expand Down
2 changes: 1 addition & 1 deletion js/src/util/scrollbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* --------------------------------------------------------------------------
*/

import SelectorEngine from '../dom/selector-engine'
import { SelectorEngine } from '../dom/selector-engine'
import Manipulator from '../dom/manipulator'
import { isElement } from './index'

Expand Down
2 changes: 1 addition & 1 deletion js/src/util/template-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { DefaultAllowlist, sanitizeHtml } from './sanitizer'
import { getElement, isElement } from '../util/index'
import SelectorEngine from '../dom/selector-engine'
import { SelectorEngine } from '../dom/selector-engine'
import Config from './config'

/**
Expand Down
Loading

0 comments on commit d98e376

Please sign in to comment.