mirror of
https://github.com/twbs/bootstrap.git
synced 2025-09-28 22:39:11 +02:00
fix(manipulator): increase coverage for manipulator
This commit is contained in:
@@ -562,8 +562,8 @@ class Carousel {
|
||||
}
|
||||
|
||||
const config = {
|
||||
...Util.getDataAttributes(target),
|
||||
...Util.getDataAttributes(this)
|
||||
...Manipulator.getDataAttributes(target),
|
||||
...Manipulator.getDataAttributes(this)
|
||||
}
|
||||
const slideIndex = this.getAttribute('data-slide-to')
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
import Data from './dom/data'
|
||||
import EventHandler from './dom/eventHandler'
|
||||
import Manipulator from './dom/manipulator'
|
||||
import SelectorEngine from './dom/selectorEngine'
|
||||
import Util from './util'
|
||||
|
||||
@@ -347,7 +348,7 @@ class Collapse {
|
||||
let data = Data.getData(element, DATA_KEY)
|
||||
const _config = {
|
||||
...Default,
|
||||
...Util.getDataAttributes(element),
|
||||
...Manipulator.getDataAttributes(element),
|
||||
...typeof config === 'object' && config ? config : {}
|
||||
}
|
||||
|
||||
@@ -391,7 +392,7 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
const triggerData = Util.getDataAttributes(this)
|
||||
const triggerData = Manipulator.getDataAttributes(this)
|
||||
const selector = Util.getSelectorFromElement(this)
|
||||
const selectorElements = Util.makeArray(SelectorEngine.find(selector))
|
||||
|
||||
|
@@ -1,12 +1,32 @@
|
||||
import Util from '../util'
|
||||
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.0.0-beta): dom/manipulator.js
|
||||
* Bootstrap (v4.1.1): dom/manipulator.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const regexDataKey = /[A-Z]/g
|
||||
|
||||
function normalizeData(val) {
|
||||
if (val === 'true') {
|
||||
return true
|
||||
} else if (val === 'false') {
|
||||
return false
|
||||
} else if (val === 'null') {
|
||||
return null
|
||||
} else if (val === Number(val).toString()) {
|
||||
return Number(val)
|
||||
} else if (val === '') {
|
||||
return null
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
function normalizeDataKey(key) {
|
||||
return key.replace(regexDataKey, (chr) => chr.toLowerCase())
|
||||
}
|
||||
|
||||
const Manipulator = {
|
||||
setChecked(input, val) {
|
||||
if (input instanceof HTMLInputElement) {
|
||||
@@ -23,21 +43,55 @@ const Manipulator = {
|
||||
},
|
||||
|
||||
setDataAttribute(element, key, value) {
|
||||
const $ = Util.jQuery
|
||||
if (typeof $ !== 'undefined') {
|
||||
$(element).data(key, value)
|
||||
}
|
||||
|
||||
element.setAttribute(`data-${key.replace(/[A-Z]/g, (chr) => `-${chr.toLowerCase()}`)}`, value)
|
||||
element.setAttribute(`data-${normalizeDataKey(key)}`, value)
|
||||
},
|
||||
|
||||
removeDataAttribute(element, key) {
|
||||
const $ = Util.jQuery
|
||||
if (typeof $ !== 'undefined') {
|
||||
$(element).removeData(key)
|
||||
element.removeAttribute(`data-${normalizeDataKey(key)}`)
|
||||
},
|
||||
|
||||
getDataAttributes(element) {
|
||||
if (typeof element === 'undefined' || element === null) {
|
||||
return {}
|
||||
}
|
||||
|
||||
element.removeAttribute(`data-${key.replace(/[A-Z]/g, (chr) => `-${chr.toLowerCase()}`)}`)
|
||||
let attributes
|
||||
if (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'dataset')) {
|
||||
attributes = {
|
||||
...element.dataset
|
||||
}
|
||||
} else {
|
||||
attributes = {}
|
||||
for (let i = 0; i < element.attributes.length; i++) {
|
||||
const attribute = element.attributes[i]
|
||||
|
||||
if (attribute.nodeName.indexOf('data-') !== -1) {
|
||||
// remove 'data-' part of the attribute name
|
||||
const attributeName = attribute
|
||||
.nodeName
|
||||
.substring('data-'.length)
|
||||
.replace(/-./g, (str) => str.charAt(1).toUpperCase())
|
||||
|
||||
attributes[attributeName] = attribute.nodeValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in attributes) {
|
||||
if (!Object.prototype.hasOwnProperty.call(attributes, key)) {
|
||||
continue
|
||||
}
|
||||
|
||||
attributes[key] = normalizeData(attributes[key])
|
||||
}
|
||||
|
||||
return attributes
|
||||
},
|
||||
|
||||
getDataAttribute(element, key) {
|
||||
return normalizeData(element
|
||||
.getAttribute(`data-${normalizeDataKey(key)}`)
|
||||
)
|
||||
},
|
||||
|
||||
offset(element) {
|
||||
|
@@ -267,7 +267,7 @@ class Dropdown {
|
||||
_getConfig(config) {
|
||||
config = {
|
||||
...this.constructor.Default,
|
||||
...Util.getDataAttributes(this._element),
|
||||
...Manipulator.getDataAttributes(this._element),
|
||||
...config
|
||||
}
|
||||
|
||||
|
@@ -473,7 +473,7 @@ class Modal {
|
||||
// Restore fixed content padding
|
||||
Util.makeArray(SelectorEngine.find(Selector.FIXED_CONTENT))
|
||||
.forEach((element) => {
|
||||
const padding = Util.getDataAttribute(element, 'padding-right')
|
||||
const padding = Manipulator.getDataAttribute(element, 'padding-right')
|
||||
if (typeof padding !== 'undefined') {
|
||||
Manipulator.removeDataAttribute(element, 'padding-right')
|
||||
element.style.paddingRight = padding
|
||||
@@ -483,7 +483,7 @@ class Modal {
|
||||
// Restore sticky content and navbar-toggler margin
|
||||
Util.makeArray(SelectorEngine.find(`${Selector.STICKY_CONTENT}`))
|
||||
.forEach((element) => {
|
||||
const margin = Util.getDataAttribute(element, 'margin-right')
|
||||
const margin = Manipulator.getDataAttribute(element, 'margin-right')
|
||||
if (typeof margin !== 'undefined') {
|
||||
Manipulator.removeDataAttribute(element, 'margin-right')
|
||||
element.style.marginRight = margin
|
||||
@@ -491,17 +491,13 @@ class Modal {
|
||||
})
|
||||
|
||||
// Restore body padding
|
||||
const padding = Util.getDataAttribute(document.body, 'padding-right')
|
||||
const padding = Manipulator.getDataAttribute(document.body, 'padding-right')
|
||||
if (typeof padding !== 'undefined') {
|
||||
Manipulator.removeDataAttribute(document.body, 'padding-right')
|
||||
document.body.style.paddingRight = padding
|
||||
} else {
|
||||
document.body.style.paddingRight = ''
|
||||
}
|
||||
|
||||
static _getInstance(element) {
|
||||
return Data.getData(element, DATA_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
_getScrollbarWidth() { // thx d.walsh
|
||||
@@ -520,7 +516,7 @@ class Modal {
|
||||
let data = Data.getData(this, DATA_KEY)
|
||||
const _config = {
|
||||
...Default,
|
||||
...Util.getDataAttributes(this),
|
||||
...Manipulator.getDataAttributes(this),
|
||||
...typeof config === 'object' && config ? config : {}
|
||||
}
|
||||
|
||||
@@ -539,6 +535,10 @@ class Modal {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static _getInstance(element) {
|
||||
return Data.getData(element, DATA_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -557,8 +557,8 @@ EventHandler.on(document, Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (
|
||||
|
||||
const config = Data.getData(target, DATA_KEY)
|
||||
? 'toggle' : {
|
||||
...Util.getDataAttributes(target),
|
||||
...Util.getDataAttributes(this)
|
||||
...Manipulator.getDataAttributes(target),
|
||||
...Manipulator.getDataAttributes(this)
|
||||
}
|
||||
|
||||
if (this.tagName === 'A' || this.tagName === 'AREA') {
|
||||
|
@@ -322,7 +322,7 @@ class ScrollSpy {
|
||||
|
||||
EventHandler.on(window, Event.LOAD_DATA_API, () => {
|
||||
Util.makeArray(SelectorEngine.find(Selector.DATA_SPY))
|
||||
.forEach((spy) => new ScrollSpy(spy, Util.getDataAttributes(spy)))
|
||||
.forEach((spy) => new ScrollSpy(spy, Manipulator.getDataAttributes(spy)))
|
||||
})
|
||||
|
||||
/**
|
||||
|
@@ -11,6 +11,7 @@ import {
|
||||
} from './tools/sanitizer'
|
||||
import Data from './dom/data'
|
||||
import EventHandler from './dom/eventHandler'
|
||||
import Manipulator from './dom/manipulator'
|
||||
import Popper from 'popper.js'
|
||||
import SelectorEngine from './dom/selectorEngine'
|
||||
import Util from './util'
|
||||
@@ -671,7 +672,7 @@ class Tooltip {
|
||||
}
|
||||
|
||||
_getConfig(config) {
|
||||
const dataAttributes = Util.getDataAttributes(this.element)
|
||||
const dataAttributes = Manipulator.getDataAttributes(this.element)
|
||||
|
||||
Object.keys(dataAttributes)
|
||||
.forEach((dataAttr) => {
|
||||
@@ -741,10 +742,6 @@ class Tooltip {
|
||||
.map((token) => token.trim())
|
||||
.forEach((tClass) => tip.classList.remove(tClass))
|
||||
}
|
||||
|
||||
static _getInstance(element) {
|
||||
return Data.getData(element, DATA_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
_handlePopperPlacementChange(popperData) {
|
||||
@@ -793,6 +790,10 @@ class Tooltip {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static _getInstance(element) {
|
||||
return Data.getData(element, DATA_KEY)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -22,20 +22,6 @@ function toType(obj) {
|
||||
return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase()
|
||||
}
|
||||
|
||||
function normalizeData(val) {
|
||||
if (val === 'true') {
|
||||
return true
|
||||
} else if (val === 'false') {
|
||||
return false
|
||||
} else if (val === 'null') {
|
||||
return null
|
||||
} else if (val === Number(val).toString()) {
|
||||
return Number(val)
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
const Util = {
|
||||
|
||||
TRANSITION_END: 'bsTransitionEnd',
|
||||
@@ -164,41 +150,6 @@ const Util = {
|
||||
return [nodeList]
|
||||
},
|
||||
|
||||
getDataAttributes(element) {
|
||||
if (typeof element === 'undefined' || element === null) {
|
||||
return {}
|
||||
}
|
||||
|
||||
let attributes
|
||||
if (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'dataset')) {
|
||||
attributes = this.extend({}, element.dataset)
|
||||
} else {
|
||||
attributes = {}
|
||||
for (let i = 0; i < element.attributes.length; i++) {
|
||||
const attribute = element.attributes[i]
|
||||
if (attribute.nodeName.indexOf('data-') !== -1) {
|
||||
// remove 'data-' part of the attribute name
|
||||
const attributeName = attribute.nodeName.substring('data-'.length).replace(/-./g, (str) => str.charAt(1).toUpperCase())
|
||||
attributes[attributeName] = attribute.nodeValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in attributes) {
|
||||
if (!Object.prototype.hasOwnProperty.call(attributes, key)) {
|
||||
continue
|
||||
}
|
||||
|
||||
attributes[key] = normalizeData(attributes[key])
|
||||
}
|
||||
|
||||
return attributes
|
||||
},
|
||||
|
||||
getDataAttribute(element, key) {
|
||||
return normalizeData(element.getAttribute(`data-${key.replace(/[A-Z]/g, (chr) => `-${chr.toLowerCase()}`)}`))
|
||||
},
|
||||
|
||||
isVisible(element) {
|
||||
if (typeof element === 'undefined' || element === null) {
|
||||
return false
|
||||
|
Reference in New Issue
Block a user