Skip to content

Commit 001c232

Browse files
Upgrade to Blockly 12.0.0 and nav plugin 0.0.8
Updates for: - Awkward change in addConnectionHighlight that means Blockly now manages visibility and creates the highlights sooner. - setEnabled removal - dropdowns HTMLElement support - plugin CSS - toolbox integration with the plugin - Reinstate outline around showLeds 'field' when focussed - Active focus styling for flyout buttons and labels - Fix focus handling for showLeds field editor The escape key now works as expected. - Correct background color for play sound effect field - We can now remove the patch script as isFullBlockField is public.
1 parent 5ecc2f7 commit 001c232

File tree

17 files changed

+361
-278
lines changed

17 files changed

+361
-278
lines changed

package.json

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
"built/tests/blocksrunner.js",
5151
"built/tests/blockssetup.js",
5252
"scripts/patchUglifyify.js",
53-
"scripts/patchBlocklyFieldColour.js",
5453
"docfiles",
5554
"theme",
5655
"common-docs",
@@ -62,9 +61,9 @@
6261
"npm": ">=8.0.0"
6362
},
6463
"dependencies": {
65-
"@blockly/field-colour": "5.0.12",
66-
"@blockly/keyboard-experiment": "0.0.7",
67-
"@blockly/plugin-workspace-search": "9.1.0",
64+
"@blockly/field-colour": "6.0.0",
65+
"@blockly/keyboard-experiment": "0.0.8",
66+
"@blockly/plugin-workspace-search": "10.0.0",
6867
"@crowdin/crowdin-api-client": "^1.33.0",
6968
"@fortawesome/fontawesome-free": "^5.15.4",
7069
"@microsoft/applicationinsights-web": "^2.8.11",
@@ -73,7 +72,7 @@
7372
"@zip.js/zip.js": "2.4.20",
7473
"adm-zip": "^0.5.12",
7574
"axios": "^1.6.8",
76-
"blockly": "12.0.0-beta.4",
75+
"blockly": "12.0.0",
7776
"browserify": "17.0.0",
7877
"chai": "^3.5.0",
7978
"chalk": "^4.1.2",
@@ -158,12 +157,6 @@
158157
"overrides": {
159158
"combine-source-map": {
160159
"source-map": "0.4.4"
161-
},
162-
"@blockly/field-colour": {
163-
"blockly": "^12.0.0-beta.4"
164-
},
165-
"@blockly/plugin-workspace-search": {
166-
"blockly": "^12.0.0-beta.4"
167160
}
168161
},
169162
"scripts": {
@@ -183,6 +176,6 @@
183176
"update": "gulp update",
184177
"watch-streamer": "cd docs/static/streamer && tsc -t es6 --watch",
185178
"prepare": "node ./scripts/npm-prepare.js",
186-
"postinstall": "node ./scripts/patchUglifyify.js && node ./scripts/patchBlocklyFieldColour.js"
179+
"postinstall": "node ./scripts/patchUglifyify.js"
187180
}
188181
}

pxtblocks/compiler/compiler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,11 +240,11 @@ function blockKey(b: Blockly.Block) {
240240
}
241241

242242
function setChildrenEnabled(block: Blockly.Block, enabled: boolean) {
243-
block.setEnabled(enabled);
243+
block.setDisabledReason(!enabled, "disabled");
244244
// propagate changes
245245
const children = block.getDescendants(false);
246246
for (const child of children) {
247-
child.setEnabled(enabled);
247+
child.setDisabledReason(!enabled, "disabled");
248248
}
249249
}
250250

@@ -257,7 +257,7 @@ function updateDisabledBlocks(e: Environment, allBlocks: Blockly.Block[], topBlo
257257
}
258258

259259
// unset disabled
260-
allBlocks.forEach(b => b.setEnabled(true));
260+
allBlocks.forEach(b => b.setDisabledReason(false, "disabled"));
261261

262262
// update top blocks
263263
const events: pxt.Map<Blockly.Block> = {};

pxtblocks/copyPaste.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ export function initCopyPaste() {
3030
function registerCopy() {
3131
const copyShortcut: Blockly.ShortcutRegistry.KeyboardShortcut = {
3232
name: Blockly.ShortcutItems.names.COPY,
33-
preconditionFn(workspace) {
34-
return oldCopy.preconditionFn(workspace);
33+
preconditionFn(workspace, scope) {
34+
return oldCopy.preconditionFn(workspace, scope);
3535
},
3636
callback: copy,
3737
// the registered shortcut from blockly isn't an array, it's some sort
@@ -44,17 +44,17 @@ function registerCopy() {
4444
function registerCut() {
4545
const cutShortcut: Blockly.ShortcutRegistry.KeyboardShortcut = {
4646
name: Blockly.ShortcutItems.names.CUT,
47-
preconditionFn(workspace) {
48-
return oldCut.preconditionFn(workspace);
47+
preconditionFn(workspace, scope) {
48+
return oldCut.preconditionFn(workspace, scope);
4949
},
50-
callback(workspace, e, shortcut) {
50+
callback(workspace, e, shortcut, scope) {
5151
const handler = getCopyPasteHandlers()?.cut;
5252

5353
if (handler) {
5454
return handler(workspace, e);
5555
}
5656

57-
return oldCut.callback(workspace, e, shortcut);
57+
return oldCut.callback(workspace, e, shortcut, scope);
5858
},
5959
keyCodes: [oldCut.keyCodes[0], oldCut.keyCodes[1], oldCut.keyCodes[2]],
6060
};
@@ -65,8 +65,8 @@ function registerCut() {
6565
function registerPaste() {
6666
const pasteShortcut: Blockly.ShortcutRegistry.KeyboardShortcut = {
6767
name: Blockly.ShortcutItems.names.PASTE,
68-
preconditionFn(workspace) {
69-
return oldPaste.preconditionFn(workspace);
68+
preconditionFn(workspace, scope) {
69+
return oldPaste.preconditionFn(workspace, scope);
7070
},
7171
callback: paste,
7272
keyCodes: [oldPaste.keyCodes[0], oldPaste.keyCodes[1], oldPaste.keyCodes[2]],
@@ -168,22 +168,22 @@ function registerPasteContextMenu() {
168168
Blockly.ContextMenuRegistry.registry.register(pasteOption);
169169
}
170170

171-
const copy = (workspace: Blockly.WorkspaceSvg, e: Event, shortcut?: Blockly.ShortcutRegistry.KeyboardShortcut) => {
171+
const copy = (workspace: Blockly.WorkspaceSvg, e: Event, shortcut?: Blockly.ShortcutRegistry.KeyboardShortcut, scope?: Blockly.ContextMenuRegistry.Scope) => {
172172
const handler = getCopyPasteHandlers()?.copy;
173173

174174
if (handler) {
175175
return handler(workspace, e);
176176
}
177177

178-
return oldCopy.callback(workspace, e, shortcut);
178+
return oldCopy.callback(workspace, e, shortcut, scope);
179179
}
180180

181-
const paste = (workspace: Blockly.WorkspaceSvg, e: Event, shortcut?: Blockly.ShortcutRegistry.KeyboardShortcut) => {
181+
const paste = (workspace: Blockly.WorkspaceSvg, e: Event, shortcut?: Blockly.ShortcutRegistry.KeyboardShortcut, scope?: Blockly.ContextMenuRegistry.Scope) => {
182182
const handler = getCopyPasteHandlers()?.paste;
183183

184184
if (handler) {
185185
return handler(workspace, e);
186186
}
187187

188-
return oldPaste.callback(workspace, e, shortcut);
188+
return oldPaste.callback(workspace, e, shortcut, scope);
189189
}

pxtblocks/diff.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ function diffWorkspaceNoEvents(oldWs: Blockly.Workspace, newWs: Blockly.Workspac
163163
done(b);
164164
const b2 = cloneIntoDiff(b);
165165
done(b2);
166-
b2.setEnabled(false);
166+
b2.setDisabledReason(true, "disabled");
167167
});
168168
logTodo('deleted top')
169169
}
@@ -272,7 +272,7 @@ function diffWorkspaceNoEvents(oldWs: Blockly.Workspace, newWs: Blockly.Workspac
272272
function stitch(b: Blockly.Block) {
273273
log(`stitching ${b.toDevString()}->${dids[b.id]}`)
274274
const wb = ws.getBlockById(dids[b.id]);
275-
wb.setEnabled(false);
275+
wb.setDisabledReason(true, "disabled");
276276
markUsed(wb);
277277
done(wb);
278278
// connect previous connection to delted or existing block

pxtblocks/fields/field_ledmatrix.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export class FieldMatrix extends Blockly.Field implements FieldCustom {
4646

4747
private currentDragState_: boolean;
4848
private selected: number[] | undefined = undefined;
49+
private returnEphemeralFocus: Blockly.ReturnEphemeralFocus | undefined = undefined;
4950

5051
constructor(text: string, params: any, validator?: Blockly.FieldValidator) {
5152
super(text, validator);
@@ -143,6 +144,7 @@ export class FieldMatrix extends Blockly.Field implements FieldCustom {
143144
}
144145
case "Escape": {
145146
(this.sourceBlock_.workspace as Blockly.WorkspaceSvg).markFocused();
147+
this.returnEphemeralFocus?.()
146148
return;
147149
}
148150
default: {
@@ -190,7 +192,7 @@ export class FieldMatrix extends Blockly.Field implements FieldCustom {
190192
this.selected = [0, 0];
191193
this.setFocusIndicator(this.cells[0][0], this.cellState[0][0])
192194
this.elt.setAttribute('aria-activedescendant', this.sourceBlock_.id + ":00");
193-
this.elt.focus();
195+
this.returnEphemeralFocus = Blockly.getFocusManager().takeEphemeralFocus(this.elt);
194196
}
195197

196198
private initMatrix() {
@@ -237,6 +239,7 @@ export class FieldMatrix extends Blockly.Field implements FieldCustom {
237239
}
238240
}
239241

242+
this.fieldGroup_.classList.add("blocklyFieldLedMatrixGroup");
240243
this.fieldGroup_.replaceChild(this.elt, this.fieldGroup_.firstChild);
241244
if (!this.sourceBlock_.isInFlyout) {
242245
this.elt.addEventListener("keydown", this.keyHandler.bind(this));
@@ -509,6 +512,11 @@ function removeQuotes(str: string) {
509512
}
510513

511514
Blockly.Css.register(`
515+
.blocklyFieldLedMatrixGroup.blocklyActiveFocus {
516+
outline: var(--blockly-selection-width) solid var(--blockly-active-node-color);
517+
border-radius: 3px;
518+
}
519+
512520
.blocklyMatrix:focus-visible {
513521
outline: none;
514522
}

pxtblocks/fields/field_textdropdown.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/// <reference path="../../built/pxtlib.d.ts" />
22

33
import * as Blockly from "blockly";
4-
import { clearDropDownDiv, FieldCustom, FieldCustomOptions } from "./field_utils";
4+
import { clearDropDownDiv, FieldCustom, FieldCustomOptions, isImageProperties } from "./field_utils";
55

66
export interface FieldTextDropdownOptions extends FieldCustomOptions {
77
values?: string;
@@ -140,11 +140,11 @@ export class BaseFieldTextDropdown extends Blockly.FieldTextInput {
140140
for (let i = 0; i < options.length; i++) {
141141
const [label, value] = options[i];
142142
const content = (() => {
143-
if (typeof label === 'object') {
143+
if (isImageProperties(label)) {
144144
// Convert ImageProperties to an HTMLImageElement.
145-
const image = new Image(label['width'], label['height']);
146-
image.src = label['src'];
147-
image.alt = label['alt'] || '';
145+
const image = new Image(label.width, label.height);
146+
image.src = label.src;
147+
image.alt = label.alt;
148148
return image;
149149
}
150150
return label;
@@ -308,7 +308,7 @@ function validateOptions(options: Blockly.MenuOption[]) {
308308
} else if (
309309
tuple[0] &&
310310
typeof tuple[0] !== 'string' &&
311-
typeof tuple[0].src !== 'string'
311+
!isImageProperties(tuple[0])
312312
) {
313313
foundError = true;
314314
pxt.error(

pxtblocks/fields/field_utils.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,4 +699,25 @@ function inflateJRes(jres: pxt.Map<pxt.JRes | string>): pxt.Map<pxt.JRes> {
699699
export function clearDropDownDiv() {
700700
Blockly.DropDownDiv.clearContent();
701701
Blockly.DropDownDiv.getContentDiv().style.height = "";
702+
}
703+
704+
/**
705+
* Returns whether or not an object conforms to the ImageProperties interface.
706+
*
707+
* @param obj The object to test.
708+
* @returns True if the object conforms to ImageProperties, otherwise false.
709+
*/
710+
export function isImageProperties(obj: any): obj is Blockly.ImageProperties {
711+
return (
712+
obj &&
713+
typeof obj === 'object' &&
714+
'src' in obj &&
715+
typeof obj.src === 'string' &&
716+
'alt' in obj &&
717+
typeof obj.alt === 'string' &&
718+
'width' in obj &&
719+
typeof obj.width === 'number' &&
720+
'height' in obj &&
721+
typeof obj.height === 'number'
722+
);
702723
}

pxtblocks/loader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,7 @@ function initComments() {
685685

686686
function initTooltip() {
687687
const renderTip = (el: any) => {
688-
if (el.disabled)
688+
if (el.hasDisabledReason?.("disabled"))
689689
return lf("This block is disabled and will not run. Attach this block to an event to enable it.")
690690
let tip = el.tooltip;
691691
while (typeof tip === "function") {

pxtblocks/plugins/comments/bubble.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import dom = Blockly.utils.dom;
77
* bubble, where it has a "tail" that points to the block, and a "head" that
88
* displays arbitrary svg elements.
99
*/
10-
export abstract class Bubble implements Blockly.IDeletable {
10+
export abstract class Bubble implements Blockly.IDeletable, Blockly.IBubble, Blockly.ISelectable {
1111
/** The width of the border around the bubble. */
1212
static readonly BORDER_WIDTH = 0;
1313

@@ -639,6 +639,32 @@ export abstract class Bubble implements Blockly.IDeletable {
639639
// Bubbles don't have any visual for being selected.
640640
}
641641

642+
/** See IFocusableNode.getFocusableElement. */
643+
getFocusableElement(): HTMLElement | SVGElement {
644+
return this.svgRoot;
645+
}
646+
647+
/** See IFocusableNode.getFocusableTree. */
648+
getFocusableTree(): Blockly.IFocusableTree {
649+
return this.workspace;
650+
}
651+
652+
/** See IFocusableNode.onNodeFocus. */
653+
onNodeFocus(): void {
654+
this.select();
655+
this.bringToFront();
656+
}
657+
658+
/** See IFocusableNode.onNodeBlur. */
659+
onNodeBlur(): void {
660+
this.unselect();
661+
}
662+
663+
/** See IFocusableNode.canBeFocused. */
664+
canBeFocused(): boolean {
665+
return true;
666+
}
667+
642668
contentTop() {
643669
const topBarSize = this.topBar.getBBox();
644670
return Bubble.BORDER_WIDTH + topBarSize.height

pxtblocks/plugins/flyout/buttonFlyoutInflater.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ export class ButtonFlyoutInflater extends Blockly.ButtonFlyoutInflater {
2222
);
2323
button.show();
2424

25-
return new Blockly.FlyoutItem(button, BUTTON_TYPE, true);
25+
return new Blockly.FlyoutItem(button, BUTTON_TYPE);
2626
}
2727
}

0 commit comments

Comments
 (0)