Skip to content

Commit f814186

Browse files
Merge branch 'main' into makecode-tweaks
2 parents fdb569f + d84f46d commit f814186

File tree

5 files changed

+100
-52
lines changed

5 files changed

+100
-52
lines changed

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ export class KeyboardNavigation {
8686
this.workspaceParentTabIndex = workspace
8787
.getParentSvg()
8888
.getAttribute('tabindex');
89-
workspace.getParentSvg().removeAttribute('tabindex');
89+
// We add a focus listener below so use -1 so it doesn't become focusable.
90+
workspace.getParentSvg().setAttribute('tabindex', '-1');
9091

9192
this.focusListener = () => {
9293
this.navigationController.setHasFocus(

src/line_cursor.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,14 @@ export class LineCursor extends Marker {
245245
return true;
246246
case ASTNode.types.INPUT:
247247
return !(location as Blockly.Connection).isConnected();
248-
case ASTNode.types.FIELD:
249-
// @ts-expect-error isFullBlockField is a protected method.
250-
return !(location as Blockly.Field).isFullBlockField();
248+
case ASTNode.types.FIELD: {
249+
const field = node.getLocation() as Blockly.Field;
250+
return !(
251+
field.getSourceBlock()?.isSimpleReporter() &&
252+
// @ts-expect-error isFullBlockField is a protected method.
253+
field.isFullBlockField()
254+
);
255+
}
251256
default:
252257
return false;
253258
}

src/navigation.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -610,20 +610,18 @@ export class Navigation {
610610
if (!newBlock) {
611611
return;
612612
}
613-
if (!this.markedNode) {
614-
this.warn('No marked node when inserting from flyout.');
615-
return;
616-
}
617-
if (
618-
!this.tryToConnectNodes(
619-
workspace,
620-
this.markedNode,
621-
Blockly.ASTNode.createBlockNode(newBlock)!,
622-
)
623-
) {
624-
this.warn(
625-
'Something went wrong while inserting a block from the flyout.',
626-
);
613+
if (this.markedNode) {
614+
if (
615+
!this.tryToConnectNodes(
616+
workspace,
617+
this.markedNode,
618+
Blockly.ASTNode.createBlockNode(newBlock)!,
619+
)
620+
) {
621+
this.warn(
622+
'Something went wrong while inserting a block from the flyout.',
623+
);
624+
}
627625
}
628626

629627
this.focusWorkspace(workspace);
@@ -1468,12 +1466,14 @@ function fakeEventForNode(node: Blockly.ASTNode): PointerEvent {
14681466
* @returns True if we showed the editor, false otherwise.
14691467
*/
14701468
function tryShowFullBlockFieldEditor(block: Blockly.Block): boolean {
1471-
for (const input of block.inputList) {
1472-
for (const field of input.fieldRow) {
1473-
// @ts-expect-error isFullBlockField is a protected method.
1474-
if (field.isClickable() && field.isFullBlockField()) {
1475-
field.showEditor();
1476-
return true;
1469+
if (block.isSimpleReporter()) {
1470+
for (const input of block.inputList) {
1471+
for (const field of input.fieldRow) {
1472+
// @ts-expect-error isFullBlockField is a protected method.
1473+
if (field.isClickable() && field.isFullBlockField()) {
1474+
field.showEditor();
1475+
return true;
1476+
}
14771477
}
14781478
}
14791479
}

test/index.html

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,32 @@
107107
<div id="p5output"></div>
108108
<div id="scenarioForm">
109109
<form id="options">
110-
<label for="scenarioSelect">Scenario:</label>
110+
<label for="scenario">Scenario:</label>
111111
<select
112112
name="scenario"
113-
id="scenarioSelect"
113+
id="scenario"
114114
onchange="document.forms.options.submit()">
115115
<option value="simpleCircle">simple circle</option>
116116
<option value="sun">sun</option>
117117
<option value="blank">blank canvas</option>
118118
</select>
119+
<br />
120+
<label for="renderer">Renderer:</label>
121+
<select
122+
name="renderer"
123+
id="renderer"
124+
onchange="document.forms.options.submit()">
125+
<option value="geras">Geras</option>
126+
<option value="thrasos">Thrasos</option>
127+
<option value="zelos">Zelos</option>
128+
</select>
129+
<br />
130+
<label for="stackConnections">Disable stack connections:</label>
131+
<input
132+
type="checkbox"
133+
name="noStack"
134+
id="noStack"
135+
onChange="document.forms.options.submit()" />
119136
</form>
120137
</div>
121138
</div>

test/index.ts

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,49 @@ import {load} from './loadTestBlocks';
2424
import {runCode, registerRunCodeShortcut} from './runCode';
2525

2626
/**
27-
* Load initial workspace state based on the value in the scenario dropdown.
27+
* Parse query params for inject and navigation options and update
28+
* the fields on the options form to match.
2829
*
29-
* @param workspace The workspace to load blocks into.
30+
* @returns An options object with keys for each supported option.
3031
*/
31-
function loadScenario(workspace: Blockly.WorkspaceSvg) {
32-
const scenarioSelector = location.search.match(/scenario=([^&]+)/);
33-
// Default to the sunny day example.
34-
const scenarioString = scenarioSelector
35-
? scenarioSelector[1]
36-
: 'simpleCircle';
37-
const selector = document.getElementById(
38-
'scenarioSelect',
39-
) as HTMLSelectElement;
40-
selector.value = scenarioString;
41-
42-
// Load the initial state from storage and run the code.
43-
load(workspace, scenarioString);
32+
function getOptions() {
33+
const params = new URLSearchParams(window.location.search);
34+
35+
const scenarioParam = params.get('scenario');
36+
const scenario = scenarioParam ?? 'simpleCircle';
37+
38+
const rendererParam = params.get('renderer');
39+
let renderer = 'zelos';
40+
// For backwards compatibility with previous behaviour, support
41+
// (e.g.) ?geras as well as ?renderer=geras:
42+
if (rendererParam) {
43+
renderer = rendererParam;
44+
} else if (params.get('geras')) {
45+
renderer = 'geras';
46+
} else if (params.get('thrasos')) {
47+
renderer = 'thrasos';
48+
}
49+
50+
const noStackParam = params.get('noStack');
51+
const stackConnections = !noStackParam;
52+
53+
// Update form inputs to match params, but only after the page is
54+
// fully loaded as Chrome (at least) tries to restore previous form
55+
// values and does so _after_ DOMContentLoaded has fired, which can
56+
// result in the form inputs being out-of-sync with the actual
57+
// options when doing browswer page navigation.
58+
window.addEventListener('load', () => {
59+
(document.getElementById('renderer') as HTMLSelectElement).value = renderer;
60+
(document.getElementById('scenario') as HTMLSelectElement).value = scenario;
61+
(document.getElementById('noStack') as HTMLInputElement).checked =
62+
!stackConnections;
63+
});
64+
65+
return {
66+
scenario,
67+
stackConnections,
68+
renderer,
69+
};
4470
}
4571

4672
/**
@@ -50,26 +76,25 @@ function loadScenario(workspace: Blockly.WorkspaceSvg) {
5076
* @returns The created workspace.
5177
*/
5278
function createWorkspace(): Blockly.WorkspaceSvg {
53-
console.log(location.search);
54-
const renderer = location.search.includes('geras')
55-
? 'geras'
56-
: location.search.includes('thrasos')
57-
? 'thrasos'
58-
: 'zelos';
59-
const options = {
79+
const {scenario, stackConnections, renderer} = getOptions();
80+
81+
const injectOptions = {
6082
toolbox: toolboxCategories,
6183
renderer,
6284
};
6385
const blocklyDiv = document.getElementById('blocklyDiv')!;
64-
const workspace = Blockly.inject(blocklyDiv, options);
86+
const workspace = Blockly.inject(blocklyDiv, injectOptions);
6587

66-
new KeyboardNavigation(workspace, {});
88+
const navigationOptions = {
89+
cursor: {stackConnections},
90+
};
91+
new KeyboardNavigation(workspace, navigationOptions);
6792
registerRunCodeShortcut();
6893

6994
// Disable blocks that aren't inside the setup or draw loops.
7095
workspace.addChangeListener(Blockly.Events.disableOrphans);
7196

72-
loadScenario(workspace);
97+
load(workspace, scenario);
7398
runCode();
7499

75100
return workspace;
@@ -88,7 +113,7 @@ function addP5() {
88113
javascriptGenerator.addReservedWords('sketch');
89114
}
90115

91-
document.addEventListener('DOMContentLoaded', function () {
116+
document.addEventListener('DOMContentLoaded', () => {
92117
addP5();
93118
createWorkspace();
94119
document.getElementById('run')?.addEventListener('click', runCode);

0 commit comments

Comments
 (0)