From e1a338eed47706aac506893bf87f56b452a7b139 Mon Sep 17 00:00:00 2001
From: Alex Simonides
Date: Thu, 26 Aug 2021 15:38:05 -0700
Subject: [PATCH] Fix partial-numeric string prop parsing
Internally Vue was using `parseFloat` for this,
and `parseFloat('1abc') === 1` rather than `NaN` like it is for
non-numeric strings
The fix was lifted from https://github.com/vuejs/vue-next/pull/4393,
so I'll double check whether that's been merged by the time
the rest of this is ready
---
demo-app/_vue-components/index.js | 2 +
demo-app/_vue-components/prop-tester.vue | 64 ++++++++++++++++++++++++
demo-app/_vue-components/user-list.vue | 42 +++++++++-------
demo-app/home/home.controller.js | 21 ++++++--
demo-app/home/home.html | 13 ++++-
demo-app/style.css | 15 ++++--
lib/vue-wrapper/index.js | 16 ++++++
7 files changed, 145 insertions(+), 28 deletions(-)
create mode 100644 demo-app/_vue-components/prop-tester.vue
diff --git a/demo-app/_vue-components/index.js b/demo-app/_vue-components/index.js
index 8817f75..367e601 100644
--- a/demo-app/_vue-components/index.js
+++ b/demo-app/_vue-components/index.js
@@ -1,10 +1,12 @@
import { defineNatively } from '@blueshift/ng-interop';
+import PropTester from './prop-tester.vue';
import UserItem from './user-item.vue';
import UserList from './user-list.vue';
defineNatively([
+ PropTester,
UserItem,
UserList,
]);
diff --git a/demo-app/_vue-components/prop-tester.vue b/demo-app/_vue-components/prop-tester.vue
new file mode 100644
index 0000000..9db812f
--- /dev/null
+++ b/demo-app/_vue-components/prop-tester.vue
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo-app/_vue-components/user-list.vue b/demo-app/_vue-components/user-list.vue
index 0aed3c5..1c39981 100644
--- a/demo-app/_vue-components/user-list.vue
+++ b/demo-app/_vue-components/user-list.vue
@@ -1,28 +1,34 @@
-
-
+
+
{{ headingText }}
-
+
+
aNumber: {{ aNumber+1 }}
aBoolean: {{ aBoolean }}
-
-
diff --git a/demo-app/home/home.controller.js b/demo-app/home/home.controller.js
index f50534d..a1e171a 100644
--- a/demo-app/home/home.controller.js
+++ b/demo-app/home/home.controller.js
@@ -4,11 +4,26 @@ class HomeCtrl {
'UserService',
];
+ name = 'AngularJS inside ng-wrapper vue component';
+ users = [];
+ selectedId = null;
+ testProps = {
+ title: '1string',
+ likes: 4,
+ is_published: true,
+ comment_ids: ['a1', '2b', 'c3'],
+ author: {
+ name: 'Alex',
+ published: true,
+ post_count: 10,
+ },
+ callback: function testCb() {},
+ promise: Promise.resolve(10),
+ };
+
+
constructor($scope, UserService) {
- this.name = 'AngularJS';
this.UserService = UserService;
- this.users = [];
- this.selectedId = null;
this.$scope = $scope;
}
diff --git a/demo-app/home/home.html b/demo-app/home/home.html
index fb61905..2fe3dcf 100644
--- a/demo-app/home/home.html
+++ b/demo-app/home/home.html
@@ -7,7 +7,7 @@ Hello {{ $ctrl.name }}!
+
diff --git a/demo-app/style.css b/demo-app/style.css
index b9483e8..e1e1a9d 100644
--- a/demo-app/style.css
+++ b/demo-app/style.css
@@ -1,11 +1,7 @@
:root {
--c-ng1: #B52E31;
--c-vue: #42b983;
-}
-
-h1,
-p {
- font-family: Lato;
+ font-family: 'Helvetica Neue', Arial, sans-serif;
}
#app {
@@ -13,11 +9,20 @@ p {
max-width: 100vw;
margin: 0 auto;
}
+h2 {
+ margin-top: 0;
+}
.list-container {
display: grid;
width: 100%;
grid-template-columns: repeat(2, 1fr);
+ gap: 1rem;
+}
+
+.vue-heading {
+ border-left: 4px solid var(--c-vue);
+ padding-left: 8px;
}
.user {
diff --git a/lib/vue-wrapper/index.js b/lib/vue-wrapper/index.js
index fcc653f..5dce607 100644
--- a/lib/vue-wrapper/index.js
+++ b/lib/vue-wrapper/index.js
@@ -378,6 +378,10 @@ export function defineGuardedCustomElement(options) {
})
}
+ _setAttr(key) {
+ this._setProp(camelize(key), parseNumber(this.getAttribute(key)), false);
+ }
+
_setProp(key, val, shouldReflect = true) {
if (key?.startsWith('ng')) {
// Skip any attributes that start with `ng-`
@@ -479,3 +483,15 @@ export function defineGuardedCustomElement(options) {
return customElementClass;
}
+
+/**
+ * @TODO: this can just be imported from the library once https://github.com/vuejs/vue-next/pull/4393 is merged
+ * @param {string|null} value
+ * @return {string|number}
+ */
+export function parseNumber(value) {
+ // for Number('') and Number(null) as they both become 0
+ if (!value) return '';
+ const casted = Number(value);
+ return value === 'NaN' || !Number.isNaN(casted) ? casted : value;
+}