Skip to content

[QTI] Add an inline-only mode to TipTapEditor for gap match choices #6193

Closed

Description

@AlexVelezLl

❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.

Overview

Gap match choices (qti-gap-text) only allow inline content in QTI, so the rich text editor used for them should only offer inline formatting. TipTapEditor needs a way to be limited to inline-only features for a particular field. Any non-inline content that still reaches it should be converted to inline, whether it comes from stored data that was already broken or from the clipboard, so a gap match item can't be saved in a shape the schema rejects. This builds on #6151 and starts after it merges.

Complexity: Medium
Target branch: unstable

Context

  • TipTapEditor currently has one configuration: the full set of block and inline features, for every field that uses it.
  • After Bring back underline, strikethrough and align support, and remove RTE link support #6151, the editor saves underline and strikethrough as <span style="text-decoration"> and alignment as style="text-align", links are switched off, and pasted styles are filtered to the allowlist. Pasted blocks are kept.
  • The editor's Image and Small nodes are block nodes. Math is inline.
  • The QTI editor doesn't have a gap match interaction yet (today it has choice, text entry, ordering and associate). This task gives that interaction an editor it can use.
  • qti-gap-text allows only text and inline elements (XSD GapTextDType). The passage around the gaps is ordinary block content.

The Change

  • TipTapEditor should support an inline-only mode that a field can switch on. In this mode the content is a single inline run, with no paragraphs, headings, lists or other blocks.

  • In inline-only mode the editor should offer only these features, all of which qti-gap-text allows:

    Offered Not offered
    Bold, italic Format dropdown (headings, small text)
    Underline, strikethrough (from Bring back underline, strikethrough and align support, and remove RTE link support #6151) Bullet and numbered lists
    Subscript, superscript Code block
    Math Text alignment
    Inline code Images
    Undo / redo Line breaks
  • Features that aren't offered should be unavailable everywhere: toolbar, mobile toolbar, keyboard shortcuts and markdown-style input rules. Hiding the buttons isn't enough.

  • No line breaks. qti-gap-text allows <br>, but a gap answer is dropped mid-sentence into the passage and shown as a chip in the answer pool, so a line break would split the passage line and make the chip hard to read. Enter, Shift-Enter and Mod-Enter insert nothing.

  • Pasted content should be reduced to inline: blocks become inline text, line breaks become spaces, and allowed inline formatting and math are kept. Anything not allowed, images included, is dropped.

  • Stored content that contains blocks or line breaks should load as inline content without errors and save back as valid inline content.

  • The existing full editor stays unchanged for every other field, including the gap match passage.

Out of Scope

  • Building the gap match interaction editor itself (the passage, gap widgets and distractors list). This task only provides the inline-only editor mode it will use.
  • Images in gap choices (qti-gap-img, or inline images in qti-gap-text). In the design, gap answers are typed as text straight into the passage's gap widgets, so image distractors wouldn't make sense either.

Acceptance Criteria

General

  • TipTapEditor has an inline-only mode that a field can switch on; fields that don't switch it on work exactly as before
  • In inline-only mode the toolbar and mobile toolbar offer only bold, italic, underline, strikethrough, subscript, superscript, math, inline code, and undo/redo
  • In inline-only mode, keyboard shortcuts and markdown-style input rules can't create blocks (paragraphs, headings, lists, code blocks) or images
  • In inline-only mode, Enter, Shift-Enter and Mod-Enter insert nothing, including on touch keyboards
  • Pasting blocks keeps their text, allowed inline formatting and math as a single inline run, with each line break turned into a space; images and other disallowed content are dropped
  • Stored content that contains blocks or <br> loads without errors and saves back as inline content with no <br>
  • Content saved from inline-only mode validates as qti-gap-text content

Accessibility and i18n

  • Toolbar options that aren't available are left out, not shown disabled, so screen readers don't announce controls that do nothing

Testing

  • Tests cover the offered and removed toolbar options, Enter and Shift-Enter, pasting block content and line breaks, and loading stored block content in inline-only mode

References

AI usage

I used Claude Code to check the QTI 3 schema's content model for gap match, compare it with TipTapEditor's current features and the changes in #6151, and draft this issue. I reviewed and edited each section.

Activity

  1. changed the title [-]Add an inline-only mode to TipTapEditor for gap match choices[/-] [+][QTI] Add an inline-only mode to TipTapEditor for gap match choices[/+] on Sep 25, 2026
  2. added theissue type on Sep 29, 2026
  3. rtibblesbot commented on Sep 30, 2026

    @rtibblesbot
    Contributor

    Plan: An inlineOnly prop on TipTapEditor that makes a field hold one inline run, offering only what qti-gap-text allows (#6193).

    • Inline-only schema in useEditor
    • Flatten blocks to one inline run
    • inlineOnly prop on TipTapEditor
    • Toolbars offer only inline tools
    • Self-review the produced code

    Assumptions — the issue did not settle these; say so if one is wrong.

    • Flattened blocks are joined by a space; if a line break is wanted instead, toInlineHTML and the plain-text paste transform change.
    • Inline code and line break stay keyboard-only (Mod-e, backticks, Shift-Enter), as in the full editor; a toolbar button for either adds a task.
    • Copy, paste, clear formatting and minimize stay in the inline toolbar; if "offer only" excludes them, Task 4 drops them too.
    • Enter does nothing in inline mode; if it should insert a line break, Task 1 adds a keymap.
    • Inline-only mode supports format="html" only; markdown support would need serializer work for an inline doc.
    • Stored block content is rewritten on the next blur or minimize, not on load; an eager rewrite would emit update from mount.

    @rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

    How was this generated?
    • Implemented code following the pre-approved plan using test-driven development (red-green-refactor)
    • Ran the project's full test suite and linter before committing
    • For UI changes: captured live screenshots to verify rendering
    • For backend changes: verified with example API/CLI output
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions