|
1 | 1 | import { isDev } from '@qwik.dev/core/build'; |
2 | | -import { _CONST_PROPS, _EFFECT_BACK_REF, _VAR_PROPS } from '../internal'; |
3 | 2 | import { clearAllEffects, clearEffectSubscription } from '../reactive-primitives/cleanup'; |
4 | 3 | import { WrappedSignalImpl } from '../reactive-primitives/impl/wrapped-signal-impl'; |
5 | 4 | import type { Signal } from '../reactive-primitives/signal.public'; |
@@ -31,7 +30,7 @@ import type { QRL } from '../shared/qrl/qrl.public'; |
31 | 30 | import type { HostElement, QElement, QwikLoaderEventScope, qWindow } from '../shared/types'; |
32 | 31 | import { DEBUG_TYPE, QContainerValue, VirtualType } from '../shared/types'; |
33 | 32 | import { escapeHTML } from '../shared/utils/character-escaping'; |
34 | | -import { _OWNER, _PROPS_HANDLER } from '../shared/utils/constants'; |
| 33 | +import { _CONST_PROPS, _OWNER, _PROPS_HANDLER, _VAR_PROPS } from '../shared/utils/constants'; |
35 | 34 | import { |
36 | 35 | fromCamelToKebabCase, |
37 | 36 | getEventDataFromHtmlAttribute, |
@@ -97,6 +96,7 @@ import type { VirtualVNode } from '../shared/vnode/virtual-vnode'; |
97 | 96 | import type { TextVNode } from '../shared/vnode/text-vnode'; |
98 | 97 | import { markVNodeDirty } from '../shared/vnode/vnode-dirty'; |
99 | 98 | import { ChoreBits } from '../shared/vnode/enums/chore-bits.enum'; |
| 99 | +import { _EFFECT_BACK_REF } from '../reactive-primitives/backref'; |
100 | 100 |
|
101 | 101 | export const vnode_diff = ( |
102 | 102 | container: ClientContainer, |
@@ -819,8 +819,8 @@ export const vnode_diff = ( |
819 | 819 |
|
820 | 820 | function diffProps( |
821 | 821 | vnode: ElementVNode, |
822 | | - srcAttrs: Record<string, any>, |
823 | | - dstAttrs: Record<string, any>, |
| 822 | + newAttrs: Record<string, any>, |
| 823 | + oldAttrs: Record<string, any>, |
824 | 824 | currentFile: string | null |
825 | 825 | ): boolean { |
826 | 826 | vnode_ensureElementInflated(vnode); |
@@ -904,21 +904,27 @@ export const vnode_diff = ( |
904 | 904 | }; |
905 | 905 |
|
906 | 906 | // Actual diffing logic |
907 | | - for (const key in srcAttrs) { |
908 | | - const srcValue = srcAttrs[key]; |
| 907 | + // Apply all new attributes |
| 908 | + for (const key in newAttrs) { |
| 909 | + const newValue = newAttrs[key]; |
909 | 910 | const isEvent = isHtmlAttributeAnEventName(key); |
910 | 911 |
|
911 | | - if (key in dstAttrs) { |
912 | | - if (srcValue !== dstAttrs[key]) { |
913 | | - isEvent ? recordJsxEvent(key, srcValue) : record(key, srcValue); |
| 912 | + if (key in oldAttrs) { |
| 913 | + if (newValue !== oldAttrs[key]) { |
| 914 | + isEvent ? recordJsxEvent(key, newValue) : record(key, newValue); |
914 | 915 | } |
915 | 916 | } else { |
916 | | - isEvent ? recordJsxEvent(key, srcValue) : record(key, srcValue); |
| 917 | + isEvent ? recordJsxEvent(key, newValue) : record(key, newValue); |
917 | 918 | } |
918 | 919 | } |
919 | 920 |
|
920 | | - for (const key in dstAttrs) { |
921 | | - if (!(key in srcAttrs) && !isHtmlAttributeAnEventName(key)) { |
| 921 | + // Remove attributes that no longer exist in new props |
| 922 | + for (const key in oldAttrs) { |
| 923 | + if ( |
| 924 | + !(key in newAttrs) && |
| 925 | + !key.startsWith(HANDLER_PREFIX) && |
| 926 | + !isHtmlAttributeAnEventName(key) |
| 927 | + ) { |
922 | 928 | record(key, null); |
923 | 929 | } |
924 | 930 | } |
|
0 commit comments