From 8136607e0782646cd095b6e3ff8ece63033df390 Mon Sep 17 00:00:00 2001 From: Andrey Oganesyan Date: Thu, 2 Jan 2025 23:13:33 +0400 Subject: [PATCH] fix(core): Fixed elementIsChildOf returning false for nested web components (#7762) * 7761: Fixed elementIsChildOf returning false for nested web components; added .mjs files to prettier job * do this check only for the wrapper-slot case fixes #7761 --------- Co-authored-by: Vladimir Kharlampidi --- .eslintrc.cjs | 2 +- package.json | 2 +- src/modules/a11y/a11y.mjs | 2 +- src/shared/utils.mjs | 23 +++++++++++++++++++++-- src/vue/get-children.mjs | 10 +++------- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 2dceb4ec4..2bb5bef4d 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -36,7 +36,7 @@ module.exports = { ecmaFeatures: { jsx: true, }, - ecmaVersion: 2018, + ecmaVersion: 2021, sourceType: 'module', }, diff --git a/package.json b/package.json index 3ee71ead5..17a1ea36c 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "element": "npm run build && concurrently --kill-others \"vite ./playground/element\" \"npm run watch\" ", "react": "npm run build && concurrently --kill-others \"vite ./playground/react\" \"npm run watch\"", "vue": "npm run build && concurrently --kill-others \"vite ./playground/vue\" \"npm run watch\"", - "prettier": "prettier \"**/*.+(js|json|scss|css|less|ts|jsx)\"", + "prettier": "prettier \"**/*.+(js|json|scss|css|less|ts|jsx|mjs)\"", "format": "npm run prettier -- --write", "check-format": "npm run prettier -- --list-different", "lint": "eslint --ext .js,.jsx .", diff --git a/src/modules/a11y/a11y.mjs b/src/modules/a11y/a11y.mjs index f76177d83..384aa4a80 100644 --- a/src/modules/a11y/a11y.mjs +++ b/src/modules/a11y/a11y.mjs @@ -19,7 +19,7 @@ export default function A11y({ swiper, extendParams, on }) { itemRoleDescriptionMessage: null, slideRole: 'group', id: null, - scrollOnFocus: true + scrollOnFocus: true, }, }); diff --git a/src/shared/utils.mjs b/src/shared/utils.mjs index 0638f70e8..c69ec5750 100644 --- a/src/shared/utils.mjs +++ b/src/shared/utils.mjs @@ -213,12 +213,31 @@ function elementChildren(element, selector = '') { } return children.filter((el) => el.matches(selector)); } +function elementIsChildOfSlot(el, slot) { + // Breadth-first search through all parent's children and assigned elements + const elementsQueue = [slot]; + while (elementsQueue.length > 0) { + const elementToCheck = elementsQueue.shift(); + if (el === elementToCheck) { + return true; + } + elementsQueue.push( + ...elementToCheck.children, + ...(elementToCheck.shadowRoot?.children || []), + ...(elementToCheck.assignedElements?.() || []), + ); + } +} function elementIsChildOf(el, parent) { - const isChild = parent.contains(el); + let isChild = parent.contains(el); if (!isChild && parent instanceof HTMLSlotElement) { const children = [...parent.assignedElements()]; - return children.includes(el); + isChild = children.includes(el); + if (!isChild) { + isChild = elementIsChildOfSlot(el, parent); + } } + return isChild; } function showWarning(text) { diff --git a/src/vue/get-children.mjs b/src/vue/get-children.mjs index 53f2fec17..a12b9d274 100644 --- a/src/vue/get-children.mjs +++ b/src/vue/get-children.mjs @@ -18,13 +18,9 @@ function getChildren(originalSlots = {}, slidesRef, oldSlidesRef) { if (isFragment && vnode.children) { getSlidesFromElements(vnode.children, slotName); } else if ( - ( - vnode.type && - (vnode.type.name === 'SwiperSlide' || vnode.type.name === 'AsyncComponentWrapper') - ) || - ( - vnode.componentOptions && (vnode.componentOptions.tag === 'SwiperSlide') - ) + (vnode.type && + (vnode.type.name === 'SwiperSlide' || vnode.type.name === 'AsyncComponentWrapper')) || + (vnode.componentOptions && vnode.componentOptions.tag === 'SwiperSlide') ) { slides.push(vnode); } else if (slots[slotName]) {