scratch-blocks 2.0.4 → 2.0.6
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/dist/main.mjs +1 -1
- package/package.json +1 -1
- package/src/blocks/vertical_extensions.ts +34 -10
- package/src/index.ts +15 -0
- package/src/scratch_connection_checker.ts +5 -4
package/package.json
CHANGED
|
@@ -28,6 +28,10 @@ import * as Constants from '../constants'
|
|
|
28
28
|
import { FlyoutCheckboxIcon } from '../flyout_checkbox_icon'
|
|
29
29
|
import { ScratchProcedures } from '../procedures'
|
|
30
30
|
|
|
31
|
+
interface ScratchBlockSvg extends Blockly.BlockSvg {
|
|
32
|
+
hatStylePersisted?: boolean
|
|
33
|
+
}
|
|
34
|
+
|
|
31
35
|
/**
|
|
32
36
|
* Helper function that generates an extension based on a category name.
|
|
33
37
|
* The generated function will set the block's style based on the category name.
|
|
@@ -61,26 +65,46 @@ const SHAPE_STATEMENT = function (this: Blockly.Block) {
|
|
|
61
65
|
this.setNextStatement(true, null)
|
|
62
66
|
}
|
|
63
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Build an extension to make a block be shaped as a hat block, based on the given hat type.
|
|
70
|
+
* Replaces the block's setStyle function to ensure that the hat shape is preserved
|
|
71
|
+
* even if the style is changed or rebuilt.
|
|
72
|
+
* @param hatType the type of hat: 'cap' for regular Scratch hat blocks, or 'bowler' for procedure definitions.
|
|
73
|
+
* @returns A Blockly extension implementing the requested hat type.
|
|
74
|
+
*/
|
|
75
|
+
const makeHatExtension = function (hatType: string) {
|
|
76
|
+
return function (this: Blockly.Block) {
|
|
77
|
+
this.setInputsInline(true)
|
|
78
|
+
this.setNextStatement(true, null)
|
|
79
|
+
this.hat = hatType
|
|
80
|
+
// When the workspace theme is refreshed (e.g. when an extension is loaded),
|
|
81
|
+
// Blockly calls setStyle() on all workspace blocks. This resets block.hat to
|
|
82
|
+
// the style's hat value, which is '' for most styles, erasing the hat set
|
|
83
|
+
// above. Override setStyle on this instance to re-apply the hat afterward.
|
|
84
|
+
const blockSvg = this as ScratchBlockSvg
|
|
85
|
+
if (!blockSvg.hatStylePersisted) {
|
|
86
|
+
const origSetStyle = blockSvg.setStyle.bind(blockSvg)
|
|
87
|
+
blockSvg.setStyle = function (blockStyleName: string) {
|
|
88
|
+
origSetStyle(blockStyleName)
|
|
89
|
+
blockSvg.hat = hatType
|
|
90
|
+
}
|
|
91
|
+
blockSvg.hatStylePersisted = true
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
64
96
|
/**
|
|
65
97
|
* Extension to make a block be shaped as a hat block, regardless of its
|
|
66
98
|
* inputs. That means the block should have a next connection and have inline
|
|
67
99
|
* inputs, but have no previous connection.
|
|
68
100
|
*/
|
|
69
|
-
const SHAPE_HAT =
|
|
70
|
-
this.setInputsInline(true)
|
|
71
|
-
this.setNextStatement(true, null)
|
|
72
|
-
this.hat = 'cap'
|
|
73
|
-
}
|
|
101
|
+
const SHAPE_HAT = makeHatExtension('cap')
|
|
74
102
|
|
|
75
103
|
/**
|
|
76
104
|
* Extension to make a block be shaped as a bowler hat block, with rounded
|
|
77
105
|
* corners on both sides and no indentation for statement blocks.
|
|
78
106
|
*/
|
|
79
|
-
const SHAPE_BOWLER_HAT =
|
|
80
|
-
this.setInputsInline(true)
|
|
81
|
-
this.setNextStatement(true, null)
|
|
82
|
-
this.hat = 'bowler'
|
|
83
|
-
}
|
|
107
|
+
const SHAPE_BOWLER_HAT = makeHatExtension('bowler')
|
|
84
108
|
|
|
85
109
|
/**
|
|
86
110
|
* Extension to make a block be shaped as an end block, regardless of its
|
package/src/index.ts
CHANGED
|
@@ -157,3 +157,18 @@ contextMenuItems.registerDuplicateBlock()
|
|
|
157
157
|
Blockly.ContextMenuRegistry.registry.unregister('workspaceDelete')
|
|
158
158
|
contextMenuItems.registerDeleteAll()
|
|
159
159
|
Blockly.comments.CommentView.defaultCommentSize = new Blockly.utils.Size(200, 200)
|
|
160
|
+
|
|
161
|
+
// When the focused block is deleted and has no parent or nearby neighbor,
|
|
162
|
+
// Blockly falls back to focusing the first/topmost block in the workspace,
|
|
163
|
+
// which triggers a scroll to that block. In Scratch, focus should fall back
|
|
164
|
+
// to the workspace itself (whose onNodeFocus is a no-op) rather than to a
|
|
165
|
+
// specific block, so deleting a block doesn't reset the scroll position.
|
|
166
|
+
// We may need to re-evaluate this when we explicitly work on keyboard navigation.
|
|
167
|
+
const originalGetRestoredFocusableNode =
|
|
168
|
+
Blockly.WorkspaceSvg.prototype.getRestoredFocusableNode
|
|
169
|
+
Blockly.WorkspaceSvg.prototype.getRestoredFocusableNode = function (
|
|
170
|
+
previousNode,
|
|
171
|
+
) {
|
|
172
|
+
if (!previousNode && !this.isFlyout) return null
|
|
173
|
+
return originalGetRestoredFocusableNode.call(this, previousNode)
|
|
174
|
+
}
|
|
@@ -14,10 +14,11 @@ class ScratchConnectionChecker extends Blockly.ConnectionChecker {
|
|
|
14
14
|
isDragging: boolean,
|
|
15
15
|
opt_distance?: number,
|
|
16
16
|
): number {
|
|
17
|
-
// The prototype
|
|
18
|
-
const
|
|
19
|
-
c?.
|
|
20
|
-
|
|
17
|
+
// The prototype's next connection is visual-only and should not accept any connections.
|
|
18
|
+
const isPrototypeNextConn = (c: Blockly.Connection | null) =>
|
|
19
|
+
c?.type === Blockly.ConnectionType.NEXT_STATEMENT &&
|
|
20
|
+
c.getSourceBlock().type === 'procedures_prototype'
|
|
21
|
+
if (isPrototypeNextConn(a) || isPrototypeNextConn(b)) {
|
|
21
22
|
return Blockly.Connection.REASON_CHECKS_FAILED
|
|
22
23
|
}
|
|
23
24
|
return super.canConnectWithReason(a, b, isDragging, opt_distance)
|