Просмотр исходного кода

Support immediate circular reference protection in x-data

Caleb Porzio 4 лет назад
Родитель
Сommit
56215a47f8

+ 1 - 1
packages/alpinejs/src/interceptor.js

@@ -11,7 +11,7 @@ export function initInterceptors(data) {
                 Object.defineProperty(obj, key, result[0])
             }
 
-            if (isObject(value)) {
+            if (isObject(value) && value !== obj) {
                 recurse(value, path)
             }
         })

+ 65 - 0
tests/cypress/integration/custom-interceptors.spec.js

@@ -0,0 +1,65 @@
+import { haveText, html, test } from '../utils'
+
+test('can register custom interceptors',
+    [html`
+        <div x-data="{ foo: $magic() }">
+            <span x-text="foo"></span>
+        </div>
+    `,
+    `
+        Alpine.magic('magic', () => {
+            return Alpine.interceptor((key, path) => {
+                return {
+                    init(initialValue, setter) {
+                        setter(key+path)
+                    },
+                    set(value, setter) {
+                        setter(value)
+                    },
+                }
+            })
+        })
+    `],
+    ({ get }) => get('span').should(haveText('foofoo'))
+)
+
+test('interceptors are nesting aware',
+    [html`
+        <div x-data="{ foo: { bar: { baz: $magic() }}}">
+            <span x-text="foo.bar.baz"></span>
+        </div>
+    `,
+    `
+        Alpine.magic('magic', () => {
+            return Alpine.interceptor((key, path) => {
+                return {
+                    init(initialValue, setter) {
+                        setter(key+path)
+                    },
+                    set(value, setter) {
+                        setter(value)
+                    },
+                }
+            })
+        })
+    `],
+    ({ get }) => get('span').should(haveText('bazfoo.bar.baz'))
+)
+
+test('interceptor system prevents against circular references',
+    [html`
+        <div x-data="{ foo: $foo }">
+            <span x-text="'...'">
+        </div>
+    `,
+    `
+        Alpine.magic('foo', () => {
+            return {
+                get anyGivenProperty() {
+                    return this
+                }
+            }
+        })
+    `],
+    ({ get }) => get('span').should(haveText('...'))
+)