Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(helpers): only deep merge plain objects #20284

Merged
merged 4 commits into from
Aug 27, 2024

Conversation

cgodo
Copy link
Contributor

@cgodo cgodo commented Aug 6, 2024

Description

The defaults composable uses the mergeDeep helper to merge defaults. However, it is not able to merge properties with HTML elements, like for example, the attach property of all overlays, because it throws a maximum call stack size exceeded.

Changed the mergeDeep utility to handle objects with circular references and to avoid traversing Nodes. Also added two new tests to check these changes.

fixes #20278

Markup:

<script setup>
  const defaultsA = { VMenu: { attach: document.body } }
  const defaultsB = { VMenu: { attach: document.getElementById('app') } }
</script>

<template>
  <v-menu location="right">
    <template #activator="{ props }">
      <v-btn v-bind="props" class="ma-5">Menu</v-btn>
    </template>
    <v-list>
      <v-list-item title="Menu item" />
      <v-list-item title="Menu item" />
    </v-list>
  </v-menu>

  <v-defaults-provider :defaults="defaultsA">
    <v-defaults-provider :defaults="defaultsB">
      <v-menu location="right">
        <template #activator="{ props }">
          <v-btn v-bind="props" class="ma-5">Menu with defaults provider</v-btn>
        </template>
        <v-list>
          <v-list-item title="Menu item" />
          <v-list-item title="Menu item" />
        </v-list>
      </v-menu>
    </v-defaults-provider>
  </v-defaults-provider>
</template>

@KaelWD
Copy link
Member

KaelWD commented Aug 13, 2024

This function is called quite a lot and circular reference checking seems like it could add a fair bit of overhead, I think just a Object.getPrototypeOf(val) === Object.prototype might be good enough for detecting non-plain objects.

@cgodo
Copy link
Contributor Author

cgodo commented Aug 13, 2024

Yes, your suggestion would be simpler and even work for more non-plain objects, not just Nodes, so circular checks won't be necessary. I made the changes in mergeDeep and updated tests.

@cgodo cgodo changed the title fix(helpers): allow to mergeDeep circular references and Nodes fix(helpers): only deep merge plain objects Aug 13, 2024
@KaelWD KaelWD force-pushed the master branch 2 times, most recently from e20cfec to 2766105 Compare August 15, 2024 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug Report][3.6.14] Maximum call stack size exceeded when using elements in default options
2 participants