Conversation
- Replace vendored blockly_compressed.js, blocks_compressed.js, media/, and msg/en.js with Blockly v12.4.1 UMD bundles - Rewrite mythos_uncompressed.js for v12 API: DOMParser instead of Blockly.Xml.textToDom, fixed domToWorkspace arg order, workspace.getTopBlocks(), ES6 FieldTextArea class, removed goog.* dependencies - Fix block rendering in JavaFX: add BLOCK_CREATE listener with setTimeout(0) to re-queue all descendants after placement (works around JavaFX immediate- render mode dequeuing children before they initialise) - Convert 39 toolbox <block type="text"> to <shadow> in value positions - Fix applyChanges(): strip Blockly v12 <variables> prefix before JAXB parse; broaden catch to Exception so JSException cannot prevent window close - Fix OutlawSchema.xsd: change block @id from xs:integer to xs:string (Blockly v12 generates alphanumeric IDs); add <shadow> element to value type so shadow default blocks survive save/reload - Implement addCustomVariables() using workspace.createVariable(); call after domToWorkspace so variables survive ws.clear() - Switch Variables toolbox category to custom="VARIABLE" for dynamic Blockly- managed list with "Create variable..." button - Forward scroll wheel events from JavaFX to Blockly workspace via setOnScroll interceptor executing ws.scroll() JS; correct Y-axis direction for macOS - Add duplicate-window guard to MythosEditor.show() via static activeEditors map - Add AGENTS.md to PackPartitions documenting the flag/state/block pipeline Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each script editor window runs in its own JavaFX WebView with an isolated
JS heap, so Blockly v12's module-level clipboard stash (stashedCopyData /
stashedWorkspace) is invisible across windows.
Solution: add a static Java-side clipboard (`MythosEditor.sharedBlockClipboard`)
shared by all editor instances.
- MythosEditor.setClipboard(json) / getClipboard() expose the shared stash
to JS via the existing Mythos.editor bridge.
- editor.html registers a keydown capture-phase listener:
Copy (Ctrl/Cmd+C) – after Blockly's internal copy handler runs
(deferred via setTimeout), serialise the selected
block's toCopyData() JSON and push it to Java.
Paste (Ctrl/Cmd+V) – before Blockly's paste handler fires, pull the
Java clipboard JSON and inject it into Blockly's
stash via Blockly.clipboard.setLastCopiedData() /
setLastCopiedWorkspace(), pointing the workspace
at the current window. Same-window paste is
unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
In Blockly v12, registerDefaultOptions() only registers workspace and block options; it deliberately omits registerCommentOptions(), which registers the three workspace-comment context-menu items (Add Comment, Duplicate Comment, Delete Comment) and the "commentCreate" item that appears on right-click of the canvas to create a floating sticky note. Call registerCommentOptions() once after Blockly.inject() so that right-clicking the canvas surface shows "Add Comment", allowing users to place freestanding workspace comment notes. The options.comments flag was already true (inherited from hasCategories(toolbox)), so no inject option change is needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs fixed in MythosFieldTextArea.showEditor_(): 1. Editor invisible until key press: WidgetDiv.show() was called without the workspace argument (4th param) and with the default takeFocus=true (5th param). In Blockly v12 this causes takeEphemeralFocus() to focus the WidgetDiv container div, which in JavaFX WebView's immediate-render mode prevents the textarea from receiving input until a key re-fires focus. Fixed by passing workspace and false for takeFocus so focus goes directly to the textarea via htmlInput.focus(). 2. Editor appears at bottom of screen: No positioning was applied after show(). The blocklyWidgetDiv is position:absolute with no left/top set, so it rendered at its default DOM position. Fixed by reading the field's screen coordinates via getScaledBBox() and writing left/top directly on the div, placing the editor just below the clicked field. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Collaborator
|
This is awesome!Thank you!-Seth 😎On Feb 22, 2026, at 1:33 PM, Brendan Robert ***@***.***> wrote:This upgrades us from the pre-1.0 version of Blockly to the most recent V12 version, incorporating over 9 years of fixes and improvements.
Editing
Copy/paste across scripts — blocks can be copied to clipboard and pasted into another script window
Improved undo/redo — more reliable; covers variable creation/deletion which the old version often missed
Block comments — collapsible comment bubbles on blocks (you may have noticed the "Describe this function..." default already
appearing)
Workspace comments — floating sticky notes directly on the canvas (new in v5+)
Collapse blocks — right-click → Collapse to hide a complex subtree as a single labelled block
Variable & Function Management
"Create variable..." dialog — proper modal; the old version had a fragile prompt hack
Variable renaming — rename from the variable block's context menu; propagates everywhere in the workspace
Function editing — procedures_defreturn mutation dialog for adding/removing parameters is more robust
Performance
Lazy rendering — only visible blocks are rendered; large scripts (like the 48-block Door script) scroll and load noticeably faster
Better memory management — old version leaked event listeners on block disposal
You can view, comment on, or merge this pull request online at:
#44
Commit Summary
b580dff Upgrade Mythos script editor from Blockly ~2015 to Blockly v12.4.1
63b26a1 Add *.dmg to .gitignore
File Changes (22 files)
M
OutlawEditor/.gitignore
(3)
M
OutlawEditor/src/main/java/org/badvision/outlaweditor/MythosEditor.java
(13)
M
OutlawEditor/src/main/java/org/badvision/outlaweditor/ui/MythosScriptEditorController.java
(16)
M
OutlawEditor/src/main/resources/jaxb/OutlawSchema/OutlawSchema.xsd
(4)
M
OutlawEditor/src/main/resources/mythos/blockly_compressed.js
(3185)
M
OutlawEditor/src/main/resources/mythos/blocks_compressed.js
(344)
A
OutlawEditor/src/main/resources/mythos/media/delete-icon.svg
(1)
A
OutlawEditor/src/main/resources/mythos/media/disconnect.mp3
(0)
A
OutlawEditor/src/main/resources/mythos/media/dropdown-arrow.svg
(1)
A
OutlawEditor/src/main/resources/mythos/media/foldout-icon.svg
(1)
M
OutlawEditor/src/main/resources/mythos/media/handclosed.cur
(0)
A
OutlawEditor/src/main/resources/mythos/media/handdelete.cur
(0)
A
OutlawEditor/src/main/resources/mythos/media/pilcrow.png
(0)
M
OutlawEditor/src/main/resources/mythos/media/quote0.png
(0)
M
OutlawEditor/src/main/resources/mythos/media/quote1.png
(0)
A
OutlawEditor/src/main/resources/mythos/media/resize-handle.svg
(3)
M
OutlawEditor/src/main/resources/mythos/media/sprites.png
(0)
M
OutlawEditor/src/main/resources/mythos/media/sprites.svg
(38)
A
OutlawEditor/src/main/resources/mythos/msg/en.js
(465)
M
OutlawEditor/src/main/resources/mythos/mythos-editor/html/editor.html
(188)
M
OutlawEditor/src/main/resources/mythos/mythos-editor/js/mythos_uncompressed.js
(265)
A
Platform/Apple/tools/PackPartitions/AGENTS.md
(184)
Patch Links:
https://github.com/badvision/lawless-legends/pull/44.patch
https://github.com/badvision/lawless-legends/pull/44.diff
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
- Replace htmlInput.select() with setSelectionRange(len, len) so the editor opens with cursor at end of text rather than all text selected - Add border (2px solid #ccc), border-radius, padding, box-shadow, and white background to the textarea so the editor has a visible frame - Set resize: vertical so users can drag the textarea taller if needed - Set WidgetDiv background to transparent to avoid a double-background Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy fix: read Blockly's already-stashed copy data via getLastCopiedData() instead of re-calling toCopyData() on the (possibly-unfocused) selected block. Blockly v12 uses a FocusManager whose focused node may differ from or outlive what getSelected() returns, so reading the stash directly is more reliable. Paste fix: after injecting the Java-side JSON into Blockly's stash, call Blockly.clipboard.paste(copyData, Mythos.workspace) directly and stopPropagation so Blockly's shortcut handler does not run a second paste. The original code only set the stash and relied on Blockly's preconditionFn to allow the paste, but that precondition checks the stashed workspace origin in ways that could silently block the paste. Undo-delete fix: patch BlockSvg.prototype.dispose (the rendered subclass) instead of Block.prototype.dispose. BlockSvg.dispose calls this.unplug() before delegating to super, so patching the base class was too late to capture the parent connection; patching BlockSvg ensures captureConnInfo() runs before unplug() clears the connection. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…osition When deleting B from chain A→B→C, the undo reconnection was calling pConn.connect(bPrev) while A.nextConnection was already occupied by C (from the healStack). Blockly v12 walks to the end of the chain in this case and appends B there rather than inserting it between A and C. Fix the middle-of-chain case by: 1. Explicitly disconnecting C from A.nextConnection before connecting B 2. Connecting B to A.nextConnection 3. Re-attaching C to B.nextConnection Also capture nextBlockId in captureConnInfo (though the fix uses targetBlock() at undo time, which is more reliable). Apply the same explicit-disconnect pattern to value-input reconnection. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three changes to the cross-window clipboard bridge in editor.html:
1. Call Blockly.clipboard.paste(Mythos.workspace) with ONE argument
instead of paste(copyData, Mythos.workspace) with two. The confirmed
paste() signature is paste(a,b,c): when a&&b are both truthy it calls
pasteFromData(a,b) directly, which short-circuits the stash entirely
and ignores setLastCopiedWorkspace(). With one arg b is undefined so
a&&b is false and paste() reads from stashedCopyData/stashedWorkspace
-- the stash we just primed with setLastCopiedData()+
setLastCopiedWorkspace(). This is exactly how Blockly's own Ctrl+V
shortcut handler drives paste internally.
2. Move e.preventDefault()/e.stopPropagation() to after the data checks,
so a same-window paste where getClipboard() returns null still lets
Blockly's own shortcut handler fire normally.
3. Add Mythos.editor.log() calls: one to confirm getClipboard() returned
data across the JS/Java bridge, and one to surface any paste errors
that were previously swallowed by catch(err){}.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CommentView.setSizeWithoutFiringEvents() calls getBBox() on SVG child
elements (topbar background RECT, resize-handle IMAGE, delete/collapse
button icons) to compute the exact pixel geometry for layout. In
JavaFX's embedded WebKit, getBBox() returns {width:0, height:0} for
elements that are in the DOM but have not yet completed a browser
layout/paint cycle.
The constructor calls setSizeWithoutFiringEvents() synchronously
immediately after appending the SVG root to the layer, so getBBox()
always returns zeros. This produces three layout defects:
- foreignObject y=0 instead of y=24: the textarea overlaps the topbar
- resize handle placed at (120,100) instead of (108,88): off the edge
- delete button icon positioned at x=0 because container bbox is 0
Fix: add a COMMENT_CREATE workspace event listener that defers a second
setSizeWithoutFiringEvents() call via setTimeout(0), identical in
structure to the existing BLOCK_CREATE re-render workaround. One
browser paint cycle is enough for getBBox() to return the real
CSS-computed dimensions. view.setSizeWithoutFiringEvents is called
directly (rather than comment.setSize) to avoid emitting a spurious
COMMENT_RESIZE undo event during initialisation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Undo reconnection was using parentBlock.nextConnection for ALL previousConnection-attached blocks. For blocks at the head of an IF THEN or ELSE branch the parent connection is the statement input (DO0/DO1/etc.), not nextConnection. captureConnInfo now detects statement-input parents by comparing the connection object identity against parentBlock.nextConnection, falls back to walking inputList to find the input name, and stores it as stmtInputName. The BlockDelete undo patch resolves pConn via getInput(stmtInputName).connection when stmtInputName is set. COMMENT_CREATE handler: increase defer to 50ms and add console.warn traces to diagnose remaining layout issues. Copy handler: add console.warn traces to confirm Java bridge is reached. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oach
Comments – two bugs fixed:
1. Position: MouseEvent.x/y undefined in JavaFX WebKit → every new comment
appeared at workspace (0,0) regardless of right-click position. Fixed
by polyfilling MouseEvent.prototype.x/y → clientX/clientY.
2. Layout: topBarBackground <rect> height set via CSS only; getBBox().height
returns 0 in JavaFX WebKit (getBBox ignores CSS). CommentEditor.updateSize
uses that to set foreignObject.y, so the textarea overlapped the topbar.
Fixed by stamping height='24' attribute on the rect before calling
setSizeWithoutFiringEvents so getBBox returns the real topbar height.
Cross-window paste – replaced unreliable JS→Java bridge with Java-side approach:
- Cmd+C: addEventFilter reads Blockly's copy stash from JS via executeScript
and stores in shared static field (fallback for JS-side copy handler).
- Cmd+V: addEventFilter reads shared static field (pure Java), injects JSON
into Blockly stash and calls paste() via executeScript. Consumes the JavaFX
event only when cross-window data is present, so same-window paste is
unaffected. Bypasses the JS→Java bridge entirely on the paste side.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Object.defineProperty on host object prototypes (like MouseEvent.prototype) throws in the WebKit version embedded in JavaFX because those prototypes are non-extensible. The uncaught TypeError stopped script execution before Blockly.inject(), leaving Mythos.workspace undefined and crashing every subsequent call. Wrapping in try/catch means the polyfill gracefully no-ops on this platform. The comment position fix via the polyfill will not apply; the topBarBackground height fix (which is independent) still runs normally. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes: - registerCommentOptions() call (context menu "Add Comment" item) - COMMENT_CREATE change-listener handler - blocklyCommentForeignObject / blocklyComment CSS rules - MouseEvent.x/y polyfill Co-Authored-By: Claude Sonnet 4.6 <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.
This upgrades us from the pre-1.0 version of Blockly to the most recent V12 version, incorporating over 9 years of fixes and improvements.
Editing
appearing)
Variable & Function Management
Performance