Pārlūkot izejas kodu

Fix directive handler flushing order

Caleb Porzio 3 gadi atpakaļ
vecāks
revīzija
8ac8f31264

+ 6 - 6
index.html

@@ -8,11 +8,11 @@
     <!-- <script src="https://unpkg.com/alpinejs@3.0.0/dist/cdn.min.js" defer></script> -->
     <!-- <script src="https://unpkg.com/alpinejs@3.0.0/dist/cdn.min.js" defer></script> -->
 
 
     <!-- Play around. -->
     <!-- Play around. -->
-    <div x-data="{ open: false }">
-        <button @click="open = !open">Toggle</button>
+    <div x-data="{ html: '<span x-text=&quot;foo&quot;></span>', foo: 'bar' }">
+        <template x-if="true">
+            <h1>yoyoyo</h1>
+        </template>
 
 
-        <span x-show="open">
-            Content...
-        </span>
+        <div x-html="html"></div>
     </div>
     </div>
-</html>
+</html>

+ 12 - 3
packages/alpinejs/src/directives.js

@@ -34,13 +34,22 @@ export function directives(el, attributes, originalAttributeOverride) {
 }
 }
 
 
 let isDeferringHandlers = false
 let isDeferringHandlers = false
-let directiveHandlerStack = []
+let directiveHandlerStacks = new Map
+let currentHandlerStackKey = Symbol()
 
 
 export function deferHandlingDirectives(callback) {
 export function deferHandlingDirectives(callback) {
     isDeferringHandlers = true
     isDeferringHandlers = true
 
 
+    let key = Symbol()
+
+    currentHandlerStackKey = key
+
+    directiveHandlerStacks.set(key, [])
+
     let flushHandlers = () => {
     let flushHandlers = () => {
-        while (directiveHandlerStack.length) directiveHandlerStack.shift()()
+        while (directiveHandlerStacks.get(key).length) directiveHandlerStacks.get(key).shift()()
+
+        directiveHandlerStacks.delete(key)
     }
     }
 
 
     let stopDeferring = () => { isDeferringHandlers = false; flushHandlers() }
     let stopDeferring = () => { isDeferringHandlers = false; flushHandlers() }
@@ -82,7 +91,7 @@ export function getDirectiveHandler(el, directive) {
 
 
         handler = handler.bind(handler, el, directive, utilities)
         handler = handler.bind(handler, el, directive, utilities)
 
 
-        isDeferringHandlers ? directiveHandlerStack.push(handler) : handler()
+        isDeferringHandlers ? directiveHandlerStacks.get(currentHandlerStackKey).push(handler) : handler()
     }
     }
 
 
     fullHandler.runCleanups = doCleanup
     fullHandler.runCleanups = doCleanup

+ 14 - 0
tests/cypress/integration/directives/x-html.spec.js

@@ -33,5 +33,19 @@ test('x-html allows alpine code within',
     ({ get }) => {
     ({ get }) => {
         get('h1').should(haveText('baz'))
         get('h1').should(haveText('baz'))
     }
     }
+)
+
+test.only('x-html runs even after x-if or x-for',
+    html`
+        <div x-data="{ html: '<span x-text=&quot;foo&quot;></span>', foo: 'bar' }">
+            <template x-if="true">
+                <h1>yoyoyo</h1>
+            </template>
 
 
+            <div x-html="html"></div>
+        </div>
+    `,
+    ({ get }) => {
+        get('span').should(haveText('bar'))
+    }
 )
 )