Feat: single runnable code block plugin for the editor - #56
Merged
Conversation
Merges the code block feature and the separate "executable" runtime dropdown into one CKEditor plugin. It requires CodeBlockEditing and provides its own `codeBlock` toolbar item, so neither `CodeBlock` nor a second toolbar entry is needed any more. Code block settings now live in a contextual balloon that follows the caret into any code block, holding the language, the runtime, and an "editable code" toggle (off by default) that only applies once a runtime is chosen. The same panel runs the snippet through the same WebSocket channel the published article uses and shows its output, so authors can try a block without leaving the editor. Runnable blocks are labelled with their runtime next to the language label in the editing view. Published articles honour the new flag: the CodeMirror editor is read-only unless the block is runnable and marked editable. The data contract is unchanged and back-compatible — `data-executable` plus the new `data-executable-editable` on `<code>` — and upcast now migrates those attributes into real model attributes, including legacy content carrying them on `<pre>`, instead of leaving them to General HTML Support. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Combines the code block feature and the separate "executable" runtime dropdown into one CKEditor plugin, adds a proper settings panel for code blocks, and makes snippets runnable inside the editor — not just in the published article.
The plugin requires
CodeBlockEditingand registers its owncodeBlocktoolbar item (split button: insert + language list + "Code block settings"), soCodeBlockand the secondexecutabletoolbar entry are gone from the editor config. The oldexecutable-code-block-plugin.tsis deleted.Component settings
A contextual balloon follows the caret into any code block:
runCodeWebSocket call the published page uses (wired via the newrunnableCodeBlock: { onRun, translate, direction }config).useI18n()), since the panel is translated by the app dictionary while the CKEditor UI language staysen. New UI strings added toen.json/fa.json.Published rendering
CodeHighlightnow honours the flag: CodeMirror is read-only unless the block is runnable and marked editable; the reset control follows the same condition, and run controls key off the runtime rather than the mere presence of the attribute object.Data contract
Unchanged and back-compatible:
data-executable="<runtime>"plus the newdata-executable-editable="true"on<code>, which the article body parser already maps toexecutable.editable. Upcast now migrates both into real model attributes — including legacy content carrying them on<pre>— and strips them from the General-HTML-Support bag so they are never written twice.Testing
Verified in a headless CKEditor instance (jsdom): loading, both commands, panel bindings, running with output, and data round-tripping.
<pre><code class="language-go" data-executable="go-1.24" data-executable-editable="true">survives load→save byte-identically and unrelated GHS attributes are preserved.npm run buildpasses; the repo has no jest tests.Not covered by that: real balloon positioning and pointer interaction in a browser — worth a quick manual pass in the dashboard editor.
🤖 Generated with Claude Code