File tree Expand file tree Collapse file tree
panels/textDisplayElement Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11<script lang =" ts" module >
22 import { CodeJar } from ' @novacbn/svelte-codejar'
33 import { TextDisplay } from ' ../../outliner/textDisplay'
4+ import { insertLineBreakAsText } from ' ../../util/codeJar'
45 import { localize as translate } from ' ../../util/lang'
56 import { Stopwatch } from ' ../../util/stopwatch'
67 import {
117118 class =" toolbar text-display-text-toolbar"
118119 style ={!! selected ? ' margin-bottom: 16px;' : ' visibility:hidden; height: 0px;' }
119120>
120- <div class ="content codejar-container" on:keydown ={onKeydown }>
121+ <div
122+ class =" content codejar-container"
123+ on:keydown ={onKeydown }
124+ on:beforeinput ={insertLineBreakAsText }
125+ >
121126 <CodeJar
122127 bind:element ={codeJarElement }
123128 syntax =" snbtTextComponent"
Original file line number Diff line number Diff line change 11<script lang =" ts" >
22 import { CodeJar } from ' @novacbn/svelte-codejar'
3+ import { insertLineBreakAsText } from ' ../util/codeJar'
34
45 interface Props {
56 value: string
5556 })
5657 </script >
5758
58- <div class ="content codejar-container" onkeydown ={onKeydown }>
59+ <div class ="content codejar-container" onkeydown ={onKeydown } onbeforeinput ={ insertLineBreakAsText } >
5960 <CodeJar
6061 bind:element ={codeJarElement }
6162 {syntax }
Original file line number Diff line number Diff line change @@ -146,4 +146,30 @@ describe('UI behaviour', () => {
146146 expect ( await blockbench . dialog ( ) . isOpen ( ) ) . toBe ( false )
147147 } )
148148 } )
149+
150+ describe ( 'code editors' , ( ) => {
151+ it ( 'Enter starts a new line in the On-Summon Function editor' , async ( ) => {
152+ await blockbench . newProject ( BLUEPRINT_FORMAT_ID )
153+ await blockbench . action ( 'animated_java:action/blueprint-settings' ) . trigger ( )
154+ await blockbench . evaluate ( ( ) => {
155+ ; ( globalThis as any ) . Dialog . open . sidebar . setPage ( 'eventFunctions' )
156+ } )
157+ await blockbench . waitFor ( ( ) => document . querySelector ( '.dialog pre[contenteditable]' ) )
158+ await blockbench . page . click ( '.dialog pre[contenteditable]' )
159+
160+ const { keyboard } = blockbench . page
161+ await keyboard . type ( 'tag @s add a' )
162+ await keyboard . press ( 'Enter' )
163+ await keyboard . type ( 'tag @s add b' )
164+ await keyboard . press ( 'Enter' )
165+ await keyboard . type ( 'say hi' )
166+ await blockbench . dialog ( ) . cancel ( )
167+
168+ expect (
169+ await blockbench . evaluate (
170+ ( ) => ( globalThis as any ) . Project . animated_java . on_summon_function
171+ )
172+ ) . toBe ( 'tag @s add a\ntag @s add b\nsay hi' )
173+ } )
174+ } )
149175} )
Original file line number Diff line number Diff line change 1+ /**
2+ * `beforeinput` handler that inserts native line breaks into a CodeJar editor as `\n` text.
3+ *
4+ * Chromium 150+ (Blockbench 5.2+) inserts `<br>` on Enter, even in `plaintext-only` `<pre>`
5+ * editors, and CodeJar reads its value from `textContent`, which drops `<br>`.
6+ */
7+ export function insertLineBreakAsText ( event : InputEvent ) {
8+ if ( event . inputType !== 'insertLineBreak' && event . inputType !== 'insertParagraph' ) return
9+ const selection = getSelection ( )
10+ if ( ! ( event . target instanceof HTMLElement ) || ! selection ?. rangeCount ) return
11+
12+ const afterCursor = document . createRange ( )
13+ afterCursor . selectNodeContents ( event . target )
14+ const { endContainer, endOffset } = selection . getRangeAt ( 0 )
15+ afterCursor . setStart ( endContainer , endOffset )
16+
17+ event . preventDefault ( )
18+ // A trailing `\n` doesn't render as a new line in a <pre>, so pad it with a second one.
19+ // The caret lands between them, since the browser can't place it after a trailing `\n`.
20+ document . execCommand ( 'insertHTML' , false , afterCursor . toString ( ) === '' ? '\n\n' : '\n' )
21+ }
You can’t perform that action at this time.
0 commit comments