@@ -24,54 +24,35 @@ import {javascriptGenerator} from 'blockly/javascript';
2424// @ts -expect-error No types in js file
2525import { load } from './loadTestBlocks' ;
2626import { runCode , registerRunCodeShortcut } from './runCode' ;
27+ import { createPlayground } from '@blockly/dev-tools' ;
2728
2829( window as unknown as { Blockly : typeof Blockly } ) . Blockly = Blockly ;
2930
3031/**
31- * Parse query params for inject and navigation options and update
32- * the fields on the options form to match.
33- *
34- * @returns An options object with keys for each supported option.
32+ * Parse query params for a predefined block scenario and applies it to the
33+ * workspace.
3534 */
36- function getOptions ( ) {
35+ function applyScenario ( ) {
3736 const params = new URLSearchParams ( window . location . search ) ;
3837
3938 const scenarioParam = params . get ( 'scenario' ) ;
40- const scenario = scenarioParam ?? 'simpleCircle' ;
41-
42- const rendererParam = params . get ( 'renderer' ) ;
43- let renderer = 'zelos' ;
44- // For backwards compatibility with previous behaviour, support
45- // (e.g.) ?geras as well as ?renderer=geras:
46- if ( rendererParam ) {
47- renderer = rendererParam ;
48- } else if ( params . get ( 'geras' ) ) {
49- renderer = 'geras' ;
50- } else if ( params . get ( 'thrasos' ) ) {
51- renderer = 'thrasos' ;
52- }
53-
54- const toolboxParam = params . get ( 'toolbox' ) ;
55- const toolbox = toolboxParam ?? 'toolbox' ;
56- const toolboxObject =
57- toolbox === 'flyout' ? toolboxFlyout : toolboxCategories ;
39+ const scenario = scenarioParam ?? 'custom' ;
5840
5941 // Update form inputs to match params, but only after the page is
6042 // fully loaded as Chrome (at least) tries to restore previous form
6143 // values and does so _after_ DOMContentLoaded has fired, which can
6244 // result in the form inputs being out-of-sync with the actual
63- // options when doing browswer page navigation.
45+ // options when doing browser page navigation.
6446 window . addEventListener ( 'load' , ( ) => {
65- ( document . getElementById ( 'toolbox' ) as HTMLSelectElement ) . value = toolbox ;
66- ( document . getElementById ( 'renderer' ) as HTMLSelectElement ) . value = renderer ;
6747 ( document . getElementById ( 'scenario' ) as HTMLSelectElement ) . value = scenario ;
6848 } ) ;
6949
70- return {
71- scenario,
72- renderer,
73- toolbox : toolboxObject ,
74- } ;
50+ if ( scenario !== 'custom' ) {
51+ load ( Blockly . getMainWorkspace ( ) , scenario ) ;
52+ const url = new URL ( window . location . href ) ;
53+ url . searchParams . delete ( 'scenario' ) ;
54+ window . history . replaceState ( { } , document . title , url . toString ( ) ) ;
55+ }
7556}
7657
7758/**
@@ -80,13 +61,8 @@ function getOptions() {
8061 *
8162 * @returns The created workspace.
8263 */
83- function createWorkspace ( ) : Blockly . WorkspaceSvg {
84- const { scenario, renderer, toolbox} = getOptions ( ) ;
85-
86- const injectOptions = {
87- toolbox,
88- renderer,
89- } ;
64+ async function createWorkspace ( ) : Promise < Blockly . WorkspaceSvg > {
65+ const injectOptions = { toolbox : toolboxCategories } ;
9066 const blocklyDiv = document . getElementById ( 'blocklyDiv' ) ;
9167 if ( ! blocklyDiv ) {
9268 throw new Error ( 'Missing blocklyDiv' ) ;
@@ -96,16 +72,30 @@ function createWorkspace(): Blockly.WorkspaceSvg {
9672 KeyboardNavigation . registerKeyboardNavigationStyles ( ) ;
9773 registerFlyoutCursor ( ) ;
9874 registerNavigationDeferringToolbox ( ) ;
99- const workspace = Blockly . inject ( blocklyDiv , injectOptions ) ;
100-
101- Blockly . ContextMenuItems . registerCommentOptions ( ) ;
102- new KeyboardNavigation ( workspace ) ;
10375 registerRunCodeShortcut ( ) ;
76+ Blockly . ContextMenuItems . registerCommentOptions ( ) ;
10477
105- // Disable blocks that aren't inside the setup or draw loops.
106- workspace . addChangeListener ( Blockly . Events . disableOrphans ) ;
107-
108- load ( workspace , scenario ) ;
78+ let navigation : KeyboardNavigation | null = null ;
79+ const workspace = (
80+ await createPlayground (
81+ blocklyDiv ,
82+ ( blocklyDiv , options ) => {
83+ if ( navigation ) {
84+ navigation . dispose ( ) ;
85+ }
86+ const ws = Blockly . inject ( blocklyDiv , options ) ;
87+ navigation = new KeyboardNavigation ( ws ) ;
88+
89+ // Disable blocks that aren't inside the setup or draw loops.
90+ ws . addChangeListener ( Blockly . Events . disableOrphans ) ;
91+
92+ return ws ;
93+ } ,
94+ injectOptions ,
95+ )
96+ ) . getWorkspace ( ) ;
97+
98+ applyScenario ( ) ;
10999 runCode ( ) ;
110100
111101 return workspace ;
@@ -124,9 +114,9 @@ function addP5() {
124114 javascriptGenerator . addReservedWords ( 'sketch' ) ;
125115}
126116
127- document . addEventListener ( 'DOMContentLoaded' , ( ) => {
117+ document . addEventListener ( 'DOMContentLoaded' , async ( ) => {
128118 addP5 ( ) ;
129- createWorkspace ( ) ;
119+ await createWorkspace ( ) ;
130120 document . getElementById ( 'run' ) ?. addEventListener ( 'click' , runCode ) ;
131121 // Add Blockly to the global scope so that test code can access it to
132122 // verify state after keypresses.
0 commit comments