Skip to content

Commit 8b99246

Browse files
authored
Merge pull request #8070 from QwikDev/v2-blocking-parent-order
fix: blocking slot parent and parent order
2 parents c5eada7 + 96514d3 commit 8b99246

File tree

3 files changed

+97
-1
lines changed

3 files changed

+97
-1
lines changed

.changeset/ninety-pets-win.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/core': patch
3+
---
4+
5+
fix: blocking slot parent and parent order

packages/qwik/src/core/client/vnode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1701,7 +1701,7 @@ export const vnode_isDescendantOf = (vnode: VNode, ancestor: VNode): boolean =>
17011701
};
17021702

17031703
export const vnode_getProjectionParentOrParent = (vnode: VNode): VNode | null => {
1704-
return vnode.slotParent || vnode.parent;
1704+
return vnode.parent || vnode.slotParent;
17051705
};
17061706

17071707
export const vnode_getNode = (vnode: VNode | null): Element | Text | null => {

packages/qwik/src/core/shared/scheduler-rules.unit.tsx

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,97 @@ describe('findBlockingChore', () => {
784784
);
785785
expect(result).toBe(ancestorProjectionChore);
786786
});
787+
788+
it('should check parent before slotParent when both are set', () => {
789+
// This test verifies that vnode_getProjectionParentOrParent checks parent first
790+
// Set up: child has both parent and slotParent
791+
// parent has a blocking chore, slotParent does not
792+
const parentVNode = vnode_newVirtual();
793+
const slotParentVNode = vnode_newVirtual();
794+
const childVNode = vnode_newVirtual();
795+
796+
childVNode.parent = parentVNode;
797+
childVNode.slotParent = slotParentVNode;
798+
799+
const blockingChore = createMockChore(ChoreType.COMPONENT, parentVNode);
800+
(blockingChore.$host$ as VNode).chores = new ChoreArray();
801+
(blockingChore.$host$ as VNode).chores?.add(blockingChore);
802+
803+
const descendantChore = createMockChore(ChoreType.VISIBLE, childVNode);
804+
const choreQueue = new ChoreArray();
805+
const blockedChores = new Set<Chore>();
806+
const runningChores = new Set<Chore>();
807+
808+
const result = findBlockingChore(
809+
descendantChore,
810+
choreQueue,
811+
blockedChores,
812+
runningChores,
813+
container
814+
);
815+
// Should find the blocking chore on parent (not look at slotParent)
816+
expect(result).toBe(blockingChore);
817+
});
818+
819+
it('should not find slotParent blocking chore when parent exists', () => {
820+
// This test verifies that if parent is set (even if null/no chores),
821+
// slotParent is not checked
822+
const parentVNode = vnode_newVirtual();
823+
const slotParentVNode = vnode_newVirtual();
824+
const childVNode = vnode_newVirtual();
825+
826+
childVNode.parent = parentVNode; // parent set but no blocking chore
827+
childVNode.slotParent = slotParentVNode;
828+
829+
// Put a blocking chore on slotParent
830+
const blockingChore = createMockChore(ChoreType.COMPONENT, slotParentVNode);
831+
(blockingChore.$host$ as VNode).chores = new ChoreArray();
832+
(blockingChore.$host$ as VNode).chores?.add(blockingChore);
833+
834+
const descendantChore = createMockChore(ChoreType.VISIBLE, childVNode);
835+
const choreQueue = new ChoreArray();
836+
const blockedChores = new Set<Chore>();
837+
const runningChores = new Set<Chore>();
838+
839+
const result = findBlockingChore(
840+
descendantChore,
841+
choreQueue,
842+
blockedChores,
843+
runningChores,
844+
container
845+
);
846+
// Should NOT find the blocking chore on slotParent because parent is checked first
847+
// and we don't continue to slotParent when parent exists
848+
expect(result).toBeNull();
849+
});
850+
851+
it('should fall back to slotParent only when parent is null', () => {
852+
// This test verifies that slotParent is checked when parent is null
853+
const slotParentVNode = vnode_newVirtual();
854+
const childVNode = vnode_newVirtual();
855+
856+
childVNode.parent = null; // explicitly null
857+
childVNode.slotParent = slotParentVNode;
858+
859+
const blockingChore = createMockChore(ChoreType.COMPONENT, slotParentVNode);
860+
(blockingChore.$host$ as VNode).chores = new ChoreArray();
861+
(blockingChore.$host$ as VNode).chores?.add(blockingChore);
862+
863+
const descendantChore = createMockChore(ChoreType.VISIBLE, childVNode);
864+
const choreQueue = new ChoreArray();
865+
const blockedChores = new Set<Chore>();
866+
const runningChores = new Set<Chore>();
867+
868+
const result = findBlockingChore(
869+
descendantChore,
870+
choreQueue,
871+
blockedChores,
872+
runningChores,
873+
container
874+
);
875+
// Should find the blocking chore on slotParent since parent is null
876+
expect(result).toBe(blockingChore);
877+
});
787878
});
788879
});
789880

0 commit comments

Comments
 (0)