Skip to content

html-element

Obsidian-specific HTML element helpers.

Unlike the Obsidian-runtime-agnostic helpers in src/html-element.ts, these depend on Obsidian-specific presentation — the markdown-rendered CSS class that styles rendered markdown, and the Editor > Spellcheck vault setting — so they live in the Obsidian layer and use Obsidian’s createEl DOM augmentation.

Interface Description
ApplySpellcheckModeParams Options for applySpellcheckMode.
Function Description
appendCodeBlock Appends a code block to the given DocumentFragment or HTMLElement, styled to match Obsidian’s rendered-markdown inline code.
appendTextOrFragmentClone Appends a string as text, or a fresh deep clone of a DocumentFragment, to the given element. Appending a fragment moves its children out of it, so a fragment rendered more than once — a notice and a settings banner, or a banner rendered again on every refresh — would be empty from the second render on. Cloning leaves the caller’s fragment intact for the next render.
applySpellcheckMode Sets the spellcheck attribute on an element from a SpellcheckMode. The attribute has to be set explicitly, because both of the surfaces that need this are born with spellcheck="false": AbstractTextComponent forces it onto every text component, and Obsidian builds every SuggestModal input with it without consulting Editor > Spellcheck at all. Which of those a given box wants is a call-site decision, and the distinction that holds up is what the box is FOR: one that only FINDS something is a search field and stays unchecked, because squiggles under half-typed fragments are noise; one that NAMES something is a prose field and follows the setting, the way Obsidian’s own inline title and file-explorer rename do. Call it again whenever that answer changes — a picker that switches between finding and creating flips modes mid-open, and the attribute has to follow. The name being typed may be a PATH rather than a bare basename, so folder segments get checked too. That is what Obsidian’s own inline rename does, and the alternative — checking only the last segment — cannot be expressed as an attribute.
asCodeBlock Marks a value so that createFragmentWithCodeBlocks renders it as an inline code block. Wrap a value with this before handing it to t(), and the translated message comes back with the value already in place, delimited: ts createFragmentWithCodeBlocks(t(($) => $.obsidianDevUtils.pluginSuggestion.installed, \{ pluginName: asCodeBlock(pluginName) \})); The marker travels WITH the value rather than being a positional placeholder the caller matches up afterwards. That distinction is the whole point: a message naming two plugins is interpolated by name, and a translation is free to put them in either order, so anything that re-associated values with placeholders by position would silently swap them the moment a sentence read the other way round.
createFragmentWithCodeBlocks Builds a DocumentFragment from an already-translated message, rendering every value that was wrapped in asCodeBlock as an inline code block and the rest as plain text. The message stays ONE translatable unit. Splitting a sentence into a prefix and a suffix around the value is the obvious alternative and it does not survive translation: a language that reorders the clause, or that needs different case on the surrounding words, cannot express that through two fixed halves. Here the value sits wherever the translation puts it, and only its rendering is decided. A message with nothing marked comes back as plain text, so this is safe to apply to any message.