فهرست منبع

fix: handle deepEqual edge case of DOM elements

alvarosabu 2 سال پیش
والد
کامیت
e5285d6346
2فایلهای تغییر یافته به همراه26 افزوده شده و 1 حذف شده
  1. 7 1
      src/core/nodeOps.ts
  2. 19 0
      src/utils/index.ts

+ 7 - 1
src/core/nodeOps.ts

@@ -192,8 +192,14 @@ export const nodeOps: RendererOptions<TresObject, TresObject> = {
         const prevArgs = _prevValue ?? []
         const args = nextValue ?? []
         const instanceName = node.userData.tres__name || node.type
-
+        console.log('replacing', {
+          instanceName,
+          args,
+          prevArgs,
+          diff: !deepArrayEqual(prevArgs, args)
+        })
         if (instanceName && !deepArrayEqual(prevArgs, args)) {
+
           root = Object.assign(prevNode, new catalogue.value[instanceName](...nextValue))
         }
         return

+ 19 - 0
src/utils/index.ts

@@ -26,6 +26,10 @@ const HTML_TAGS =
 
 export const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS)
 
+export function isDOMElement(obj: any): obj is HTMLElement {
+  return obj && obj.nodeType === 1;
+}
+
 export function kebabToCamel(str: string) {
   return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase())
 }
@@ -77,6 +81,21 @@ export const set = (obj: any, path: string | string[], value: any): void => {
 
 
 export function deepEqual(a: any, b: any): boolean {
+
+  if (isDOMElement(a) && isDOMElement(b)) {
+    const attrsA = a.attributes;
+    const attrsB = b.attributes;
+
+    if (attrsA.length !== attrsB.length) return false;
+
+    for (let i = 0; i < attrsA.length; i++) {
+      const { name, value } = attrsA[i];
+      if (b.getAttribute(name) !== value) return false;
+    }
+
+    return true;
+  }
+
   // If both are primitives, return true if they are equal
   if (a === b) return true;