diff --git a/core/src/components/PublicPageMenu/PublicPageMenuEntry.vue b/core/src/components/PublicPageMenu/PublicPageMenuEntry.vue index cf9b8668601fe..b995377796e42 100644 --- a/core/src/components/PublicPageMenu/PublicPageMenuEntry.vue +++ b/core/src/components/PublicPageMenu/PublicPageMenuEntry.vue @@ -42,13 +42,24 @@ defineEmits<{ }>() onMounted(() => { - const anchor = document.getElementById(`${props.id}--link`) as HTMLAnchorElement - // Make the `` a menuitem - anchor.role = 'menuitem' - // Prevent native click handling if required - if (props.clickOnly) { - anchor.onclick = (event) => event.preventDefault() + let attempts = 0 + const trySetRole = () => { + const anchor = document.getElementById(`${props.id}--link`) as HTMLAnchorElement | null + if (anchor) { + // Make the `` a menuitem + anchor.role = 'menuitem' + // Prevent native click handling if required + if (props.clickOnly) { + anchor.onclick = (event) => event.preventDefault() + } + return + } + if (attempts < 10) { + attempts++ + requestAnimationFrame(trySetRole) + } } + requestAnimationFrame(trySetRole) }) diff --git a/core/src/tests/components/PublicPageMenuExternalEntry.spec.ts b/core/src/tests/components/PublicPageMenuExternalEntry.spec.ts index ab56da8b691fe..32fc718a63792 100644 --- a/core/src/tests/components/PublicPageMenuExternalEntry.spec.ts +++ b/core/src/tests/components/PublicPageMenuExternalEntry.spec.ts @@ -6,6 +6,7 @@ import { enableAutoUnmount, mount } from '@vue/test-utils' import { afterEach, describe, expect, it } from 'vitest' import { defineComponent, h } from 'vue' +import PublicPageMenuEntryReal from '../../components/PublicPageMenu/PublicPageMenuEntry.vue' import PublicPageMenuExternalEntry from '../../components/PublicPageMenu/PublicPageMenuExternalEntry.vue' const PublicPageMenuEntry = defineComponent({ @@ -61,3 +62,23 @@ describe('PublicPageMenuExternalEntry', () => { expect(wrapper.get('li').attributes('data-details')).toBe('Nextcloud') }) }) + +describe('PublicPageMenuEntry', () => { + it('does not throw when the anchor is missing in DOM', () => { + const NcListItemStub = defineComponent({ + name: 'NcListItem', + setup() { + return () => h('li') + }, + }) + let wrapper + expect(() => { + wrapper = mount(PublicPageMenuEntryReal, { + props: { id: 'missing', label: 'Missing', href: 'https://example.com' }, + global: { stubs: { NcListItem: NcListItemStub } }, + }) + }).not.toThrow() + expect(wrapper!.find('li').exists()).toBe(true) + expect(document.getElementById('missing--link')).toBeNull() + }) +})