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

isPlainObject incorrectly identifies objects wrapped in a Proxy object in Safari 10 #1378

Closed
4 tasks done
reed-soul opened this issue Apr 24, 2023 · 0 comments
Closed
4 tasks done

Comments

@reed-soul
Copy link
Contributor

Reporting a bug?

Hi there,

I encountered a bug in vue-i18n that occurs in Safari 10. Specifically, the isPlainObject method used in vue-i18n incorrectly identifies objects wrapped in a Proxy object as non-plain objects, leading to an empty messages object and the inability to retrieve localized content.

To reproduce the issue, I created a simple Vue app that uses vue-i18n to load localized content from a messages object. The messages object was created using the ref method in Vue to wrap a plain object. When running the app in Safari 10, the messages object is incorrectly identified as a non-plain object, resulting in an empty messages object and no localized content.

I believe the issue is caused by the use of the Object.prototype.toString method to check if an object is a plain object in the isPlainObject method in vue-i18n. This method does not correctly identify objects wrapped in a Proxy object as plain objects in Safari 10.

To fix the issue, I suggest updating the isPlainObject method in vue-i18n to use the Object.prototype.constructor property to check if an object is a plain object. This method correctly identifies objects wrapped in a Proxy object as plain objects in all browsers, including Safari 10.

Behavior of Object.prototype.toString in safari10

 import {ref} from 'vue'

const obj = {}
const proxyObj = new Proxy({},{})

console.log( Object.prototype.toString.call( object ) ) // output:  [object Object]
console.log( Object.prototype.toString.call( proxyObj )) //  output: [object ProxyObject]
console.log( Object.prototype.toString.call( ref( object ))) //  output: [object ProxyObject]

As shown in the figure

image

image

The following methods are recommended

I would like to recommend using the following isPlainObject method instead of the existing method in vue-i18n:

function isPlainObject(obj) {
  if (typeof obj !== 'object' || obj === null) return false
  const proto = Object.getPrototypeOf(obj)
  return proto === null || proto.constructor === Object
}

The suggested isPlainObject method, uses the Object.prototype.constructor property to check if an object is a plain object. This method is more reliable and performs well in all browsers, including Safari 10. It correctly identifies objects wrapped in a Proxy object as plain objects, which ensures that localized content can be retrieved correctly.

I hope this explanation helps!
I would be happy to contribute a fix for this issue if needed. Please let me know if you have any questions or if there is anything else I can provide to help resolve this issue.

Best regards

Expected behavior

import {ref) from 'vue'

const messages = ref(localMessages)

isPlainObject(messages) === true
isPlainObject(new Proxy({},{}) === true

Reproduction

https://stackblitz.com/edit/vitejs-vite-blg7r3?file=src/App.vue

System Info

System:
    OS: Linux 5.15 Ubuntu 20.04.6 LTS (Focal Fossa)
    CPU: (16) x64 13th Gen Intel(R) Core(TM) i5-13500H
    Memory: 11.77 GB / 15.49 GB
    Container: Yes
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 18.14.2 - ~/.nvm/versions/node/v18.14.2/bin/node
    Yarn: 1.22.19 - /mnt/c/Program Files/nodejs/yarn
    npm: 9.5.0 - ~/.nvm/versions/node/v18.14.2/bin/npm
  npmPackages:
    @vitejs/plugin-legacy: ^4.0.2 => 4.0.2 
    @vitejs/plugin-vue: ^4.1.0 => 4.1.0 
    @vitejs/plugin-vue-jsx: ^3.0.0 => 3.0.0 
    @vue/tsconfig: ^0.1.3 => 0.1.3 
    vite: ^4.2.0 => 4.2.0 
    vite-plugin-html: ^3.2.0 => 3.2.0 
    vite-plugin-mock-dev-server: ^0.3.16 => 0.3.16 
    vite-plugin-vue-setup-extend: ^0.4.0 => 0.4.0 
    vite-plugin-vue-setup-inherit-attrs: ^1.0.8 => 1.0.8 
    vue: ^3.2.37 => 3.2.37 
    vue-i18n: ^9.2.2 => 9.2.2 
    vue-router: ^4.1.3 => 4.1.3 
    vue-tsc: ^1.0.12 => 1.0.12

Screenshot

No response

Additional context

No response

Validations

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

No branches or pull requests

2 participants