scratch-blocks 2.0.0-spork.4 → 2.0.0-spork.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/main.js +1 -1
- package/dist/main.js.LICENSE.txt +6 -0
- package/package.json +4 -4
- package/src/blocks/procedures.ts +1 -1
- package/src/checkable_continuous_flyout.ts +4 -0
- package/src/checkbox_bubble.ts +21 -0
- package/src/colours.ts +1 -0
- package/src/context_menu_items.ts +24 -0
- package/src/css.ts +17 -14
- package/src/fields/field_matrix.ts +38 -27
- package/src/fields/field_note.ts +1 -1
- package/src/fields/scratch_field_angle.ts +9 -1
- package/src/fields/scratch_field_variable.ts +9 -8
- package/src/flyout_checkbox_icon.ts +15 -21
- package/src/index.ts +3 -0
- package/src/scratch_block_paster.ts +10 -0
- package/src/{scratch_comment_bubble.js → scratch_comment_bubble.ts} +52 -19
- package/src/scratch_comment_icon.ts +20 -5
- package/src/scratch_continuous_toolbox.ts +16 -0
- package/src/scratch_insertion_marker_previewer.ts +45 -0
- package/src/status_indicator_label_flyout_inflater.ts +4 -4
- package/src/xml.ts +57 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import * as Blockly from "blockly/core";
|
|
8
|
-
import { ScratchCommentBubble } from "./scratch_comment_bubble
|
|
8
|
+
import { ScratchCommentBubble } from "./scratch_comment_bubble";
|
|
9
9
|
|
|
10
10
|
interface CommentState {
|
|
11
11
|
text: string;
|
|
@@ -19,7 +19,7 @@ interface CommentState {
|
|
|
19
19
|
/**
|
|
20
20
|
* Custom comment icon that draws no icon indicator, used for block comments.
|
|
21
21
|
*/
|
|
22
|
-
class ScratchCommentIcon
|
|
22
|
+
export class ScratchCommentIcon
|
|
23
23
|
extends Blockly.icons.Icon
|
|
24
24
|
implements Blockly.ISerializable, Blockly.IHasBubble
|
|
25
25
|
{
|
|
@@ -34,9 +34,7 @@ class ScratchCommentIcon
|
|
|
34
34
|
constructor(protected sourceBlock: Blockly.BlockSvg) {
|
|
35
35
|
super(sourceBlock);
|
|
36
36
|
this.commentBubble = new ScratchCommentBubble(this.sourceBlock);
|
|
37
|
-
|
|
38
|
-
new (Blockly.Events.get("block_comment_create"))(this.commentBubble)
|
|
39
|
-
);
|
|
37
|
+
this.fireCreateEvent();
|
|
40
38
|
this.onTextChangedListener = this.onTextChanged.bind(this);
|
|
41
39
|
this.onSizeChangedListener = this.onSizeChanged.bind(this);
|
|
42
40
|
this.onCollapseListener = this.onCollapsed.bind(this);
|
|
@@ -198,10 +196,27 @@ class ScratchCommentIcon
|
|
|
198
196
|
this.commentBubble.setCollapsed(!visible);
|
|
199
197
|
}
|
|
200
198
|
|
|
199
|
+
getBubble() {
|
|
200
|
+
return this.commentBubble;
|
|
201
|
+
}
|
|
202
|
+
|
|
201
203
|
dispose() {
|
|
202
204
|
this.commentBubble.dispose();
|
|
203
205
|
super.dispose();
|
|
204
206
|
}
|
|
207
|
+
|
|
208
|
+
canBeFocused() {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Fires a block comment create event corresponding to this icon's comment.
|
|
214
|
+
*/
|
|
215
|
+
fireCreateEvent() {
|
|
216
|
+
Blockly.Events.fire(
|
|
217
|
+
new (Blockly.Events.get("block_comment_create"))(this.commentBubble)
|
|
218
|
+
);
|
|
219
|
+
}
|
|
205
220
|
}
|
|
206
221
|
|
|
207
222
|
Blockly.registry.register(
|
|
@@ -67,4 +67,20 @@ export class ScratchContinuousToolbox extends ContinuousToolbox {
|
|
|
67
67
|
runAfterRerender(callback: () => void) {
|
|
68
68
|
this.postRenderCallbacks.push(callback);
|
|
69
69
|
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Returns whether or not the given item should be deselected.
|
|
73
|
+
* Prevents items from being deselected without a replacement.
|
|
74
|
+
*
|
|
75
|
+
* @param oldItem The item that was previously selected.
|
|
76
|
+
* @param newItem The item that is proposed to be selected instead.
|
|
77
|
+
* @returns True if the old item should be allowed to be deselected.
|
|
78
|
+
*/
|
|
79
|
+
shouldDeselectItem_(
|
|
80
|
+
oldItem: Blockly.ISelectableToolboxItem | null,
|
|
81
|
+
newItem: Blockly.ISelectableToolboxItem | null
|
|
82
|
+
) {
|
|
83
|
+
if (!newItem) return false;
|
|
84
|
+
return super.shouldDeselectItem_(oldItem, newItem);
|
|
85
|
+
}
|
|
70
86
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as Blockly from "blockly/core";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Displays an indicator of where a block being dragged will be connected.
|
|
11
|
+
*/
|
|
12
|
+
class ScratchInsertionMarkerPreviewer extends Blockly.InsertionMarkerPreviewer {
|
|
13
|
+
/**
|
|
14
|
+
* Transforms the given block into a JSON representation used to construct an
|
|
15
|
+
* insertion marker.
|
|
16
|
+
*
|
|
17
|
+
* @param block The block to serialize and use as an insertion marker.
|
|
18
|
+
* @returns A JSON-formatted string corresponding to a serialized
|
|
19
|
+
* representation of the given block suitable for use as an insertion
|
|
20
|
+
* marker.
|
|
21
|
+
*/
|
|
22
|
+
protected override serializeBlockToInsertionMarker(block: Blockly.BlockSvg) {
|
|
23
|
+
const blockJson = Blockly.serialization.blocks.save(block, {
|
|
24
|
+
addCoordinates: false,
|
|
25
|
+
addInputBlocks: true,
|
|
26
|
+
addNextBlocks: false,
|
|
27
|
+
doFullSerialization: false,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (!blockJson) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Failed to serialize source block. ${block.toDevString()}`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return blockJson;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Blockly.registry.register(
|
|
41
|
+
Blockly.registry.Type.CONNECTION_PREVIEWER,
|
|
42
|
+
Blockly.registry.DEFAULT,
|
|
43
|
+
ScratchInsertionMarkerPreviewer,
|
|
44
|
+
true
|
|
45
|
+
);
|
|
@@ -22,15 +22,15 @@ class StatusIndicatorLabelFlyoutInflater extends Blockly.LabelFlyoutInflater {
|
|
|
22
22
|
*/
|
|
23
23
|
load(
|
|
24
24
|
state: Blockly.utils.toolbox.LabelInfo,
|
|
25
|
-
|
|
25
|
+
flyout: Blockly.IFlyout
|
|
26
26
|
): Blockly.FlyoutItem {
|
|
27
27
|
const label = new StatusIndicatorLabel(
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
flyout.getWorkspace(),
|
|
29
|
+
flyout.targetWorkspace,
|
|
30
30
|
state
|
|
31
31
|
);
|
|
32
32
|
label.show();
|
|
33
|
-
return new Blockly.FlyoutItem(label, STATUS_INDICATOR_LABEL_TYPE
|
|
33
|
+
return new Blockly.FlyoutItem(label, STATUS_INDICATOR_LABEL_TYPE);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
package/src/xml.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as Blockly from "blockly/core";
|
|
8
|
+
import { ScratchVariableModel } from "./scratch_variable_model";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Clears the workspace and loads the given serialized state.
|
|
12
|
+
*
|
|
13
|
+
* @param xml XML representation of a Blockly workspace.
|
|
14
|
+
* @param workspace The workspace to load the serialized data onto.
|
|
15
|
+
*/
|
|
16
|
+
export function clearWorkspaceAndLoadFromXml(
|
|
17
|
+
xml: Element,
|
|
18
|
+
workspace: Blockly.WorkspaceSvg
|
|
19
|
+
): string[] {
|
|
20
|
+
workspace.setResizesEnabled(false);
|
|
21
|
+
Blockly.Events.setGroup(true);
|
|
22
|
+
workspace.clear();
|
|
23
|
+
|
|
24
|
+
// Manually load variables to include the cloud and local properties that core
|
|
25
|
+
// Blockly is unaware of.
|
|
26
|
+
for (const variable of xml.querySelectorAll("variables variable")) {
|
|
27
|
+
const id = variable.getAttribute("id");
|
|
28
|
+
if (!id) continue;
|
|
29
|
+
const type = variable.getAttribute("type");
|
|
30
|
+
const name = variable.textContent;
|
|
31
|
+
const isLocal = variable.getAttribute("islocal") === "true";
|
|
32
|
+
const isCloud = variable.getAttribute("iscloud") === "true";
|
|
33
|
+
|
|
34
|
+
const variableModel = new ScratchVariableModel(
|
|
35
|
+
workspace,
|
|
36
|
+
name,
|
|
37
|
+
type,
|
|
38
|
+
id,
|
|
39
|
+
isLocal,
|
|
40
|
+
isCloud
|
|
41
|
+
);
|
|
42
|
+
Blockly.Events.fire(
|
|
43
|
+
new (Blockly.Events.get(Blockly.Events.VAR_CREATE))(variableModel)
|
|
44
|
+
);
|
|
45
|
+
workspace.getVariableMap().addVariable(variableModel);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Remove the `variables` element from the XML to prevent Blockly from
|
|
49
|
+
// throwing or stomping on the variables we created.
|
|
50
|
+
xml.querySelector("variables").remove();
|
|
51
|
+
|
|
52
|
+
// Defer to core for the rest of the deserialization.
|
|
53
|
+
const blockIds = Blockly.Xml.domToWorkspace(xml, workspace);
|
|
54
|
+
|
|
55
|
+
workspace.setResizesEnabled(true);
|
|
56
|
+
return blockIds;
|
|
57
|
+
}
|