From b1164cfccbb36b72431271b33caeea5c937d8e82 Mon Sep 17 00:00:00 2001 From: deadem Date: Mon, 10 Feb 2025 16:54:04 +0300 Subject: [PATCH 1/2] Fix: Ensure IE11 compatibility for `contains` function by handling text nodes --- src/diff/children.js | 4 ++-- src/util.js | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/diff/children.js b/src/diff/children.js index 5053a51174..784476fdca 100644 --- a/src/diff/children.js +++ b/src/diff/children.js @@ -7,7 +7,7 @@ import { MATCHED, UNDEFINED } from '../constants'; -import { isArray } from '../util'; +import { isArray, contains } from '../util'; import { getDomSibling } from '../component'; /** @@ -339,7 +339,7 @@ function insert(parentVNode, oldDom, parentDom) { return oldDom; } else if (parentVNode._dom != oldDom) { - if (oldDom && parentVNode.type && !parentDom.contains(oldDom)) { + if (oldDom && parentVNode.type && !contains(parentDom, oldDom)) { oldDom = getDomSibling(parentVNode); } parentDom.insertBefore(parentVNode._dom, oldDom || null); diff --git a/src/util.js b/src/util.js index 647519175f..16255d343c 100644 --- a/src/util.js +++ b/src/util.js @@ -25,4 +25,21 @@ export function removeNode(node) { if (node && node.parentNode) node.parentNode.removeChild(node); } +/** + * Checks whether a given node is contained within a specified parent node's subtree. + * This function is a workaround for Internet Explorer 11's limited support for + * `Element.prototype.contains()`, which works only for DOM elements and does not + * support text nodes. + * + * @param {import('./internal').PreactElement} parent - The parent node within which to search for the `node`. + * @param {import('./index').ContainerNode} node - The node to check for containment within the `parent` subtree. + */ +export function contains(parent, node) { + while (node) { + if (node === parent) return true; + node = node.parentNode; + } + return false; +} + export const slice = EMPTY_ARR.slice; From 9a06c296e3f3160b815bdcbe24241737ab4043dd Mon Sep 17 00:00:00 2001 From: deadem Date: Tue, 11 Feb 2025 18:44:53 +0300 Subject: [PATCH 2/2] * add special case for portals handling --- compat/src/portals.js | 2 +- src/util.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/compat/src/portals.js b/compat/src/portals.js index c480a3d3a3..b48f2356f5 100644 --- a/compat/src/portals.js +++ b/compat/src/portals.js @@ -39,7 +39,7 @@ function Portal(props) { nodeType: 1, parentNode: container, childNodes: [], - contains: () => true, + isPortal: true, // Technically this isn't needed appendChild(child) { this.childNodes.push(child); diff --git a/src/util.js b/src/util.js index 16255d343c..1907e525b9 100644 --- a/src/util.js +++ b/src/util.js @@ -35,6 +35,8 @@ export function removeNode(node) { * @param {import('./index').ContainerNode} node - The node to check for containment within the `parent` subtree. */ export function contains(parent, node) { + if ('isPortal' in parent) return true; + while (node) { if (node === parent) return true; node = node.parentNode;