mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-01-12 12:25:16 +08:00
refactor(hollowoutable): better robustness
This commit is contained in:
parent
9f4aff4b79
commit
efce8f815a
@ -1,77 +1,51 @@
|
|||||||
function getTransitionTimingFunctions (transitionTimingFunction) {
|
function createStyleObject (computedStyle) {
|
||||||
return transitionTimingFunction.replace(/([^\d]),/g, '$1#').split('# ')
|
const style = {}
|
||||||
|
const length = computedStyle.length
|
||||||
|
for (let index = 0; index < length; ++index) {
|
||||||
|
const key = computedStyle[index]
|
||||||
|
if (~key.indexOf('ransition')) continue
|
||||||
|
style[key] = computedStyle[key]
|
||||||
|
}
|
||||||
|
return style
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTransition (computedStyle) {
|
function createDiffedStyleObject (style, computedStyle) {
|
||||||
const transitionProperties = computedStyle.transitionProperty.split(', ')
|
const diffedStyle = {}
|
||||||
const transitionDurations = computedStyle.transitionDuration.split(', ')
|
for (const key of Object.keys(style)) {
|
||||||
const transitionTimingFunctions = getTransitionTimingFunctions(computedStyle.transitionTimingFunction)
|
if (~key.indexOf('ransition')) continue
|
||||||
const transitionDelays = computedStyle.transitionDelay.split(', ')
|
if (computedStyle[key] !== style[key]) {
|
||||||
const indexOfBackgroundColorTransition = transitionProperties.findIndex(property => property === 'background-color')
|
diffedStyle[key] = style[key]
|
||||||
const indexOfAllTransition = transitionProperties.findIndex(property => property === 'all')
|
|
||||||
if (~indexOfBackgroundColorTransition) {
|
|
||||||
const duration = transitionDurations[indexOfBackgroundColorTransition]
|
|
||||||
if (!duration) {
|
|
||||||
return {
|
|
||||||
backgroundColorTransitioned: false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return diffedStyle
|
||||||
if (~indexOfAllTransition) {
|
|
||||||
const duration = transitionDurations[indexOfAllTransition]
|
|
||||||
if (!duration) {
|
|
||||||
return {
|
|
||||||
backgroundColorTransitioned: false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
allTransitioned: true,
|
|
||||||
transitionWithoutBackgroundColor: 'none'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const transitionWithoutBackgroundColor = transitionProperties.map((prop, i) => (prop === 'background-color' ? null : [
|
|
||||||
transitionProperties[i],
|
|
||||||
transitionDurations[i],
|
|
||||||
transitionTimingFunctions[i],
|
|
||||||
transitionDelays[i]
|
|
||||||
].join(' '))).filter(v => v !== null).join(', ') || 'none'
|
|
||||||
return {
|
|
||||||
backgroundColorTransitioned: true,
|
|
||||||
transitionWithoutBackgroundColor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNextBackgroundColorOf (el) {
|
function getNextBackgroundColorOf (el) {
|
||||||
const computedStyle = window.getComputedStyle(el)
|
const computedStyle = window.getComputedStyle(el)
|
||||||
const prevBackgroundColor = computedStyle.backgroundColor
|
const prevStyle = createStyleObject(computedStyle)
|
||||||
const {
|
|
||||||
allTransitioned,
|
|
||||||
backgroundColorTransitioned,
|
|
||||||
transitionWithoutBackgroundColor
|
|
||||||
} = getTransition(computedStyle)
|
|
||||||
if (!backgroundColorTransitioned && !allTransitioned) {
|
|
||||||
return prevBackgroundColor
|
|
||||||
}
|
|
||||||
if (allTransitioned) {
|
|
||||||
console.warn(`[naive-ui/hollowoutable]:
|
|
||||||
background-color of`, el, `is transitioned by \`all\` property,
|
|
||||||
naive-ui can't read read all potential transition properties in this case.
|
|
||||||
When theme is changed it may cause losing some transition on it beside background-color transition.
|
|
||||||
To be avoid of this issue, specified all potential transition property explicitly.`)
|
|
||||||
}
|
|
||||||
const memorizedTransition = el.style.transition
|
const memorizedTransition = el.style.transition
|
||||||
const memorizedBackgroundColor = el.style.backgroundColor
|
const memorizedBackgroundColor = el.style.backgroundColor
|
||||||
el.style.transition = transitionWithoutBackgroundColor
|
el.style.transition = 'none'
|
||||||
const nextBackgroundColor = computedStyle.backgroundColor
|
const nextBackgroundColor = computedStyle.backgroundColor
|
||||||
el.style.backgroundColor = prevBackgroundColor
|
const diffedStyle = createDiffedStyleObject(prevStyle, computedStyle)
|
||||||
|
const memorizedInlineStyle = {}
|
||||||
|
for (const key of Object.keys(diffedStyle)) {
|
||||||
|
if (~key.indexOf('ransition')) continue
|
||||||
|
memorizedInlineStyle[key] = el.style[key]
|
||||||
|
el.style[key] = diffedStyle[key]
|
||||||
|
}
|
||||||
void (el.offsetHeight)
|
void (el.offsetHeight)
|
||||||
|
for (const key of Object.keys(diffedStyle)) {
|
||||||
|
if (~key.indexOf('ransition')) continue
|
||||||
|
el.style[key] = memorizedInlineStyle[key]
|
||||||
|
}
|
||||||
el.style.transition = memorizedTransition
|
el.style.transition = memorizedTransition
|
||||||
el.style.backgroundColor = memorizedBackgroundColor
|
el.style.backgroundColor = memorizedBackgroundColor
|
||||||
return nextBackgroundColor
|
return nextBackgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
let cachedNextBackgroundColor = null
|
let cachedNextBackgroundColor = null
|
||||||
|
let cachedCSSStyleDeclaration = new WeakMap()
|
||||||
let callCount = 0
|
let callCount = 0
|
||||||
|
|
||||||
function cache () {
|
function cache () {
|
||||||
@ -111,7 +85,15 @@ export default {
|
|||||||
let cursor = this.$el
|
let cursor = this.$el
|
||||||
while (cursor.parentElement) {
|
while (cursor.parentElement) {
|
||||||
cursor = cursor.parentElement
|
cursor = cursor.parentElement
|
||||||
const backgroundColor = window.getComputedStyle(cursor).backgroundColor
|
let backgroundColor = null
|
||||||
|
let CSSStyleDeclaration = cachedCSSStyleDeclaration.get(cursor)
|
||||||
|
if (CSSStyleDeclaration) {
|
||||||
|
backgroundColor = CSSStyleDeclaration.backgroundColor
|
||||||
|
} else {
|
||||||
|
CSSStyleDeclaration = window.getComputedStyle(cursor)
|
||||||
|
cachedCSSStyleDeclaration.set(cursor, CSSStyleDeclaration)
|
||||||
|
backgroundColor = CSSStyleDeclaration.backgroundColor
|
||||||
|
}
|
||||||
if (backgroundColor && backgroundColor !== 'rgba(0, 0, 0, 0)') {
|
if (backgroundColor && backgroundColor !== 'rgba(0, 0, 0, 0)') {
|
||||||
if (cachedNextBackgroundColor) {
|
if (cachedNextBackgroundColor) {
|
||||||
const nextBackgroundColor = cachedNextBackgroundColor.get(cursor)
|
const nextBackgroundColor = cachedNextBackgroundColor.get(cursor)
|
||||||
|
Loading…
Reference in New Issue
Block a user