-
-
Notifications
You must be signed in to change notification settings - Fork 377
Description
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
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
- Read the Contributing Guidelines
- Read the Documentation
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussions