Skip to content

Commit

Permalink
fix(helpers): only deep merge plain objects (#20284)
Browse files Browse the repository at this point in the history
Co-authored-by: Kael <kaelwd@gmail.com>

fixes #20278
  • Loading branch information
cgodo authored Aug 27, 2024
1 parent e821d5d commit 8af59fc
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
10 changes: 10 additions & 0 deletions packages/vuetify/src/util/__tests__/helpers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,16 @@ describe('helpers', () => {
it('should use arrayFn function if provided', () => {
expect(mergeDeep({ a: ['foo'] }, { a: ['bar'] }, (a, b) => [...a, ...b])).toEqual({ a: ['foo', 'bar'] })
})

it('should not recursively merge non-plain objects', () => {
const plain = { a: 'foo' }
const div = document.createElement('div')
const span = document.createElement('span')

expect(mergeDeep({ a: plain }, { a: div }).a).toBe(div)
expect(mergeDeep({ a: div }, { a: plain }).a).toBe(plain)
expect(mergeDeep({ a: div }, { a: span }).a).toBe(span)
})
})

describe('destructComputed', () => {
Expand Down
17 changes: 11 additions & 6 deletions packages/vuetify/src/util/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ export function isObject (obj: any): obj is Record<string, any> {
return obj !== null && typeof obj === 'object' && !Array.isArray(obj)
}

export function isPlainObject (obj: any): obj is Record<string, any> {
let proto
return obj !== null && typeof obj === 'object' && (
(proto = Object.getPrototypeOf(obj)) === Object.prototype ||
proto === null
)
}

export function refElement (obj?: ComponentPublicInstance<any> | HTMLElement): HTMLElement | undefined {
if (obj && '$el' in obj) {
const el = obj.$el as HTMLElement
Expand Down Expand Up @@ -487,17 +495,14 @@ export function mergeDeep (
const targetProperty = target[key]

// Only continue deep merging if
// both properties are objects
if (
isObject(sourceProperty) &&
isObject(targetProperty)
) {
// both properties are plain objects
if (isPlainObject(sourceProperty) && isPlainObject(targetProperty)) {
out[key] = mergeDeep(sourceProperty, targetProperty, arrayFn)

continue
}

if (Array.isArray(sourceProperty) && Array.isArray(targetProperty) && arrayFn) {
if (arrayFn && Array.isArray(sourceProperty) && Array.isArray(targetProperty)) {
out[key] = arrayFn(sourceProperty, targetProperty)

continue
Expand Down

0 comments on commit 8af59fc

Please # to comment.