diff --git a/contentcuration/contentcuration/frontend/shared/utils/testing.js b/contentcuration/contentcuration/frontend/shared/utils/testing.js index cc78737696..37c3e4cd45 100644 --- a/contentcuration/contentcuration/frontend/shared/utils/testing.js +++ b/contentcuration/contentcuration/frontend/shared/utils/testing.js @@ -25,3 +25,18 @@ export async function resetMockChannelScope() { Session.currentChannelId = Session._oldCurrentChannelId; delete Session._oldCurrentChannelId; } + +/** + * Tab into the component under test, entering backwards from a sentinel after it. + * + * Tabbing forward from the start of the document stops on the CSRF input the + * shared Jest setup leaves at the top of the body. + * + * @param {import('@testing-library/user-event').UserEvent} user + */ +export async function tabIn(user) { + const sentinel = document.body.appendChild(document.createElement('button')); + sentinel.focus(); + await user.tab({ shift: true }); + sentinel.remove(); +} diff --git a/contentcuration/contentcuration/frontend/shared/views/QTIEditor/components/ClickableRegion/index.vue b/contentcuration/contentcuration/frontend/shared/views/QTIEditor/components/ClickableRegion/index.vue index 7a0616624b..80ff7e1d42 100644 --- a/contentcuration/contentcuration/frontend/shared/views/QTIEditor/components/ClickableRegion/index.vue +++ b/contentcuration/contentcuration/frontend/shared/views/QTIEditor/components/ClickableRegion/index.vue @@ -85,9 +85,11 @@ } } + /* No z-index: the stacking context it opens would trap the fixed toolbars and + popovers of an editor in the slot. Being positioned and later in the DOM + already paints this above the overlay button. */ .content-wrapper { position: relative; - z-index: 1; } diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue index 0e114c49ea..bda590a756 100644 --- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue +++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditor.vue @@ -13,6 +13,8 @@ :aria-label="editorMode === 'edit' ? TipTapEditorLabel$() : TipTapViewerLabel$()" aria-multiline="true" @keydown="handleContainerKeydown" + @focusin="hasFocusWithin = true" + @focusout="handleFocusout" >
-
- - -
+
+ + +
@@ -167,6 +171,15 @@ 'insert-math': target => mathHandler.openCreateMathModal({ targetElement: target }), })); + // Tracked on the container rather than on the editor content: tabbing out of + // the content blurs it, and the re-render that blur schedules would unmount + // the mobile formatting bar before focus could land on it. `focusout` is the + // only signal that names where focus is going, so it alone clears this. + const hasFocusWithin = ref(false); + const handleFocusout = event => { + hasFocusWithin.value = editorContainer.value.contains(event.relatedTarget); + }; + const handleDrop = event => { const file = event.dataTransfer.files[0]; if (file) { @@ -278,7 +291,8 @@ return { editorContainer, isReady, - isFocused, + hasFocusWithin, + handleFocusout, handleDrop, linkHandler, editor, diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditorStrings.js b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditorStrings.js index ba1b764548..b403506d65 100644 --- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditorStrings.js +++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/TipTapEditorStrings.js @@ -383,10 +383,6 @@ const MESSAGES = { message: 'Insert content menu', context: 'Accessibility label for the insert content menu button', }, - insertContentOption: { - message: 'Insert content option', - context: 'Accessibility label for the insert content dropdown menu', - }, }; let TipTapEditorStrings = null; diff --git a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/EditorToolbar.vue b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/EditorToolbar.vue index df6732dff6..c159c85207 100644 --- a/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/EditorToolbar.vue +++ b/contentcuration/contentcuration/frontend/shared/views/TipTapEditor/TipTapEditor/components/EditorToolbar.vue @@ -81,6 +81,7 @@