diff --git a/.github/workflows/assign_reviewers.yml b/.github/workflows/assign_reviewers.yml
index 042f1553e7..850c7c805f 100644
--- a/.github/workflows/assign_reviewers.yml
+++ b/.github/workflows/assign_reviewers.yml
@@ -15,9 +15,11 @@ on:
jobs:
requested-reviewer:
runs-on: ubuntu-latest
+ permissions:
+ pull-requests: write
steps:
- name: Assign requested reviewer
- uses: actions/github-script@v5
+ uses: actions/github-script@v7
with:
script: |
try {
diff --git a/codelabs/custom_generator/custom_generator.md b/codelabs/custom_generator/custom_generator.md
index 34ab94ac6a..5f8db1134d 100644
--- a/codelabs/custom_generator/custom_generator.md
+++ b/codelabs/custom_generator/custom_generator.md
@@ -203,7 +203,7 @@ A custom language generator is simply an instance of `Blockly.Generator`. Create
```js
import * as Blockly from 'blockly';
-export const jsonGenerator = new Blockly.Generator('JSON');
+export const jsonGenerator = new Blockly.CodeGenerator('JSON');
```
### Generate code
diff --git a/codelabs/keyboard_navigation/AST.png b/codelabs/keyboard_navigation/AST.png
deleted file mode 100644
index 556e883ed6..0000000000
Binary files a/codelabs/keyboard_navigation/AST.png and /dev/null differ
diff --git a/codelabs/keyboard_navigation/block_terms.png b/codelabs/keyboard_navigation/block_terms.png
deleted file mode 100644
index 789a3dce15..0000000000
Binary files a/codelabs/keyboard_navigation/block_terms.png and /dev/null differ
diff --git a/codelabs/keyboard_navigation/flashing_cursor.gif b/codelabs/keyboard_navigation/flashing_cursor.gif
deleted file mode 100644
index a6db40a29e..0000000000
Binary files a/codelabs/keyboard_navigation/flashing_cursor.gif and /dev/null differ
diff --git a/codelabs/keyboard_navigation/keyboard_navigation.md b/codelabs/keyboard_navigation/keyboard_navigation.md
deleted file mode 100644
index 6249e8160d..0000000000
--- a/codelabs/keyboard_navigation/keyboard_navigation.md
+++ /dev/null
@@ -1,567 +0,0 @@
-author: Abby Schmiedt
-summary: Codelab to configure keyboard navigation
-id: keyboard-navigation
-categories: blockly,codelab,accessibility,keyboard navigation
-status: Published
-Feedback Link: https://github.com/google/blockly-samples/issues/new/choose
-
-# Keyboard navigation
-
-## Codelab overview
-
-Keyboard navigation is the first step in making Blockly more accessible. This guide focuses on how to modify keyboard navigation.
-
-### What you'll learn
-
-- How to change the behavior of a cursor.
-- How to change the look of cursors and markers.
-- How to add a shortcut.
-- How to change the current key mappings.
-
-### What you'll build
-
-- A cursor that displays a red blinking image over the block.
-- A cursor that skips over previous and next connections.
-- A keyboard shortcut for moving the cursor to the top of a stack.
-
-### What you'll need
-
-- Basic understanding of blocks and toolboxes in Blockly.
-- NPM installed ([instructions](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)).
-- Comfort using the command line/terminal.
-- Familiarity with the blockly keyboard navigation [documentation](https://developers.google.com/blockly/guides/configure/web/keyboard-nav).
-
-## Setup
-
-This codelab will demonstrate how to install the [keyboard navigation plugin](https://www.npmjs.com/package/@blockly/keyboard-navigation) on top of the Blockly sample app and then add code to create and use a custom `Cursor` and `Marker`.
-
-### The application
-
-Use the [`npx @blockly/create-package app`](https://www.npmjs.com/package/@blockly/create-package) command to create a standalone application that contains a sample setup of Blockly, including custom blocks and a display of the generated code and output.
- 1. Run `npx @blockly/create-package app keyboard-navigation-codelab`. This will create a blockly application in the folder `keyboard-navigation-codelab`.
- 1. `cd` into the new directory: `cd keyboard-navigation-codelab`.
- 1. Install the [keyboard navigation plugin](https://www.npmjs.com/package/@blockly/keyboard-navigation): `npm install @blockly/keyboard-navigation --save`
- 1. Run `npm start` to start the server and run the sample application.
- 1. The sample app will automatically run in the browser window that opens.
-
-## Terminology
-
-A [**Marker**](https://developers.google.com/blockly/reference/js/blockly.marker_class) holds a location and is not movable. A marker is used to mark a location on the workspace, such as marking the spot where the user can drop a block from the toolbox.
-
-A [**Cursor**](https://developers.google.com/blockly/reference/js/blockly.cursor_class) is a marker that can move. It extends a `Blockly.Marker` but adds logic to allow the marker to move through the blocks, inputs, fields, connections and workspace coordinates.
-
-The below image displays different parts of a block that a user can navigate to using keyboard navigation.
-
-
-
-## Initialize NavigationController plugin
-
-First, import and set up a `NavigationController` in `index.js`. `NavigationController` is the class in charge of registering all keyboard shortcuts.
-
-Import `NavigationController` at the top of `index.js`:
-
-```js
-import {NavigationController} from '@blockly/keyboard-navigation';
-```
-
-Then, somewhere after the existing code that injects the workspace, create an instance of `NavigationController`, initialize it, and add it to the workspace:
-
-```js
-// Initialize NavigationController plugin and add to our workspace.
-const navigationController = new NavigationController();
-navigationController.init();
-navigationController.addWorkspace(ws);
-```
-
-At this point, the app will have default keyboard navigation enabled. Pressing **ctrl + shift + k** will enter the user into keyboard navigation mode. From here, `WASD` style commands can be used to navigate around. Further details can be found in [the blockly keyboard navigation documentation](https://developers.google.com/blockly/guides/configure/web/keyboard-nav).
-
-## Understand AST Nodes
-
-Blockly organizes all the different components in a workspace in a structured way by representing them as an abstract syntax tree ([AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)).
-
-The following image displays the AST for a workspace.
-
-
-
-There are four different levels to the AST:
-1. Workspace Level (green): Holds all workspace nodes.
-1. Stack Level (blue): Holds all stack nodes.
-1. Block and Connection Level (red): Holds all block and connection nodes.
-1. Field and Input Level (yellow): Holds all field and input nodes.
-
-For a more detailed explanation of the different levels please see the [keyboard navigation documentation](https://developers.google.com/blockly/guides/configure/web/keyboard-nav#using_the_default_cursor).
-
-### Create AST nodes
-
-The `Blockly.ASTNode` class is used to represent the AST. The `Blockly.ASTNode` class holds a workspace component. This component can be a block, connection, field, input or workspace coordinate.
-
-The following code shows how to create a `Blockly.ASTNode` for the different workspace components:
-
-```js
-const workspaceNode = Blockly.ASTNode.createWorkspaceNode(
- workspace, wsCoordinate);
-const stackNode = Blockly.ASTNode.createStackNode(topBlock);
-const connectionNode = Blockly.ASTNode.createConnectionNode(connection);
-const blockNode = Blockly.ASTNode.createBlockNode(block);
-const fieldNode = Blockly.ASTNode.createFieldNode(field);
-const inputNode = Blockly.ASTNode.createInputNode(input);
-```
-
-### Use AST nodes
-
-These nodes are used in the cursor to decide where to go and what to draw.
-
-Every node can:
-1. Return the node below it (`in()`)
-1. Return the node above it (`out()`)
-1. Return the previous node (`prev()`)
-1. Return the next node (`next()`)
-
-For example, the following code can be used to get the stack node from a workspace node:
-
-```js
-const stackNode = workspaceNode.in();
-```
-
-## Define and set a custom marker
-
-The `Blockly.blockRendering.MarkerSvg` class contains the logic to draw cursors and markers. It decides what to draw depending on the current node the cursor or marker holds.
-
-To start, create a new directory at `src/markers` and add a file inside named `custom_marker_svg.js`.
-
-At the top of the file, import `blockly/core`:
-
-```js
-import * as Blockly from 'blockly/core';
-```
-
-Then define a new custom marker and have it extend `Blockly.blockRendering.MarkerSvg`:
-
-```js
-class CustomMarkerSvg extends Blockly.blockRendering.MarkerSvg {
- constructor(workspace, constants, marker) {
- super(workspace, constants, marker);
- }
-}
-```
-
-Now, inside `CustomMarkerSvg`, override `createDomInternal_()`. This method is in charge of creating all DOM elements for the marker. Add a new path element for when the cursor is on a block:
-
-```js
- /**
- * @override
- */
- createDomInternal_() {
- super.createDomInternal_();
-
- // Create the svg element for the marker when it is on a block and set the
- // parent to markerSvg_.
- this.blockPath_ = Blockly.utils.dom.createSvgElement(
- 'path', {}, this.markerSvg_);
-
- // If this is a cursor make the cursor blink.
- if (this.isCursor()) {
- const blinkProperties = this.getBlinkProperties_();
- Blockly.utils.dom.createSvgElement('animate', blinkProperties,
- this.blockPath_);
- }
- }
-```
-
-Next, create a method named `showWithBlock_(curNode)` that will:
-
-- Update the block path.
-- Set the current marker.
-- Set the parent.
-- Show the current marker.
-
-This method will be called within `showAtLocation_(curNode)` when the user moves to a new block:
-
-```js
- showWithBlock_(curNode) {
- // Get the block from the AST Node
- const block = curNode.getLocation();
-
- // Get the path of the block.
- const blockPath = block.pathObject.svgPath.getAttribute('d');
-
- // Set the path for the cursor.
- this.blockPath_.setAttribute('d', blockPath);
-
- // Set the current marker.
- this.currentMarkerSvg = this.blockPath_;
-
- // Set the parent of the cursor as the block.
- this.setParent_(block);
-
- // Show the current marker.
- this.showCurrent_();
- }
-```
-
-Then, override `showAtLocation_(curNode)`. This method is used to decide what to display at a given node:
-
-```js
- /**
- * @override
- */
- showAtLocation_(curNode) {
- let handled = false;
- // If the cursor is on a block call the new method we created to draw the
- // cursor.
- if (curNode.getType() == Blockly.ASTNode.types.BLOCK) {
- this.showWithBlock_(curNode);
- handled = true;
- }
-
- // If we have not drawn the cursor let the parent draw it.
- if (!handled) {
- super.showAtLocation_.call(this, curNode);
- }
- }
-```
-
-Finally, override the `hide()` method:
-
-```js
- /**
- * @override
- */
- hide() {
- super.hide();
- // Hide the marker we created.
- this.blockPath_.style.display = 'none';
- }
-```
-
-### Renderer setup
-
-Override the renderer to have it use the cursor `CustomMarkerSvg`. For more information on customizing a renderer see the custom renderer [codelab](https://blocklycodelabs.dev/codelabs/custom-renderer/index.html).
-
-Add the following code to the bottom of `custom_marker_svg.js`, outside of the `CustomMarkerSvg` class definition:
-
-```js
-class CustomRenderer extends Blockly.geras.Renderer {
- constructor(name) {
- super(name);
- }
-}
-Blockly.blockRendering.register('custom_renderer', CustomRenderer);
-```
-
-Now override the method responsible for returning the drawer for markers and cursors.
-
-Add the following method inside the `CustomRenderer` class:
-
-```js
-makeMarkerDrawer(workspace, marker) {
- return new CustomMarkerSvg(workspace, this.getConstants(), marker);
-}
-```
-
-In order to use the custom renderer, it has to be imported at the top of `index.js`.
-
-```js
-import './markers/custom_marker_svg';
-```
-
-Then, change the call to `Blockly.inject` to pass the newly registered renderer named `custom_renderer`:
-
-```js
-const ws = Blockly.inject(blocklyDiv, {
- toolbox: toolbox,
- renderer: 'custom_renderer',
-});
-```
-
-### Test it out
-
-Open the sample app and drag a function block on to the workspace. Press **ctrl + shift + k** to enter into keyboard navigation mode. Notice how the entire block starts flashing red.
-
-
-
-## Define and set a custom cursor
-
-Create a new directory at `src/cursors` and add a file inside named `custom.js`.
-
-At the top of the new file, add an import of `blockly/core`:
-
-```js
-import * as Blockly from 'blockly/core';
-```
-
-Then define a new custom cursor and have it extend the base cursor, `Blockly.Cursor`:
-
-```js
-export class CustomCursor extends Blockly.Cursor {
- constructor() {
- super();
- }
-}
-```
-
-Import the cursor at the top of `src/index.js`.
-
-```js
-import {CustomCursor} from './cursors/custom';
-```
-
-Somewhere after the existing code that injects the workspace, use its `MarkerManager` to set the new custom cursor:
-
-```js
-// Add CustomCursor to workspace
-ws.getMarkerManager().setCursor(new CustomCursor());
-```
-
-## Change the cursor behavior
-
-### Override the move methods
-
-Override the methods that move the cursor in order to skip over previous and next connections.
-
-Add the following code to `cursors/custom.js`, inside the `CustomCursor` class definition (these implementations are just a starting point that will be improved upon in the next step):
-
-```js
- next() {
- // The current Blockly.ASTNode the cursor is on.
- const curNode = this.getCurNode();
- if (!curNode) {
- return null;
- }
- // The next Blockly.ASTNode.
- let newNode = curNode.next();
- if (newNode) {
- this.setCurNode(newNode);
- }
- return newNode;
- }
-
- in() {
- const curNode = this.getCurNode();
- if (!curNode) {
- return null;
- }
- let newNode = curNode.in();
- if (newNode) {
- this.setCurNode(newNode);
- }
- return newNode;
- }
-
- prev() {
- const curNode = this.getCurNode();
- if (!curNode) {
- return null;
- }
- let newNode = curNode.prev();
- if (newNode) {
- this.setCurNode(newNode);
- }
- return newNode;
- }
-
- out() {
- const curNode = this.getCurNode();
- if (!curNode) {
- return null;
- }
- let newNode = curNode.out();
- if (newNode) {
- this.setCurNode(newNode);
- }
- return newNode;
- }
-```
-
-### Modify the move methods
-
-Now add logic to the move methods to skip over the previous and next connections. The following image represents the logic being added. The red boxes represent the nodes to skip.
-
-
-
-Change the `next` method so it will skip over any previous or next connections and go straight to the next block:
-
-```js
- next() {
- const curNode = this.getCurNode();
- if (!curNode) {
- return null;
- }
- let newNode = curNode.next();
- // While the newNode exists and is either a previous or next type go to the
- // next value.
- while (newNode && (newNode.getType() === Blockly.ASTNode.types.PREVIOUS ||
- newNode.getType() === Blockly.ASTNode.types.NEXT)) {
- newNode = newNode.next();
- }
- if (newNode) {
- this.setCurNode(newNode);
- }
- return newNode;
- }
-```
-
-Change the `prev` method so it will skip over any previous or next connections and go straight to the previous block:
-
-```js
- prev() {
- const curNode = this.getCurNode();
- if (!curNode) {
- return null;
- }
- let newNode = curNode.prev();
- // While the newNode exists and is either a previous or next connection go
- // to the previous value.
- while (newNode && (newNode.getType() === Blockly.ASTNode.types.PREVIOUS ||
- newNode.getType() === Blockly.ASTNode.types.NEXT)) {
- newNode = newNode.prev();
- }
- if (newNode) {
- this.setCurNode(newNode);
- }
- return newNode;
- }
-```
-
-Change the `in` method so that it will skip over any previous connections and go straight to the contained block:
-
-```js
- in() {
- const curNode = this.getCurNode();
- if (!curNode) {
- return null;
- }
- let newNode = curNode.in();
- // If the newNode is a previous connection go to the next value in the
- // level. This will be the block.
- if (newNode && newNode.getType() === Blockly.ASTNode.types.PREVIOUS) {
- newNode = newNode.next();
- }
- if (newNode) {
- this.setCurNode(newNode);
- }
- return newNode;
- }
-```
-
-#### Test it out
-
-Open the sample app and enter into keyboard navigation mode (**ctrl + shift + k**). Drag some blocks on to the workspace and navigate to the first block. From here hit the **S** key to go to the next block. Notice how the cursor skips over the previous and next connection and goes straight to the next block.
-
-
-
-## Adding a shortcut
-
-This section will add a shortcut that will allow users to move their cursor to the top of their current stack by pressing **ctrl + W**.
-
-### Create a key mapping
-
-A key mapping connects a key code or combination of key codes to a shortcut. When the key code or combination of key codes are pressed the shortcut will run.
-
-Primary keys can be combined with modifier keys by using the `createSerializedKey()` method. A list of the available modifier keys are:
-
-- `Blockly.ShortcutRegistry.modifierKeys.SHIFT`
-- `Blockly.ShortcutRegistry.modifierKeys.CONTROL`
-- `Blockly.ShortcutRegistry.modifierKeys.ALT`
-- `Blockly.ShortcutRegistry.modifierKeys.META`
-
-Create a key code for **ctrl + W** by adding the following code to the bottom of `index.js`:
-
-```js
-// Create a serialized key from the primary key and any modifiers.
-const ctrlW = Blockly.ShortcutRegistry.registry.createSerializedKey(
- Blockly.utils.KeyCodes.W, [Blockly.ShortcutRegistry.modifierKeys.Control]);
-```
-
-### Create a shortcut
-
-A shortcut has several properties:
-- `name`: The name of the shortcut. This must be unique.
-- `keyCodes`: A list of key codes that when pressed will trigger this shortcut. This shortcut will use the `ctrlW` defined above.
-- `preconditionFn`: A function that returns true if and only if the shortcut should be run. This shortcut will only run when `workspace.keyboardAccessibilityMode` is true.
-- `callback`: A function that is called when the shortcut has been executed. This should return true if the shortcut has been handled. If a shortcut returns true, no other shortcuts with the same key mapping will be handled.
-
-Add the following code to the bottom of `index.js`:
-
-```js
-const moveToStack = {
- name: 'moveToStack',
- keyCodes: [ctrlW], // The custom key mapping.
- preconditionFn: function(workspace) {
- return workspace.keyboardAccessibilityMode;
- },
- callback: function(workspace) {
- const cursor = workspace.getCursor();
- // Gets the current node.
- const currentNode = cursor.getCurNode();
- // Gets the source block from the current node.
- const currentBlock = currentNode.getSourceBlock();
- // If we are on a workspace node there will be no source block.
- if (currentBlock) {
- // Gets the top block in the stack.
- const rootBlock = currentBlock.getRootBlock();
- // Gets the top node on a block. This is either the previous connection,
- // output connection, or the block itself.
- const topNode = Blockly.ASTNode.createTopNode(rootBlock);
- // Update the location of the cursor.
- cursor.setCurNode(topNode);
- return true;
- }
- },
-};
-
-```
-Once the shortcut is created, it can be registered by adding the following code to the bottom of `index.js`:
-
-```js
-Blockly.ShortcutRegistry.registry.register(moveToStack);
-```
-
-### Test it out
-
-Open the sample app and create a stack of blocks. Enter into keyboard navigation mode (**ctrl + shift + k**). Move the cursor down a few blocks and then press **ctrl + W**. Notice how the cursor jumps to the top of the stack of blocks.
-
-
-
-## Change current key mappings
-
-This section will update key mappings so users can use the arrow keys for their cursor instead of the default **WASD** keys.
-
-Before adding the key mappings below, import the shortcut names by adding the
-following line to the top of `index.js`:
-
-```js
-import {Constants} from '@blockly/keyboard-navigation';
-```
-
-Now set the keys for the next, previous, in, and out actions at the bottom of `index.js`:
-
-```js
-Blockly.ShortcutRegistry.registry.removeAllKeyMappings(Constants.SHORTCUT_NAMES.OUT);
-Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.LEFT, Constants.SHORTCUT_NAMES.OUT);
-
-Blockly.ShortcutRegistry.registry.removeAllKeyMappings(Constants.SHORTCUT_NAMES.IN);
-Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.RIGHT, Constants.SHORTCUT_NAMES.IN);
-
-Blockly.ShortcutRegistry.registry.removeAllKeyMappings(Constants.SHORTCUT_NAMES.PREVIOUS);
-Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.UP, Constants.SHORTCUT_NAMES.PREVIOUS);
-
-Blockly.ShortcutRegistry.registry.removeAllKeyMappings(Constants.SHORTCUT_NAMES.NEXT);
-Blockly.ShortcutRegistry.registry.addKeyMapping(Blockly.utils.KeyCodes.DOWN, Constants.SHORTCUT_NAMES.NEXT);
-```
-
-Note: For a full list of the shortcuts registered in the keyboard navigation plugin see the [constants file](https://github.com/google/blockly-samples/blob/master/plugins/keyboard-navigation/src/constants.js).
-
-### Test it out
-
-Open the sample app and enter into keyboard navigation mode (**ctrl + shift + k**). The arrow keys can now be used to move around instead of the default **WASD** keys.
-
-## Summary
-
-There is still a lot of work to be done in figuring out the best way to provide
-keyboard navigation support for users.
-
-In this codelab you learned:
-- How to create a new cursor.
-- How to change the look of markers and cursors.
-- How to add shortcuts.
diff --git a/codelabs/keyboard_navigation/new_cursor.gif b/codelabs/keyboard_navigation/new_cursor.gif
deleted file mode 100644
index 635cb876dc..0000000000
Binary files a/codelabs/keyboard_navigation/new_cursor.gif and /dev/null differ
diff --git a/codelabs/keyboard_navigation/skip_connections.png b/codelabs/keyboard_navigation/skip_connections.png
deleted file mode 100644
index c4d6c77a72..0000000000
Binary files a/codelabs/keyboard_navigation/skip_connections.png and /dev/null differ
diff --git a/codelabs/keyboard_navigation/skip_to_top.gif b/codelabs/keyboard_navigation/skip_to_top.gif
deleted file mode 100644
index 2da398380a..0000000000
Binary files a/codelabs/keyboard_navigation/skip_to_top.gif and /dev/null differ
diff --git a/eslint.config.js b/eslint.config.js
index 3bd67633df..4ce99166d9 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -40,6 +40,7 @@ module.exports = [
'**/dist/',
'**/build/',
'examples/blockly-svelte/public/bundle.js',
+ 'plugins/migration/test/manual-test-data/',
// specific examples that are sometimes copied into plugins
'plugins/dev-create/templates/sample-app',
'plugins/dev-create/templates/sample-app-ts',
diff --git a/gh-pages/_index.html b/gh-pages/_index.html
index eb8d2e97fd..ac2486fc20 100644
--- a/gh-pages/_index.html
+++ b/gh-pages/_index.html
@@ -286,7 +286,7 @@
- Keyboard Navigation is our first step towards an accessible Blockly.
- For more information on how the default keyboard navigation works please
- see the
- documentation.
-
-
-
- Cursors
- The cursor controls how the user navigates the blocks, inputs, fields and
- connections on a workspace. This demo shows three different cursors:
- Default Cursor: This cursor uses previous, next, in, and out to
- navigate through the different parts of a block. See the
- developer documentation
- for more information.
- Basic Cursor: Uses pre order traversal to allow users to navigate
- through everything using only the previous and next command.
- Line Cursor: We tried to make this cursor mimic a text editor.
- Navigating up and down will take the cursor to the next and previous
- "line" of code. Navigating in and out will move the cursor through all the
- fields and inputs in that "line" of code.
-
-
-
-
-
-
-
-
diff --git a/plugins/keyboard-navigation/test/index.js b/plugins/keyboard-navigation/test/index.js
deleted file mode 100644
index 919ab31037..0000000000
--- a/plugins/keyboard-navigation/test/index.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * @license
- * Copyright 2020 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * @fileoverview Plugin test.
- */
-
-import {createPlayground} from '@blockly/dev-tools';
-import * as Blockly from 'blockly';
-import {toolbox} from './toolbox';
-
-import {LineCursor, NavigationController} from '../src';
-
-let controller;
-
-/**
- * Create a workspace.
- * @param {HTMLElement} blocklyDiv The blockly container div.
- * @param {!Blockly.BlocklyOptions} options The Blockly options.
- * @returns {!Blockly.WorkspaceSvg} The created workspace.
- */
-function createWorkspace(blocklyDiv, options) {
- const workspace = Blockly.inject(blocklyDiv, options);
- controller.addWorkspace(workspace);
- return workspace;
-}
-
-document.addEventListener('DOMContentLoaded', function () {
- controller = new NavigationController();
- controller.init();
- const defaultOptions = {
- toolbox: toolbox,
- };
- createPlayground(
- document.getElementById('root'),
- createWorkspace,
- defaultOptions,
- );
-});
-
-document
- .getElementById('accessibilityModeCheck')
- .addEventListener('click', (e) => {
- if (e.target.checked) {
- controller.enable(Blockly.getMainWorkspace());
- } else {
- controller.disable(Blockly.getMainWorkspace());
- }
- });
-
-document.getElementById('cursorChanger').addEventListener('change', (e) => {
- const cursorType = e.target.value;
- const accessibilityCheckbox = document.getElementById(
- 'accessibilityModeCheck',
- );
- const markerManager = Blockly.getMainWorkspace().getMarkerManager();
- const oldCurNode = markerManager.getCursor().getCurNode();
-
- document.getElementById('cursorChanger').value = cursorType;
- if (cursorType === 'basic') {
- Blockly.ASTNode.NAVIGATE_ALL_FIELDS = false;
- markerManager.setCursor(new Blockly.BasicCursor());
- } else if (cursorType === 'line') {
- Blockly.ASTNode.NAVIGATE_ALL_FIELDS = true;
- markerManager.setCursor(new LineCursor());
- } else {
- Blockly.ASTNode.NAVIGATE_ALL_FIELDS = false;
- markerManager.setCursor(new Blockly.Cursor());
- }
- if (oldCurNode) {
- markerManager.getCursor().setCurNode(oldCurNode);
- }
-
- if (!accessibilityCheckbox.checked) {
- accessibilityCheckbox.checked = true;
- controller.enable(Blockly.getMainWorkspace());
- }
-
- document.activeElement.blur();
-});
diff --git a/plugins/keyboard-navigation/test/navigation_modify_test.mocha.js b/plugins/keyboard-navigation/test/navigation_modify_test.mocha.js
deleted file mode 100644
index 492b98f9c5..0000000000
--- a/plugins/keyboard-navigation/test/navigation_modify_test.mocha.js
+++ /dev/null
@@ -1,691 +0,0 @@
-/**
- * @license
- * Copyright 2021 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-const chai = require('chai');
-const Blockly = require('blockly');
-const {Navigation} = require('../src/navigation');
-const assert = chai.assert;
-const {testHelpers} = require('@blockly/dev-tools');
-const {captureWarnings} = testHelpers;
-
-suite('Insert/Modify', function () {
- /**
- * Check that modify failed.
- * @param {Navigation} navigation The class under test.
- * @param {Blockly.WorkspaceSvg} workspace The main workspace.
- * @param {!Blockly.ASTNode} markerNode The node to try to connect to.
- * @param {!Blockly.ASTNode} cursorNode The node to connect to the markerNode.
- */
- function assertModifyFails(navigation, workspace, markerNode, cursorNode) {
- let modifyResult;
- const warnings = captureWarnings(function () {
- modifyResult = navigation.tryToConnectMarkerAndCursor(
- workspace,
- markerNode,
- cursorNode,
- );
- });
- assert.isFalse(modifyResult);
- assert.equal(
- warnings.length,
- 1,
- 'Expecting 1 warnings for why modify failed.',
- );
- }
-
- /**
- * Define default blocks.
- */
- function defineTestBlocks() {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'stack_block',
- message0: '',
- previousStatement: null,
- nextStatement: null,
- },
- {
- type: 'row_block',
- message0: '%1',
- args0: [
- {
- type: 'input_value',
- name: 'INPUT',
- },
- ],
- output: null,
- },
- {
- type: 'statement_block',
- message0: '%1',
- args0: [
- {
- type: 'input_statement',
- name: 'NAME',
- },
- ],
- previousStatement: null,
- nextStatement: null,
- colour: 230,
- tooltip: '',
- helpUrl: '',
- },
- ]);
- }
-
- setup(function () {
- this.jsdomCleanup = require('jsdom-global')(
- '',
- );
- // We are running these tests in node even thought they require a rendered
- // workspace, which doesn't exactly work. The rendering system expects
- // cancelAnimationFrame to be defined so we need to define it.
- window.cancelAnimationFrame = function () {};
-
- // NOTE: block positions chosen such that they aren't unintentionally
- // bumped out of bounds during tests.
- const xmlText = `
-
-
-
-
-
-
-
-
- `;
-
- defineTestBlocks();
-
- this.workspace = Blockly.inject('blocklyDiv', {
- toolbox: `
-
-
-
- `,
- });
- Blockly.Xml.domToWorkspace(
- Blockly.utils.xml.textToDom(xmlText),
- this.workspace,
- );
- this.navigation = new Navigation();
- this.navigation.addWorkspace(this.workspace);
-
- this.stack_block_1 = this.workspace.getBlockById('stack_block_1');
- this.stack_block_2 = this.workspace.getBlockById('stack_block_2');
- this.row_block_1 = this.workspace.getBlockById('row_block_1');
- this.row_block_2 = this.workspace.getBlockById('row_block_2');
- this.statement_block_1 = this.workspace.getBlockById('statement_block_1');
- this.statement_block_2 = this.workspace.getBlockById('statement_block_2');
- this.navigation.enableKeyboardAccessibility(this.workspace);
- });
-
- teardown(function () {
- delete Blockly.Blocks['stack_block'];
- delete Blockly.Blocks['row_block'];
- delete Blockly.Blocks['statement_block'];
- window.cancelAnimationFrame = undefined;
- this.jsdomCleanup();
- });
-
- suite('Marked Connection', function () {
- suite('Marker on next', function () {
- setup(function () {
- this.markerNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_1.nextConnection,
- );
- });
- test('Cursor on workspace', function () {
- const cursorNode = Blockly.ASTNode.createWorkspaceNode(
- this.workspace,
- new Blockly.utils.Coordinate(0, 0),
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on compatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_2.previousConnection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(this.stack_block_1.getNextBlock().id, 'stack_block_2');
- });
- test('Cursor on incompatible connection', function () {
- // Connect method will try to find a way to connect blocks with
- // incompatible types.
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_2.nextConnection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(this.stack_block_1.getNextBlock(), this.stack_block_2);
- });
- test('Cursor on really incompatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_1.outputConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- assert.isNull(this.stack_block_1.getNextBlock());
- });
- test('Cursor on block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.stack_block_2);
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(this.stack_block_1.getNextBlock().id, 'stack_block_2');
- });
- });
-
- suite('Marker on previous', function () {
- setup(function () {
- this.markerNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_1.previousConnection,
- );
- });
- test('Cursor on compatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_2.nextConnection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(this.stack_block_1.getPreviousBlock().id, 'stack_block_2');
- });
- test('Cursor on incompatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_2.previousConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- assert.isNull(this.stack_block_1.getPreviousBlock());
- });
- test('Cursor on really incompatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_1.outputConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- assert.isNull(this.stack_block_1.getNextBlock());
- });
- test('Cursor on block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.stack_block_2);
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(this.stack_block_1.getPreviousBlock().id, 'stack_block_2');
- });
- test('Cursor on incompatible block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.row_block_1);
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- assert.isNull(this.stack_block_1.getPreviousBlock());
- });
- });
-
- suite('Marker on value input', function () {
- setup(function () {
- this.markerNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_1.inputList[0].connection,
- );
- });
- test('Cursor on compatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_2.outputConnection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(this.row_block_2.getParent().id, 'row_block_1');
- });
- test('Cursor on incompatible connection', function () {
- // Connect method will try to find a way to connect blocks with
- // incompatible types.
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_2.inputList[0].connection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(
- this.row_block_1.inputList[0].connection.targetBlock(),
- this.row_block_2,
- );
- });
- test('Cursor on really incompatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_1.previousConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.row_block_2);
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(this.row_block_2.getParent().id, 'row_block_1');
- });
- });
-
- suite('Marked Statement input', function () {
- setup(function () {
- this.statement_block_1.inputList[0].connection.connect(
- this.stack_block_1.previousConnection,
- );
- this.stack_block_1.nextConnection.connect(
- this.stack_block_2.previousConnection,
- );
- this.markerNode = Blockly.ASTNode.createInputNode(
- this.statement_block_1.inputList[0],
- );
- });
- test('Cursor on block inside statement', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_2.previousConnection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(
- this.stack_block_2.previousConnection.targetBlock(),
- this.statement_block_1,
- );
- });
- test('Cursor on stack', function () {
- const cursorNode = Blockly.ASTNode.createStackNode(
- this.statement_block_2,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(
- this.statement_block_2.getParent().id,
- 'statement_block_1',
- );
- });
- test('Cursor on incompatible type', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_1.outputConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- assert.isNull(this.row_block_1.getParent());
- });
- });
-
- suite('Marker on output', function () {
- setup(function () {
- this.markerNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_1.outputConnection,
- );
- });
- test('Cursor on compatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_2.inputList[0].connection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(this.row_block_1.getParent().id, 'row_block_2');
- });
- test('Cursor on incompatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_2.outputConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on really incompatible connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_1.previousConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.row_block_2);
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.equal(this.row_block_1.getParent().id, 'row_block_2');
- });
- });
- });
-
- suite('Marked Workspace', function () {
- setup(function () {
- this.markerNode = Blockly.ASTNode.createWorkspaceNode(
- this.workspace,
- new Blockly.utils.Coordinate(100, 200),
- );
- });
- test('Cursor on row block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.row_block_1);
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- const pos = this.row_block_1.getRelativeToSurfaceXY();
- assert.equal(pos.x, 100);
- assert.equal(pos.y, 200);
- });
-
- test('Cursor on output connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_1.outputConnection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- const pos = this.row_block_1.getRelativeToSurfaceXY();
- assert.equal(pos.x, 100);
- assert.equal(pos.y, 200);
- });
-
- test('Cursor on previous connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_1.previousConnection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- const pos = this.stack_block_1.getRelativeToSurfaceXY();
- assert.equal(pos.x, 100);
- assert.equal(pos.y, 200);
- });
-
- test('Cursor on input connection', function () {
- // Move the source block to the marked location on the workspace.
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_1.inputList[0].connection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- });
-
- test('Cursor on next connection', function () {
- // Move the source block to the marked location on the workspace.
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_1.nextConnection,
- );
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- });
-
- test('Cursor on child block (row)', function () {
- this.row_block_1.inputList[0].connection.connect(
- this.row_block_2.outputConnection,
- );
-
- const cursorNode = Blockly.ASTNode.createBlockNode(this.row_block_2);
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.isNull(this.row_block_2.getParent());
- const pos = this.row_block_2.getRelativeToSurfaceXY();
- assert.equal(pos.x, 100);
- assert.equal(pos.y, 200);
- });
-
- test('Cursor on child block (stack)', function () {
- this.stack_block_1.nextConnection.connect(
- this.stack_block_2.previousConnection,
- );
-
- const cursorNode = Blockly.ASTNode.createBlockNode(this.stack_block_2);
- assert.isTrue(
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- this.markerNode,
- cursorNode,
- ),
- );
- assert.isNull(this.stack_block_2.getParent());
- const pos = this.stack_block_2.getRelativeToSurfaceXY();
- assert.equal(pos.x, 100);
- assert.equal(pos.y, 200);
- });
-
- test('Cursor on workspace', function () {
- const cursorNode = Blockly.ASTNode.createWorkspaceNode(
- this.workspace,
- new Blockly.utils.Coordinate(100, 100),
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- });
-
- suite('Marked Block', function () {
- suite('Marked any block', function () {
- // These tests are using a stack block, but do not depend on the type of
- // the block.
- setup(function () {
- this.markerNode = Blockly.ASTNode.createBlockNode(this.stack_block_1);
- });
- test('Cursor on workspace', function () {
- const cursorNode = Blockly.ASTNode.createWorkspaceNode(
- this.workspace,
- new Blockly.utils.Coordinate(100, 100),
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- });
- suite('Marked stack block', function () {
- setup(function () {
- this.markerNode = Blockly.ASTNode.createBlockNode(this.stack_block_1);
- });
- test('Cursor on row block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.row_block_1);
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on stack block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.stack_block_1);
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on next connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_2.nextConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on previous connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.stack_block_2.previousConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- });
- suite('Marked row block', function () {
- setup(function () {
- this.markerNode = Blockly.ASTNode.createBlockNode(this.row_block_1);
- });
- test('Cursor on stack block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.stack_block_1);
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on row block', function () {
- const cursorNode = Blockly.ASTNode.createBlockNode(this.row_block_1);
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on value input connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_2.inputList[0].connection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- test('Cursor on output connection', function () {
- const cursorNode = Blockly.ASTNode.createConnectionNode(
- this.row_block_2.outputConnection,
- );
- assertModifyFails(
- this.navigation,
- this.workspace,
- this.markerNode,
- cursorNode,
- );
- });
- });
- });
-});
diff --git a/plugins/keyboard-navigation/test/navigation_test.mocha.js b/plugins/keyboard-navigation/test/navigation_test.mocha.js
deleted file mode 100644
index ed5c67e989..0000000000
--- a/plugins/keyboard-navigation/test/navigation_test.mocha.js
+++ /dev/null
@@ -1,1365 +0,0 @@
-/**
- * @license
- * Copyright 2020 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * @fileoverview
- * @author aschmiedt@google.com (Abby Schmiedt)
- */
-'use strict';
-
-const chai = require('chai');
-const sinon = require('sinon');
-
-const Blockly = require('blockly');
-const {NavigationController, Constants} = require('../src/index');
-const {
- createNavigationWorkspace,
- createKeyDownEvent,
-} = require('./test_helper');
-
-suite('Navigation', function () {
- setup(function () {
- this.jsdomCleanup = require('jsdom-global')(
- '',
- );
- // We are running these tests in node even thought they require a rendered
- // workspace, which doesn't exactly work. The rendering system expects
- // cancelAnimationFrame to be defined so we need to define it.
- window.cancelAnimationFrame = function () {};
- this.controller = new NavigationController();
- this.controller.init();
- this.navigation = this.controller.navigation;
-
- this.getContextStub = sinon
- .stub(window.HTMLCanvasElement.prototype, 'getContext')
- .callsFake(() => {
- return {
- measureText: function () {
- return {width: 0};
- },
- };
- });
- });
-
- teardown(function () {
- this.controller.dispose();
- window.cancelAnimationFrame = undefined;
- this.jsdomCleanup();
- sinon.restore();
- });
-
- // Test that toolbox key handlers call through to the right functions and
- // transition correctly between toolbox, workspace, and flyout.
- suite('Tests toolbox keys', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '%1',
- args0: [
- {
- type: 'field_input',
- name: 'TEXTFIELD',
- text: 'test',
- },
- ],
- },
- ]);
- this.workspace = createNavigationWorkspace(this.navigation, true);
- this.navigation.focusToolbox(this.workspace);
- });
-
- teardown(function () {
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- sinon.restore();
- delete Blockly.Blocks['basic_block'];
- });
-
- const testCases = [
- [
- 'Calls toolbox selectNext',
- createKeyDownEvent(Blockly.utils.KeyCodes.S, 'NotAField'),
- 'selectNext_',
- ],
- [
- 'Calls toolbox selectPrevious',
- createKeyDownEvent(Blockly.utils.KeyCodes.W, 'NotAField'),
- 'selectPrevious_',
- ],
- [
- 'Calls toolbox selectParent',
- createKeyDownEvent(Blockly.utils.KeyCodes.D, 'NotAField'),
- 'selectChild_',
- ],
- [
- 'Calls toolbox selectChild',
- createKeyDownEvent(Blockly.utils.KeyCodes.A, 'NotAField'),
- 'selectParent_',
- ],
- ];
-
- testCases.forEach(function (testCase) {
- const testCaseName = testCase[0];
- const mockEvent = testCase[1];
- const stubName = testCase[2];
- test(testCaseName, function () {
- const toolbox = this.workspace.getToolbox();
- const selectStub = sinon.stub(toolbox, stubName);
- toolbox.selectedItem_ = toolbox.contents_[0];
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
- sinon.assert.called(selectStub);
- });
- });
-
- test('Go to flyout', function () {
- const navigation = this.navigation;
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.D,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- navigation.getState(this.workspace),
- Constants.STATE.FLYOUT,
- );
-
- const flyoutCursor = navigation.getFlyoutCursor(this.workspace);
- // See test_helper.js for hardcoded field values.
- chai.assert.equal(
- flyoutCursor.getCurNode().getLocation().getFieldValue('TEXTFIELD'),
- 'first',
- );
- });
-
- test('Focuses workspace from toolbox (e)', function () {
- const navigation = this.navigation;
- navigation.setState(this.workspace, Constants.STATE.TOOLBOX);
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.E,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
- test('Focuses workspace from toolbox (escape)', function () {
- const navigation = this.navigation;
- navigation.setState(this.workspace, Constants.STATE.TOOLBOX);
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.ESC,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
- });
-
- // Test that flyout key handlers call through to the right functions and
- // transition correctly between toolbox, workspace, and flyout.
- suite('Tests flyout keys', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '%1',
- args0: [
- {
- type: 'field_input',
- name: 'TEXTFIELD',
- text: 'test',
- },
- ],
- },
- ]);
- this.workspace = createNavigationWorkspace(this.navigation, true);
- this.navigation.focusToolbox(this.workspace);
- this.navigation.focusFlyout(this.workspace);
- });
-
- teardown(function () {
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- sinon.restore();
- delete Blockly.Blocks['basic_block'];
- });
- // Should be a no-op
- test('Previous at beginning', function () {
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.W,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.FLYOUT,
- );
- // See test_helper.js for hardcoded field values.
- chai.assert.equal(
- this.navigation
- .getFlyoutCursor(this.workspace)
- .getCurNode()
- .getLocation()
- .getFieldValue('TEXTFIELD'),
- 'first',
- );
- });
- test('Previous', function () {
- const flyoutBlocks = this.workspace
- .getFlyout()
- .getWorkspace()
- .getTopBlocks();
- this.navigation
- .getFlyoutCursor(this.workspace)
- .setCurNode(Blockly.ASTNode.createStackNode(flyoutBlocks[1]));
- let flyoutBlock = this.navigation
- .getFlyoutCursor(this.workspace)
- .getCurNode()
- .getLocation();
- // See test_helper.js for hardcoded field values.
- chai.assert.equal(flyoutBlock.getFieldValue('TEXTFIELD'), 'second');
-
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.W,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.FLYOUT,
- );
- flyoutBlock = this.navigation
- .getFlyoutCursor(this.workspace)
- .getCurNode()
- .getLocation();
- // See test_helper.js for hardcoded field values.
- chai.assert.equal(flyoutBlock.getFieldValue('TEXTFIELD'), 'first');
- });
-
- test('Next', function () {
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.S,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.FLYOUT,
- );
- const flyoutBlock = this.navigation
- .getFlyoutCursor(this.workspace)
- .getCurNode()
- .getLocation();
- // See test_helper.js for hardcoded field values.
- chai.assert.equal(flyoutBlock.getFieldValue('TEXTFIELD'), 'second');
- });
-
- test('Out', function () {
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.A,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.TOOLBOX,
- );
- });
-
- test('Mark', function () {
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.ENTER,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- chai.assert.equal(this.workspace.getTopBlocks().length, 1);
- });
-
- test('Mark - Disabled Block', function () {
- this.navigation.loggingCallback = function (type, msg) {
- chai.assert.equal(msg, "Can't insert a disabled block.");
- };
- const flyout = this.workspace.getFlyout();
- const topBlock = flyout.getWorkspace().getTopBlocks()[0];
- topBlock.setEnabled(false);
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.ENTER,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.FLYOUT,
- );
- chai.assert.equal(this.workspace.getTopBlocks().length, 0);
- this.navigation.loggingCallback = null;
- });
-
- test('Exit', function () {
- const mockEvent = createKeyDownEvent(
- Blockly.utils.KeyCodes.ESC,
- 'NotAField',
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
- });
- // Test that workspace key handlers call through to the right functions and
- // transition correctly between toolbox, workspace, and flyout.
- suite('Tests workspace keys', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '%1',
- args0: [
- {
- type: 'field_input',
- name: 'TEXTFIELD',
- text: 'test',
- },
- ],
- previousStatement: null,
- nextStatement: null,
- },
- ]);
- this.workspace = createNavigationWorkspace(this.navigation, true);
- this.basicBlock = this.workspace.newBlock('basic_block');
- });
-
- teardown(function () {
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- sinon.restore();
- delete Blockly.Blocks['basic_block'];
- });
-
- test('Previous', function () {
- const prevSpy = sinon.spy(this.workspace.getCursor(), 'prev');
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- const wEvent = createKeyDownEvent(Blockly.utils.KeyCodes.W, '');
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, wEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- sinon.assert.calledOnce(prevSpy);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
-
- test('Next', function () {
- const nextSpy = sinon.spy(this.workspace.getCursor(), 'next');
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- const sEvent = createKeyDownEvent(Blockly.utils.KeyCodes.S, '');
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, sEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- sinon.assert.calledOnce(nextSpy);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
-
- test('Out', function () {
- const outSpy = sinon.spy(this.workspace.getCursor(), 'out');
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- const aEvent = createKeyDownEvent(Blockly.utils.KeyCodes.A, '');
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, aEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- sinon.assert.calledOnce(outSpy);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
-
- test('In', function () {
- const inSpy = sinon.spy(this.workspace.getCursor(), 'in');
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- const dEvent = createKeyDownEvent(Blockly.utils.KeyCodes.D, '');
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, dEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- sinon.assert.calledOnce(inSpy);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
-
- test('Insert', function () {
- const blockNode = Blockly.ASTNode.createBlockNode(this.basicBlock);
- this.navigation.getMarker(this.workspace).setCurNode(blockNode);
- // Stub modify as we are not testing its behavior, only if it was called.
- // Otherwise, there is a warning because there is no marked node.
- const modifyStub = sinon
- .stub(this.navigation, 'tryToConnectMarkerAndCursor')
- .returns(true);
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- const iEvent = createKeyDownEvent(Blockly.utils.KeyCodes.I, '');
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, iEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- sinon.assert.calledOnce(modifyStub);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
-
- test('Mark', function () {
- this.workspace
- .getCursor()
- .setCurNode(
- Blockly.ASTNode.createConnectionNode(
- this.basicBlock.previousConnection,
- ),
- );
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- const enterEvent = createKeyDownEvent(Blockly.utils.KeyCodes.ENTER, '');
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, enterEvent);
-
- const markedNode = this.workspace
- .getMarker(this.navigation.MARKER_NAME)
- .getCurNode();
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- markedNode.getLocation(),
- this.basicBlock.previousConnection,
- );
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
-
- test('Toolbox', function () {
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- const tEvent = createKeyDownEvent(Blockly.utils.KeyCodes.T, '');
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, tEvent);
-
- const firstCategory = this.workspace.getToolbox().contents_[0];
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.equal(
- this.workspace.getToolbox().getSelectedItem(),
- firstCategory,
- );
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.TOOLBOX,
- );
- });
- });
-
- suite('Test key press', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '%1',
- args0: [
- {
- type: 'field_input',
- name: 'TEXTFIELD',
- text: 'test',
- },
- ],
- },
- ]);
- this.workspace = createNavigationWorkspace(this.navigation, true);
-
- this.workspace.getCursor().drawer_ = null;
- this.basicBlock = this.workspace.newBlock('basic_block');
- this.basicBlock.initSvg();
- this.basicBlock.render();
- });
- teardown(function () {
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- sinon.restore();
- delete Blockly.Blocks['basic_block'];
- });
-
- test('Action does not exist', function () {
- const block = this.workspace.getTopBlocks()[0];
- const field = block.inputList[0].fieldRow[0];
- const fieldSpy = sinon.spy(field, 'onShortcut');
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.N, '');
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- this.workspace
- .getCursor()
- .setCurNode(Blockly.ASTNode.createFieldNode(field));
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isFalse(keyDownSpy.returned(true));
- sinon.assert.notCalled(fieldSpy);
- });
-
- test('Action exists - field handles action', function () {
- const block = this.workspace.getTopBlocks()[0];
- const field = block.inputList[0].fieldRow[0];
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.A, '');
- const fieldSpy = sinon.stub(field, 'onShortcut').returns(true);
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- this.workspace
- .getCursor()
- .setCurNode(Blockly.ASTNode.createFieldNode(field));
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- sinon.assert.calledOnce(fieldSpy);
- });
-
- test('Action exists - field does not handle action', function () {
- const block = this.workspace.getTopBlocks()[0];
- const field = block.inputList[0].fieldRow[0];
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.A, '');
- const fieldSpy = sinon.spy(field, 'onShortcut');
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- this.workspace
- .getCursor()
- .setCurNode(Blockly.ASTNode.createFieldNode(field));
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- sinon.assert.calledOnce(fieldSpy);
- });
-
- test('Toggle Action Off', function () {
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.K, '', [
- Blockly.utils.KeyCodes.SHIFT,
- Blockly.utils.KeyCodes.CTRL,
- ]);
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- this.workspace.keyboardAccessibilityMode = true;
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.isFalse(this.workspace.keyboardAccessibilityMode);
- });
-
- test('Toggle Action On', function () {
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.K, '', [
- Blockly.utils.KeyCodes.SHIFT,
- Blockly.utils.KeyCodes.CTRL,
- ]);
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
- this.workspace.keyboardAccessibilityMode = false;
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- chai.assert.isTrue(this.workspace.keyboardAccessibilityMode);
- });
-
- suite('Test key press in read only mode', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'field_block',
- message0: '%1 %2',
- args0: [
- {
- type: 'field_input',
- name: 'TEXTFIELD',
- text: 'test',
- },
- {
- type: 'input_value',
- name: 'NAME',
- },
- ],
- previousStatement: null,
- nextStatement: null,
- colour: 230,
- tooltip: '',
- helpUrl: '',
- },
- ]);
- this.workspace = createNavigationWorkspace(this.navigation, true, true);
- Blockly.common.setMainWorkspace(this.workspace);
- this.workspace.getCursor().drawer_ = null;
-
- this.fieldBlock1 = this.workspace.newBlock('field_block');
- this.fieldBlock1.initSvg();
- this.fieldBlock1.render();
- });
-
- teardown(function () {
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- sinon.restore();
- delete Blockly.Blocks['field_block'];
- });
-
- test('Perform valid action for read only', function () {
- const astNode = Blockly.ASTNode.createBlockNode(this.fieldBlock1);
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.S, '');
- this.workspace.getCursor().setCurNode(astNode);
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(true));
- });
-
- test('Perform invalid action for read only', function () {
- const astNode = Blockly.ASTNode.createBlockNode(this.fieldBlock1);
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.I, '');
- this.workspace.getCursor().setCurNode(astNode);
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(false));
- });
-
- test('Try to perform action on a field', function () {
- const field = this.fieldBlock1.inputList[0].fieldRow[0];
- const astNode = Blockly.ASTNode.createFieldNode(field);
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.ENTER, '');
- this.workspace.getCursor().setCurNode(astNode);
- const keyDownSpy = sinon.spy(
- Blockly.ShortcutRegistry.registry,
- 'onKeyDown',
- );
-
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
-
- chai.assert.isTrue(keyDownSpy.returned(false));
- });
- });
- });
- suite('Insert Functions', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '%1',
- args0: [
- {
- type: 'field_input',
- name: 'TEXTFIELD',
- text: 'test',
- },
- ],
- previousStatement: null,
- nextStatement: null,
- },
- ]);
-
- this.workspace = createNavigationWorkspace(this.navigation, true);
-
- const basicBlock = this.workspace.newBlock('basic_block');
- const basicBlock2 = this.workspace.newBlock('basic_block');
-
- this.basicBlock = basicBlock;
- this.basicBlock2 = basicBlock2;
- });
-
- teardown(function () {
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- sinon.restore();
- delete Blockly.Blocks['basic_block'];
- });
-
- test('Insert from flyout with a valid connection marked', function () {
- const previousConnection = this.basicBlock.previousConnection;
- const prevNode = Blockly.ASTNode.createConnectionNode(previousConnection);
- this.workspace
- .getMarker(this.navigation.MARKER_NAME)
- .setCurNode(prevNode);
-
- this.navigation.focusToolbox(this.workspace);
- this.navigation.focusFlyout(this.workspace);
- this.navigation.insertFromFlyout(this.workspace);
-
- const insertedBlock = this.basicBlock.previousConnection.targetBlock();
-
- chai.assert.isTrue(insertedBlock !== null);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
-
- test('Insert Block from flyout without marking a connection', function () {
- this.navigation.focusToolbox(this.workspace);
- this.navigation.focusFlyout(this.workspace);
- this.navigation.insertFromFlyout(this.workspace);
-
- const numBlocks = this.workspace.getTopBlocks().length;
-
- // Make sure the block was not connected to anything
- chai.assert.isNull(this.basicBlock.previousConnection.targetConnection);
- chai.assert.isNull(this.basicBlock.nextConnection.targetConnection);
-
- // Make sure that the block was added to the workspace
- chai.assert.equal(numBlocks, 3);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
-
- test('Connect two blocks that are on the workspace', function () {
- const targetNode = Blockly.ASTNode.createConnectionNode(
- this.basicBlock.previousConnection,
- );
- const sourceNode = Blockly.ASTNode.createConnectionNode(
- this.basicBlock2.nextConnection,
- );
-
- this.navigation.tryToConnectMarkerAndCursor(
- this.workspace,
- targetNode,
- sourceNode,
- );
- const insertedBlock = this.basicBlock.previousConnection.targetBlock();
-
- chai.assert.isNotNull(insertedBlock);
- });
- });
- suite('Connect Blocks', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '',
- previousStatement: null,
- nextStatement: null,
- },
- {
- type: 'inline_block',
- message0: '%1 %2',
- args0: [
- {
- type: 'input_value',
- name: 'NAME',
- },
- {
- type: 'input_value',
- name: 'NAME',
- },
- ],
- inputsInline: true,
- output: null,
- tooltip: '',
- helpUrl: '',
- },
- ]);
-
- this.workspace = createNavigationWorkspace(this.navigation, true);
-
- const basicBlock = this.workspace.newBlock('basic_block');
- const basicBlock2 = this.workspace.newBlock('basic_block');
- const basicBlock3 = this.workspace.newBlock('basic_block');
- const basicBlock4 = this.workspace.newBlock('basic_block');
-
- const inlineBlock1 = this.workspace.newBlock('inline_block');
- const inlineBlock2 = this.workspace.newBlock('inline_block');
- const inlineBlock3 = this.workspace.newBlock('inline_block');
-
- this.basicBlock = basicBlock;
- this.basicBlock2 = basicBlock2;
- this.basicBlock3 = basicBlock3;
- this.basicBlock4 = basicBlock4;
-
- this.inlineBlock1 = inlineBlock1;
- this.inlineBlock2 = inlineBlock2;
- this.inlineBlock3 = inlineBlock3;
-
- this.basicBlock.nextConnection.connect(
- this.basicBlock2.previousConnection,
- );
-
- this.basicBlock3.nextConnection.connect(
- this.basicBlock4.previousConnection,
- );
-
- this.inlineBlock1.inputList[0].connection.connect(
- this.inlineBlock2.outputConnection,
- );
- });
-
- teardown(function () {
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- sinon.restore();
- delete Blockly.Blocks['basic_block'];
- delete Blockly.Blocks['inline_block'];
- });
-
- test('Connect cursor on previous into stack', function () {
- const markedLocation = this.basicBlock2.previousConnection;
- const cursorLocation = this.basicBlock3.previousConnection;
-
- this.navigation.connect(cursorLocation, markedLocation);
-
- chai.assert.equal(
- this.basicBlock.nextConnection.targetBlock(),
- this.basicBlock3,
- );
- chai.assert.equal(
- this.basicBlock2.previousConnection.targetBlock(),
- this.basicBlock4,
- );
- });
-
- test('Connect marker on previous into stack', function () {
- const markedLocation = this.basicBlock3.previousConnection;
- const cursorLocation = this.basicBlock2.previousConnection;
-
- this.navigation.connect(cursorLocation, markedLocation);
-
- chai.assert.equal(
- this.basicBlock.nextConnection.targetBlock(),
- this.basicBlock3,
- );
- chai.assert.equal(
- this.basicBlock2.previousConnection.targetBlock(),
- this.basicBlock4,
- );
- });
-
- test('Connect cursor on next into stack', function () {
- const markedLocation = this.basicBlock2.previousConnection;
- const cursorLocation = this.basicBlock4.nextConnection;
-
- this.navigation.connect(cursorLocation, markedLocation);
-
- chai.assert.equal(
- this.basicBlock.nextConnection.targetBlock(),
- this.basicBlock4,
- );
- chai.assert.isNull(this.basicBlock3.nextConnection.targetConnection);
- });
-
- test('Connect cursor with parents', function () {
- const markedLocation = this.basicBlock3.previousConnection;
- const cursorLocation = this.basicBlock2.nextConnection;
-
- this.navigation.connect(cursorLocation, markedLocation);
-
- chai.assert.equal(
- this.basicBlock3.previousConnection.targetBlock(),
- this.basicBlock2,
- );
- });
-
- test('Try to connect input that is descendant of output', function () {
- const markedLocation = this.inlineBlock2.inputList[0].connection;
- const cursorLocation = this.inlineBlock1.outputConnection;
-
- this.navigation.connect(cursorLocation, markedLocation);
-
- chai.assert.isNull(this.inlineBlock2.outputConnection.targetBlock());
- chai.assert.equal(
- this.inlineBlock1.outputConnection.targetBlock(),
- this.inlineBlock2,
- );
- });
- test.skip('Do not connect a shadow block', function () {
- // TODO(https://github.com/google/blockly-samples/issues/538): Update
- // tests after this bug is fixed.
- this.inlineBlock2.setShadow(true);
-
- const markedLocation = this.inlineBlock2.outputConnection;
- const cursorLocation = this.inlineBlock3.inputList[0].connection;
- const didConnect = this.navigation.connect(
- cursorLocation,
- markedLocation,
- );
- chai.assert.isFalse(didConnect);
- chai.assert.isNull(this.inlineBlock2.outputConnection.targetBlock());
- chai.assert.equal(
- this.inlineBlock1.outputConnection.targetBlock(),
- this.inlineBlock2,
- );
- });
- });
-
- suite('Test cursor move on block delete', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '',
- previousStatement: null,
- nextStatement: null,
- },
- ]);
- this.workspace = createNavigationWorkspace(this.navigation, true);
-
- this.basicBlockA = this.workspace.newBlock('basic_block');
- this.basicBlockB = this.workspace.newBlock('basic_block');
- });
-
- teardown(function () {
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- sinon.restore();
- delete Blockly.Blocks['basic_block'];
- });
-
- test('Delete block - has parent ', function () {
- this.basicBlockA.nextConnection.connect(
- this.basicBlockB.previousConnection,
- );
- const astNode = Blockly.ASTNode.createBlockNode(this.basicBlockB);
- // Set the cursor to be on the child block
- this.workspace.getCursor().setCurNode(astNode);
- // Remove the child block
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.DELETE, '');
-
- // Actions that happen when a block is deleted were causing problems.
- // Since this is not what we are trying to test and does not effect the
- // feature, disable events.
- Blockly.Events.disable();
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
- Blockly.Events.enable();
-
- chai.assert.equal(
- this.workspace.getCursor().getCurNode().getType(),
- Blockly.ASTNode.types.NEXT,
- );
- });
-
- test('Delete block - no parent ', function () {
- const astNode = Blockly.ASTNode.createBlockNode(this.basicBlockB);
- this.workspace.getCursor().setCurNode(astNode);
-
- const mockEvent = createKeyDownEvent(Blockly.utils.KeyCodes.DELETE, '');
-
- // Actions that happen when a block is deleted were causing problems.
- // Since this is not what we are trying to test and does not effect the
- // feature, disable events.
- Blockly.Events.disable();
- Blockly.ShortcutRegistry.registry.onKeyDown(this.workspace, mockEvent);
- Blockly.Events.enable();
-
- chai.assert.equal(
- this.workspace.getCursor().getCurNode().getType(),
- Blockly.ASTNode.types.WORKSPACE,
- );
- });
-
- test('Delete parent block', function () {
- this.basicBlockA.nextConnection.connect(
- this.basicBlockB.previousConnection,
- );
- const astNode = Blockly.ASTNode.createBlockNode(this.basicBlockB);
- const mockDeleteBlockEvent = {
- blockId: this.basicBlockA,
- ids: [this.basicBlockA.id, this.basicBlockB.id],
- };
- // Set the cursor to be on the child block
- this.workspace.getCursor().setCurNode(astNode);
- // Remove the parent block
- this.navigation.handleBlockDeleteByDrag(
- this.workspace,
- mockDeleteBlockEvent,
- );
- chai.assert.equal(
- this.workspace.getCursor().getCurNode().getType(),
- Blockly.ASTNode.types.WORKSPACE,
- );
- });
-
- test('Delete top block in stack', function () {
- this.basicBlockA.nextConnection.connect(
- this.basicBlockB.previousConnection,
- );
- const astNode = Blockly.ASTNode.createStackNode(this.basicBlockA);
- const mockDeleteBlockEvent = {
- blockId: this.basicBlockA.id,
- ids: [this.basicBlockA.id, this.basicBlockB.id],
- };
- // Set the cursor to be on the stack
- this.workspace.getCursor().setCurNode(astNode);
- // Remove the top block in the stack
- this.navigation.handleBlockDeleteByDrag(
- this.workspace,
- mockDeleteBlockEvent,
- );
- chai.assert.equal(
- this.workspace.getCursor().getCurNode().getType(),
- Blockly.ASTNode.types.WORKSPACE,
- );
- });
- });
-
- suite('Test workspace listener', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '%1',
- args0: [
- {
- type: 'field_input',
- name: 'TEXTFIELD',
- text: 'test',
- },
- ],
- previousStatement: null,
- nextStatement: null,
- },
- ]);
- this.workspace = createNavigationWorkspace(this.navigation, true);
- this.workspaceChangeListener = this.navigation.wsChangeWrapper;
- this.basicBlockA = this.workspace.newBlock('basic_block');
- });
-
- teardown(function () {
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- delete Blockly.Blocks['basic_block'];
- sinon.restore();
- });
-
- test('Handle block mutation', function () {
- const e = {
- type: Blockly.Events.BLOCK_CHANGE,
- element: 'mutation',
- blockId: this.basicBlockA.id,
- workspaceId: this.workspace.id,
- };
- const cursor = this.workspace.getCursor();
- const nextNode = Blockly.ASTNode.createConnectionNode(
- this.basicBlockA.nextConnection,
- );
- cursor.setCurNode(nextNode);
- this.workspaceChangeListener(e);
- chai.assert.equal(
- cursor.getCurNode().getType(),
- Blockly.ASTNode.types.BLOCK,
- );
- });
- test('Handle workspace click', function () {
- const e = {
- type: Blockly.Events.CLICK,
- workspaceId: this.workspace.id,
- };
- this.navigation.focusFlyout(this.workspace);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.FLYOUT,
- );
-
- this.workspaceChangeListener(e);
-
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
- test('Focus toolbox if category clicked', function () {
- const e = {
- type: Blockly.Events.TOOLBOX_ITEM_SELECT,
- workspaceId: this.workspace.id,
- newItem: true,
- };
- const toolboxFocusStub = sinon.spy(this.navigation, 'focusToolbox');
-
- this.navigation.focusWorkspace(this.workspace);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
-
- this.workspaceChangeListener(e);
-
- sinon.assert.calledOnce(toolboxFocusStub);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.TOOLBOX,
- );
- });
- test('Focus workspace if toolbox is unselected', function () {
- const e = {
- type: Blockly.Events.TOOLBOX_ITEM_SELECT,
- workspaceId: this.workspace.id,
- newItem: false,
- };
- const resetFlyoutStub = sinon.spy(this.navigation, 'resetFlyout');
- this.navigation.setState(this.workspace, Constants.STATE.TOOLBOX);
-
- this.workspaceChangeListener(e);
-
- sinon.assert.calledOnce(resetFlyoutStub);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
- test('Focus workspace when block created on workspace', function () {
- const e = {
- type: Blockly.Events.BLOCK_CREATE,
- workspaceId: this.workspace.id,
- };
- const resetFlyoutStub = sinon.spy(this.navigation, 'resetFlyout');
- // Only works when someone is in the flyout.
- this.navigation.setState(this.workspace, Constants.STATE.FLYOUT);
-
- this.workspaceChangeListener(e);
-
- sinon.assert.calledOnce(resetFlyoutStub);
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.WORKSPACE,
- );
- });
- });
-
- suite('Test simple flyout listener', function () {
- setup(function () {
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '%1',
- args0: [
- {
- type: 'field_input',
- name: 'TEXTFIELD',
- text: 'test',
- },
- ],
- },
- ]);
- this.workspace = createNavigationWorkspace(this.navigation, true);
- this.flyoutChangeListener = this.navigation.flyoutChangeWrapper;
- this.basicBlockA = this.workspace.newBlock('basic_block');
-
- this.navigation.focusToolbox(this.workspace);
- this.workspace.getFlyout().autoClose = false;
- });
-
- teardown(function () {
- delete Blockly.Blocks['basic_block'];
- this.navigation.removeWorkspace(this.workspace);
- this.workspace.dispose();
- sinon.restore();
- });
- test('Handle block click in flyout - click event', function () {
- const flyout = this.workspace.getFlyout();
- const flyoutWorkspace = flyout.getWorkspace();
- const firstFlyoutBlock = flyoutWorkspace.getTopBlocks()[0];
- const e = {
- type: Blockly.Events.CLICK,
- workspaceId: flyoutWorkspace.id,
- targetType: 'block',
- blockId: firstFlyoutBlock.id,
- };
- const flyoutCursor = flyoutWorkspace.getCursor();
- this.navigation.focusWorkspace(this.workspace);
-
- this.flyoutChangeListener(e);
-
- chai.assert.equal(
- flyoutCursor.getCurNode().getType(),
- Blockly.ASTNode.types.STACK,
- );
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.FLYOUT,
- );
- });
- test('Handle block click in flyout - select event', function () {
- const flyout = this.workspace.getFlyout();
- const flyoutWorkspace = flyout.getWorkspace();
- const firstFlyoutBlock = flyoutWorkspace.getTopBlocks()[0];
- const e = {
- type: Blockly.Events.SELECTED,
- workspaceId: flyoutWorkspace.id,
- newElementId: firstFlyoutBlock.id,
- };
- const flyoutCursor = flyoutWorkspace.getCursor();
- this.navigation.focusWorkspace(this.workspace);
-
- this.flyoutChangeListener(e);
-
- chai.assert.equal(
- flyoutCursor.getCurNode().getType(),
- Blockly.ASTNode.types.STACK,
- );
- chai.assert.equal(
- this.navigation.getState(this.workspace),
- Constants.STATE.FLYOUT,
- );
- });
- });
-
- suite('Test clean up methods', function () {
- setup(function () {
- this.workspace = createNavigationWorkspace(this.navigation, true);
- });
- test('All listeners and markers removed', function () {
- const numListeners = this.workspace.listeners.length;
- const markerName = this.navigation.MARKER_NAME;
- this.navigation.removeWorkspace(this.workspace);
- chai.assert.equal(this.workspace.listeners.length, numListeners - 1);
-
- const marker = this.workspace.getMarkerManager().getMarker(markerName);
- chai.assert.isNull(marker);
- });
- test('Keyboard accessibility mode can not be enabled', function () {
- this.navigation.removeWorkspace(this.workspace);
- this.navigation.enableKeyboardAccessibility(this.workspace);
- chai.assert.isFalse(this.workspace.keyboardAccessibilityMode);
- });
- test('Dispose', function () {
- const numListeners = this.workspace.listeners.length;
- const flyout = this.workspace.getFlyout();
- const numFlyoutListeners = flyout.getWorkspace().listeners.length;
- this.navigation.dispose();
- chai.assert.equal(this.workspace.listeners.length, numListeners - 1);
- chai.assert.equal(
- flyout.getWorkspace().listeners.length,
- numFlyoutListeners - 1,
- );
- });
- });
-});
diff --git a/plugins/keyboard-navigation/test/shortcuts_test.mocha.js b/plugins/keyboard-navigation/test/shortcuts_test.mocha.js
deleted file mode 100644
index 4e19095210..0000000000
--- a/plugins/keyboard-navigation/test/shortcuts_test.mocha.js
+++ /dev/null
@@ -1,531 +0,0 @@
-/**
- * @license
- * Copyright 2021 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-const sinon = require('sinon');
-const chai = require('chai');
-
-const Blockly = require('blockly');
-
-const {NavigationController} = require('../src/index');
-const {
- createNavigationWorkspace,
- createKeyDownEvent,
-} = require('./test_helper');
-
-suite('Shortcut Tests', function () {
- setup(function () {
- this.jsdomCleanup = require('jsdom-global')(
- '',
- );
- // We are running these tests in node even thought they require a rendered
- // workspace, which doesn't exactly work. The rendering system expects
- // cancelAnimationFrame to be defined so we need to define it.
- window.cancelAnimationFrame = function () {};
-
- Blockly.utils.dom.getFastTextWidthWithSizeString = function () {
- return 10;
- };
- Blockly.defineBlocksWithJsonArray([
- {
- type: 'basic_block',
- message0: '',
- previousStatement: null,
- nextStatement: null,
- },
- ]);
- this.controller = new NavigationController();
- this.controller.init();
- this.navigation = this.controller.navigation;
- this.workspace = createNavigationWorkspace(this.navigation, true);
- this.controller.addWorkspace(this.workspace);
- this.basicBlock = this.workspace.newBlock('basic_block');
- });
-
- teardown(function () {
- window.cancelAnimationFrame = undefined;
- this.controller.dispose();
- this.workspace.dispose();
- this.jsdomCleanup();
- delete Blockly.Blocks['basic_block'];
- });
-
- suite('Deleting blocks', function () {
- setup(function () {
- const blockNode = Blockly.ASTNode.createBlockNode(this.basicBlock);
- this.workspace.getCursor().setCurNode(blockNode);
- });
-
- teardown(function () {
- sinon.restore();
- });
-
- const testCases = [
- {
- name: 'Delete',
- deleteEvent: createKeyDownEvent(
- Blockly.utils.KeyCodes.DELETE,
- 'NotAField',
- ),
- },
- {
- name: 'Backspace',
- deleteEvent: createKeyDownEvent(
- Blockly.utils.KeyCodes.BACKSPACE,
- 'NotAField',
- ),
- },
- ];
-
- suite('delete keybinds trigger deletion', function () {
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.deleteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 0,
- 'Expected the block to be deleted.',
- );
- });
- });
- });
-
- suite(
- 'delete keybinds do not trigger deletion if workspace is readonly',
- function () {
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- this.workspace.options.readOnly = true;
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.deleteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be deleted.',
- );
- });
- });
- },
- );
- });
-
- suite('Copy and paste', function () {
- teardown(function () {
- sinon.restore();
- });
- const testCases = [
- {
- name: 'Control',
- copyEvent: createKeyDownEvent(Blockly.utils.KeyCodes.C, 'NotAField', [
- Blockly.utils.KeyCodes.CTRL,
- ]),
- pasteEvent: createKeyDownEvent(Blockly.utils.KeyCodes.V, 'NotAField', [
- Blockly.utils.KeyCodes.CTRL,
- ]),
- },
- {
- name: 'Meta',
- copyEvent: createKeyDownEvent(Blockly.utils.KeyCodes.C, 'NotAField', [
- Blockly.utils.KeyCodes.META,
- ]),
- pasteEvent: createKeyDownEvent(Blockly.utils.KeyCodes.V, 'NotAField', [
- Blockly.utils.KeyCodes.META,
- ]),
- },
- {
- name: 'Alt',
- copyEvent: createKeyDownEvent(Blockly.utils.KeyCodes.C, 'NotAField', [
- Blockly.utils.KeyCodes.ALT,
- ]),
- pasteEvent: createKeyDownEvent(Blockly.utils.KeyCodes.V, 'NotAField', [
- Blockly.utils.KeyCodes.ALT,
- ]),
- },
- ];
-
- suite('copy and paste keybinds duplicate blocks', function () {
- setup(function () {
- const blockNode = Blockly.ASTNode.createBlockNode(this.basicBlock);
- this.workspace.getCursor().setCurNode(blockNode);
- });
-
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.copyEvent,
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 2,
- 'Expected the block to be duplicated.',
- );
- });
- });
- });
-
- suite(
- 'copy and paste does nothing if the cursor is not on a block',
- function () {
- setup(function () {
- const workspaceNode = Blockly.ASTNode.createWorkspaceNode(
- this.workspace,
- new Blockly.utils.Coordinate(100, 100),
- );
- this.workspace.getCursor().setCurNode(workspaceNode);
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.copyEvent,
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- },
- );
-
- suite(
- 'copy and paste do nothing if the cursor is on a shadow block',
- function () {
- setup(function () {
- this.basicBlock.setShadow(true);
- const blockNode = Blockly.ASTNode.createBlockNode(this.basicBlock);
- this.workspace.getCursor().setCurNode(blockNode);
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.copyEvent,
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- },
- );
-
- suite(
- 'copy and paste do nothing if the workspace is readonly',
- function () {
- setup(function () {
- this.workspace.options.readonly = true;
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.copyEvent,
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- },
- );
-
- suite('copy and paste do nothing if a gesture is in progress', function () {
- setup(function () {
- sinon.stub(Blockly.Gesture, 'inProgress').returns(true);
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.copyEvent,
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- });
-
- suite(
- 'copy and paste do nothing if the block is not deletable',
- function () {
- setup(function () {
- this.basicBlock.setDeletable(false);
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.copyEvent,
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- },
- );
- });
-
- suite('Cut and paste', function () {
- teardown(function () {
- sinon.restore();
- });
- const testCases = [
- {
- name: 'Control',
- cutEvent: createKeyDownEvent(Blockly.utils.KeyCodes.X, 'NotAField', [
- Blockly.utils.KeyCodes.CTRL,
- ]),
- pasteEvent: createKeyDownEvent(Blockly.utils.KeyCodes.V, 'NotAField', [
- Blockly.utils.KeyCodes.CTRL,
- ]),
- },
- {
- name: 'Meta',
- cutEvent: createKeyDownEvent(Blockly.utils.KeyCodes.X, 'NotAField', [
- Blockly.utils.KeyCodes.META,
- ]),
- pasteEvent: createKeyDownEvent(Blockly.utils.KeyCodes.V, 'NotAField', [
- Blockly.utils.KeyCodes.META,
- ]),
- },
- {
- name: 'Alt',
- cutEvent: createKeyDownEvent(Blockly.utils.KeyCodes.X, 'NotAField', [
- Blockly.utils.KeyCodes.ALT,
- ]),
- pasteEvent: createKeyDownEvent(Blockly.utils.KeyCodes.V, 'NotAField', [
- Blockly.utils.KeyCodes.ALT,
- ]),
- },
- ];
-
- suite('cut and paste keybinds duplicate blocks', function () {
- setup(function () {
- const blockNode = Blockly.ASTNode.createBlockNode(this.basicBlock);
- this.workspace.getCursor().setCurNode(blockNode);
- });
-
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.cutEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 0,
- 'Expected the block to be deleted.',
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to be duplicated.',
- );
- });
- });
- });
-
- suite(
- 'cut and paste does nothing if the cursor is not on a block',
- function () {
- setup(function () {
- const workspaceNode = Blockly.ASTNode.createWorkspaceNode(
- this.workspace,
- new Blockly.utils.Coordinate(100, 100),
- );
- this.workspace.getCursor().setCurNode(workspaceNode);
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.cutEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be deleted.',
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- },
- );
-
- suite(
- 'cut and paste do nothing if the cursor is on a shadow block',
- function () {
- setup(function () {
- this.basicBlock.setShadow(true);
- const blockNode = Blockly.ASTNode.createBlockNode(this.basicBlock);
- this.workspace.getCursor().setCurNode(blockNode);
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.cutEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be deleted.',
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- },
- );
-
- suite('cut and paste do nothing if the workspace is readonly', function () {
- setup(function () {
- this.workspace.options.readonly = true;
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.cutEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be deleted.',
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- });
-
- suite('cut and paste do nothing if a gesture is in progress', function () {
- setup(function () {
- sinon.stub(Blockly.Gesture, 'inProgress').returns(true);
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.cutEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be deleted.',
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- });
-
- suite(
- 'cut and paste do nothing if the block is not deletable',
- function () {
- setup(function () {
- this.basicBlock.setDeletable(false);
- });
- testCases.forEach(function (testCase) {
- test(testCase.name, function () {
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.cutEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be deleted.',
- );
- Blockly.ShortcutRegistry.registry.onKeyDown(
- this.workspace,
- testCase.pasteEvent,
- );
- chai.assert.equal(
- this.workspace.getTopBlocks().length,
- 1,
- 'Expected the block to not be duplicated.',
- );
- });
- });
- },
- );
- });
-});
diff --git a/plugins/keyboard-navigation/test/test_helper.js b/plugins/keyboard-navigation/test/test_helper.js
deleted file mode 100644
index 99abcb5fb3..0000000000
--- a/plugins/keyboard-navigation/test/test_helper.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @license
- * Copyright 2021 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-const {Constants} = require('../src/index');
-const {Navigation} = require('../src/index');
-const Blockly = require('blockly/core');
-
-/**
- * Creates a workspace for testing keyboard navigation.
- * @param {Navigation} navigation Object holding navigation classes.
- * @param {boolean} enableKeyboardNav True to enable keyboard navigation, false
- * otherwise.
- * @param {boolean} readOnly True for a read only workspace, false otherwise.
- * @returns {Blockly.WorkspaceSvg} The created workspace.
- */
-export function createNavigationWorkspace(
- navigation,
- enableKeyboardNav,
- readOnly,
-) {
- const workspace = Blockly.inject('blocklyDiv', {
- toolbox: `
-
-
-
- first
-
-
- second
-
-
-
-
- third
-
-
-
- `,
- readOnly: readOnly,
- });
- if (enableKeyboardNav) {
- navigation.addWorkspace(workspace);
- navigation.enableKeyboardAccessibility(workspace);
- navigation.setState(workspace, Constants.STATE.WORKSPACE);
- }
- return workspace;
-}
-
-/**
- * Creates a key down event used for testing.
- * @param {number} keyCode The keycode for the event. Use Blockly.utils.KeyCodes
- * enum.
- * @param {string} type The type of the target. This only matters for the
- * Blockly.utils.isTargetInput method.
- * @param {?Array} modifiers A list of modifiers. Use
- * Blockly.utils.KeyCodes enum.
- * @returns {Object} The mocked keydown
- * event.
- */
-export function createKeyDownEvent(keyCode, type, modifiers) {
- const event = {
- keyCode: keyCode,
- target: {type: type},
- getModifierState: function (name) {
- if (name == 'Shift' && this.shiftKey) {
- return true;
- } else if (name == 'Control' && this.ctrlKey) {
- return true;
- } else if (name == 'Meta' && this.metaKey) {
- return true;
- } else if (name == 'Alt' && this.altKey) {
- return true;
- }
- return false;
- },
- preventDefault: function () {},
- };
- if (modifiers && modifiers.length) {
- event.altKey = modifiers.includes(Blockly.utils.KeyCodes.ALT);
- event.ctrlKey = modifiers.includes(Blockly.utils.KeyCodes.CTRL);
- event.metaKey = modifiers.includes(Blockly.utils.KeyCodes.META);
- event.shiftKey = modifiers.includes(Blockly.utils.KeyCodes.SHIFT);
- }
- return event;
-}
diff --git a/plugins/keyboard-navigation/test/toolbox.js b/plugins/keyboard-navigation/test/toolbox.js
deleted file mode 100644
index 95dd4ff7bd..0000000000
--- a/plugins/keyboard-navigation/test/toolbox.js
+++ /dev/null
@@ -1,218 +0,0 @@
-/**
- * @license
- * Copyright 2024 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * @fileoverview A custom toolbox for the plugin test.
- */
-
-export const toolbox = {
- kind: 'categoryToolbox',
- contents: [
- {
- kind: 'category',
- name: 'Logic',
- categorystyle: 'logic_category',
- contents: [
- {
- type: 'controls_if',
- kind: 'block',
- },
- {
- type: 'logic_compare',
- kind: 'block',
- fields: {
- OP: 'EQ',
- },
- },
- {
- type: 'logic_operation',
- kind: 'block',
- fields: {
- OP: 'AND',
- },
- },
- ],
- },
- {
- kind: 'category',
- name: 'Loops',
- categorystyle: 'loop_category',
- contents: [
- {
- type: 'controls_repeat_ext',
- kind: 'block',
- inputs: {
- TIMES: {
- shadow: {
- type: 'math_number',
- fields: {
- NUM: 10,
- },
- },
- },
- },
- },
- {
- type: 'controls_repeat',
- kind: 'block',
- enabled: false,
- fields: {
- TIMES: 10,
- },
- },
- {
- type: 'controls_whileUntil',
- kind: 'block',
- fields: {
- MODE: 'WHILE',
- },
- },
- {
- type: 'controls_for',
- kind: 'block',
- fields: {
- VAR: {
- name: 'i',
- },
- },
- inputs: {
- FROM: {
- shadow: {
- type: 'math_number',
- fields: {
- NUM: 1,
- },
- },
- },
- TO: {
- shadow: {
- type: 'math_number',
- fields: {
- NUM: 10,
- },
- },
- },
- BY: {
- shadow: {
- type: 'math_number',
- fields: {
- NUM: 1,
- },
- },
- },
- },
- },
- {
- type: 'controls_forEach',
- kind: 'block',
- fields: {
- VAR: {
- name: 'j',
- },
- },
- },
- {
- type: 'controls_flow_statements',
- kind: 'block',
- enabled: false,
- fields: {
- FLOW: 'BREAK',
- },
- },
- ],
- },
- {
- kind: 'sep',
- },
- {
- kind: 'category',
- name: 'Variables',
- custom: 'VARIABLE',
- categorystyle: 'variable_category',
- },
- {
- kind: 'category',
- name: 'Buttons and Blocks',
- categorystyle: 'loop_category',
- contents: [
- {
- type: 'controls_repeat',
- kind: 'block',
- fields: {
- TIMES: 10,
- },
- },
- {
- kind: 'BUTTON',
- text: 'Randomize Button Style',
- callbackkey: 'setRandomStyle',
- },
- {
- kind: 'BUTTON',
- text: 'Randomize Button Style',
- callbackkey: 'setRandomStyle',
- },
- {
- type: 'controls_repeat',
- kind: 'block',
- fields: {
- TIMES: 10,
- },
- },
- {
- kind: 'BUTTON',
- text: 'Randomize Button Style',
- callbackkey: 'setRandomStyle',
- },
- ],
- },
- {
- kind: 'sep',
- },
- {
- kind: 'category',
- name: 'Nested Categories',
- contents: [
- {
- kind: 'category',
- name: 'sub-category 1',
- contents: [
- {
- kind: 'BUTTON',
- text: 'Randomize Button Style',
- callbackkey: 'setRandomStyle',
- },
- {
- type: 'logic_boolean',
- kind: 'block',
- fields: {
- BOOL: 'TRUE',
- },
- },
- ],
- },
- {
- kind: 'category',
- name: 'sub-category 2',
- contents: [
- {
- type: 'logic_boolean',
- kind: 'block',
- fields: {
- BOOL: 'FALSE',
- },
- },
- {
- kind: 'BUTTON',
- text: 'Randomize Button Style',
- callbackkey: 'setRandomStyle',
- },
- ],
- },
- ],
- },
- ],
-};
diff --git a/plugins/migration/CHANGELOG.md b/plugins/migration/CHANGELOG.md
index d9a8438d55..33a5d899d8 100644
--- a/plugins/migration/CHANGELOG.md
+++ b/plugins/migration/CHANGELOG.md
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [3.0.3](https://github.com/google/blockly-samples/compare/@blockly/migrate@3.0.2...@blockly/migrate@3.0.3) (2025-03-13)
+
+**Note:** Version bump only for package @blockly/migrate
+
+
+
+
+
## [3.0.2](https://github.com/google/blockly-samples/compare/@blockly/migrate@3.0.1...@blockly/migrate@3.0.2) (2024-08-08)
diff --git a/plugins/migration/bin/fix-imports.js b/plugins/migration/bin/fix-imports.js
index abaa79bee7..642767c715 100644
--- a/plugins/migration/bin/fix-imports.js
+++ b/plugins/migration/bin/fix-imports.js
@@ -99,6 +99,13 @@ const database = [
newImport: `import * as libraryBlocks from 'blockly/blocks';`,
newRequire: `const libraryBlocks = require('blockly/blocks');`,
},
+ {
+ import: 'blockly',
+ oldIdentifier: 'Blockly',
+ newIdentifier: 'Blockly', // no-op
+ newImport: `import * as Blockly from 'blockly';`,
+ newRequire: `const Blockly = require('blockly');`, // no-op
+ },
];
/**
@@ -125,9 +132,18 @@ function migrateContents(contents) {
*/
function fixImport(contents, migrationData) {
const identifier = getIdentifier(contents, migrationData);
+ // Don't need to run if there are no references.
if (!identifier) return contents;
- const newContents = replaceReferences(contents, migrationData, identifier);
- if (newContents !== contents) return addImport(newContents, migrationData);
+ // If the identifier changed, update all references to it and the import
+ if (migrationData.oldIdentifier !== migrationData.newIdentifier) {
+ const newContents = replaceReferences(contents, migrationData, identifier);
+ if (newContents !== contents) {
+ return addImport(newContents, migrationData);
+ }
+ } else {
+ // Just the import changed
+ return addImport(contents, migrationData);
+ }
return contents;
}
diff --git a/plugins/migration/package-lock.json b/plugins/migration/package-lock.json
index 24f0cfaea3..a485ded8aa 100644
--- a/plugins/migration/package-lock.json
+++ b/plugins/migration/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/migrate",
- "version": "3.0.2",
+ "version": "3.0.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/migrate",
- "version": "3.0.2",
+ "version": "3.0.3",
"license": "Apache-2.0",
"dependencies": {
"chalk": "^5.0.1",
@@ -2062,4 +2062,4 @@
"dev": true
}
}
-}
+}
\ No newline at end of file
diff --git a/plugins/migration/package.json b/plugins/migration/package.json
index 4f93c81182..d752897ff0 100644
--- a/plugins/migration/package.json
+++ b/plugins/migration/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/migrate",
- "version": "3.0.2",
+ "version": "3.0.3",
"description": "A collection of tools that help with migrating apps using Blockly to new versions of BLockly.",
"bin": "./bin/migrate.js",
"author": "Blockly Team",
diff --git a/plugins/migration/test/manual-test-data/fix-imports/import.txt b/plugins/migration/test/manual-test-data/fix-imports/import.js
similarity index 85%
rename from plugins/migration/test/manual-test-data/fix-imports/import.txt
rename to plugins/migration/test/manual-test-data/fix-imports/import.js
index 4344593a55..721272e09e 100644
--- a/plugins/migration/test/manual-test-data/fix-imports/import.txt
+++ b/plugins/migration/test/manual-test-data/fix-imports/import.js
@@ -1,11 +1,11 @@
// Manual test data for the renamings migration.
// Run using:
-// node ./bin/migrate fix-imports --from ./test/manual-test-data/fix-imports/import.txt
+// node ./bin/migrate fix-imports --from ./test/manual-test-data/fix-imports/import.js
import Blockly from 'blockly';
-import * as BlocklyDart from "blockly/dart";
+import * as BlocklyDart from 'blockly/dart';
import * as BlocklyLua from 'blockly/lua';
-import * as BlocklyPhp from "blockly/php";
+import * as BlocklyPhp from 'blockly/php';
import * as BlocklyPython from 'blockly/python';
Blockly.JavaScript.something;
@@ -31,3 +31,5 @@ Some.Other.identifer;
Blockly.libraryBlocks.something;
const something = Blockly.libraryBlocks.something;
Some.Other.identifer;
+
+Blockly.zelos;
diff --git a/plugins/migration/test/manual-test-data/fix-imports/mixed-1.txt b/plugins/migration/test/manual-test-data/fix-imports/mixed-1.js
similarity index 98%
rename from plugins/migration/test/manual-test-data/fix-imports/mixed-1.txt
rename to plugins/migration/test/manual-test-data/fix-imports/mixed-1.js
index 1c45be79da..77ffed9a26 100644
--- a/plugins/migration/test/manual-test-data/fix-imports/mixed-1.txt
+++ b/plugins/migration/test/manual-test-data/fix-imports/mixed-1.js
@@ -31,3 +31,5 @@ Some.Other.identifer;
Blockly.libraryBlocks.something;
const something = Blockly.libraryBlocks.something;
Some.Other.identifer;
+
+Blockly.zelos;
diff --git a/plugins/migration/test/manual-test-data/fix-imports/mixed-2.txt b/plugins/migration/test/manual-test-data/fix-imports/mixed-2.js
similarity index 89%
rename from plugins/migration/test/manual-test-data/fix-imports/mixed-2.txt
rename to plugins/migration/test/manual-test-data/fix-imports/mixed-2.js
index 320ddd2fe0..d8b8ca3fdc 100644
--- a/plugins/migration/test/manual-test-data/fix-imports/mixed-2.txt
+++ b/plugins/migration/test/manual-test-data/fix-imports/mixed-2.js
@@ -3,9 +3,9 @@
// node ./bin/migrate fix-imports --from ./test/manual-test-data/fix-imports/mixed-1.txt
const Blockly = require('blockly');
-import * as BlocklyDart from "blockly/dart";
+import * as BlocklyDart from 'blockly/dart';
const BlocklyLua = require('blockly/lua');
-import * as BlocklyPhp from "blockly/php";
+import * as BlocklyPhp from 'blockly/php';
const BlocklyPython = require('blockly/python');
Blockly.JavaScript.something;
@@ -31,3 +31,5 @@ Some.Other.identifer;
Blockly.libraryBlocks.something;
const something = Blockly.libraryBlocks.something;
Some.Other.identifer;
+
+Blockly.zelos;
diff --git a/plugins/migration/test/manual-test-data/fix-imports/require.txt b/plugins/migration/test/manual-test-data/fix-imports/require.js
similarity index 89%
rename from plugins/migration/test/manual-test-data/fix-imports/require.txt
rename to plugins/migration/test/manual-test-data/fix-imports/require.js
index 58b8fa0d88..d6a9410582 100644
--- a/plugins/migration/test/manual-test-data/fix-imports/require.txt
+++ b/plugins/migration/test/manual-test-data/fix-imports/require.js
@@ -3,9 +3,9 @@
// node ./bin/migrate fix-imports --from ./test/manual-test-data/fix-imports/require.txt
const Blockly = require('blockly');
-const BlocklyDart = require("blockly/dart");
+const BlocklyDart = require('blockly/dart');
const BlocklyLua = require('blockly/lua');
-let BlocklyPhp = require("blockly/php");
+let BlocklyPhp = require('blockly/php');
var BlocklyPython = require('blockly/python');
Blockly.JavaScript.something;
@@ -31,3 +31,5 @@ Some.Other.identifer;
Blockly.libraryBlocks.something;
const something = Blockly.libraryBlocks.something;
Some.Other.identifer;
+
+Blockly.zelos;
diff --git a/plugins/migration/test/manual-test-data/rename.txt b/plugins/migration/test/manual-test-data/rename.js
similarity index 99%
rename from plugins/migration/test/manual-test-data/rename.txt
rename to plugins/migration/test/manual-test-data/rename.js
index 6ce4c46d61..55bb51b878 100644
--- a/plugins/migration/test/manual-test-data/rename.txt
+++ b/plugins/migration/test/manual-test-data/rename.js
@@ -25,4 +25,4 @@ class SubClass extends Blockly.moduleC {
const thingA = /** @type {Blockly.moduleD} */ (new Blockly.moduleE());
return thingA.someMethod(paramA, paramB);
}
-};
+}
diff --git a/plugins/modal/CHANGELOG.md b/plugins/modal/CHANGELOG.md
index e537ac675e..a3e34e76c1 100644
--- a/plugins/modal/CHANGELOG.md
+++ b/plugins/modal/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [7.0.14](https://github.com/google/blockly-samples/compare/@blockly/plugin-modal@7.0.13...@blockly/plugin-modal@7.0.14) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/plugin-modal
+
+
+
+
+
+## [7.0.13](https://github.com/google/blockly-samples/compare/@blockly/plugin-modal@7.0.12...@blockly/plugin-modal@7.0.13) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/plugin-modal
+
+
+
+
+
+## [7.0.12](https://github.com/google/blockly-samples/compare/@blockly/plugin-modal@7.0.11...@blockly/plugin-modal@7.0.12) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/plugin-modal
+
+
+
+
+
## [7.0.11](https://github.com/google/blockly-samples/compare/@blockly/plugin-modal@7.0.10...@blockly/plugin-modal@7.0.11) (2024-11-07)
**Note:** Version bump only for package @blockly/plugin-modal
diff --git a/plugins/modal/package-lock.json b/plugins/modal/package-lock.json
index 56372b293b..91cfc1a495 100644
--- a/plugins/modal/package-lock.json
+++ b/plugins/modal/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/plugin-modal",
- "version": "7.0.11",
+ "version": "7.0.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/plugin-modal",
- "version": "7.0.11",
+ "version": "7.0.14",
"license": "Apache 2.0",
"devDependencies": {
"jsdom": "^19.0.0",
diff --git a/plugins/modal/package.json b/plugins/modal/package.json
index 74e2c988bc..8be8b25446 100644
--- a/plugins/modal/package.json
+++ b/plugins/modal/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/plugin-modal",
- "version": "7.0.11",
+ "version": "7.0.14",
"description": "A Blockly plugin that creates a modal.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -39,8 +39,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"jsdom": "^19.0.0",
"jsdom-global": "3.0.2",
"mocha": "^10.1.0",
diff --git a/plugins/scroll-options/CHANGELOG.md b/plugins/scroll-options/CHANGELOG.md
index 37895e55b7..14602d7137 100644
--- a/plugins/scroll-options/CHANGELOG.md
+++ b/plugins/scroll-options/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [6.0.14](https://github.com/google/blockly-samples/compare/@blockly/plugin-scroll-options@6.0.13...@blockly/plugin-scroll-options@6.0.14) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/plugin-scroll-options
+
+
+
+
+
+## [6.0.13](https://github.com/google/blockly-samples/compare/@blockly/plugin-scroll-options@6.0.12...@blockly/plugin-scroll-options@6.0.13) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/plugin-scroll-options
+
+
+
+
+
+## [6.0.12](https://github.com/google/blockly-samples/compare/@blockly/plugin-scroll-options@6.0.11...@blockly/plugin-scroll-options@6.0.12) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/plugin-scroll-options
+
+
+
+
+
## [6.0.11](https://github.com/google/blockly-samples/compare/@blockly/plugin-scroll-options@6.0.10...@blockly/plugin-scroll-options@6.0.11) (2024-11-07)
**Note:** Version bump only for package @blockly/plugin-scroll-options
diff --git a/plugins/scroll-options/package-lock.json b/plugins/scroll-options/package-lock.json
index fd8ed5d868..1e5dbb7851 100644
--- a/plugins/scroll-options/package-lock.json
+++ b/plugins/scroll-options/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/plugin-scroll-options",
- "version": "6.0.11",
+ "version": "6.0.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/plugin-scroll-options",
- "version": "6.0.11",
+ "version": "6.0.14",
"license": "Apache-2.0",
"devDependencies": {
"typescript": "^5.4.5"
diff --git a/plugins/scroll-options/package.json b/plugins/scroll-options/package.json
index 38294a7f0d..56deab5ed2 100644
--- a/plugins/scroll-options/package.json
+++ b/plugins/scroll-options/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/plugin-scroll-options",
- "version": "6.0.11",
+ "version": "6.0.14",
"description": "A Blockly plugin that adds advanced scroll options such as scroll-on-drag and scroll while holding a block.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -39,8 +39,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"typescript": "^5.4.5"
},
"peerDependencies": {
diff --git a/plugins/shadow-block-converter/CHANGELOG.md b/plugins/shadow-block-converter/CHANGELOG.md
index e3bda47a3a..6f8f83874f 100644
--- a/plugins/shadow-block-converter/CHANGELOG.md
+++ b/plugins/shadow-block-converter/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [6.0.15](https://github.com/google/blockly-samples/compare/@blockly/shadow-block-converter@6.0.14...@blockly/shadow-block-converter@6.0.15) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/shadow-block-converter
+
+
+
+
+
+## [6.0.14](https://github.com/google/blockly-samples/compare/@blockly/shadow-block-converter@6.0.13...@blockly/shadow-block-converter@6.0.14) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/shadow-block-converter
+
+
+
+
+
+## [6.0.13](https://github.com/google/blockly-samples/compare/@blockly/shadow-block-converter@6.0.12...@blockly/shadow-block-converter@6.0.13) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/shadow-block-converter
+
+
+
+
+
## [6.0.12](https://github.com/google/blockly-samples/compare/@blockly/shadow-block-converter@6.0.11...@blockly/shadow-block-converter@6.0.12) (2024-11-07)
**Note:** Version bump only for package @blockly/shadow-block-converter
diff --git a/plugins/shadow-block-converter/package-lock.json b/plugins/shadow-block-converter/package-lock.json
index 693140389f..6de9e0efa3 100644
--- a/plugins/shadow-block-converter/package-lock.json
+++ b/plugins/shadow-block-converter/package-lock.json
@@ -1,16 +1,16 @@
{
"name": "@blockly/shadow-block-converter",
- "version": "6.0.12",
+ "version": "6.0.15",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/shadow-block-converter",
- "version": "6.0.12",
+ "version": "6.0.15",
"license": "Apache-2.0",
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"chai": "^4.2.0",
"jsdom": "^19.0.0",
"jsdom-global": "^3.0.2",
diff --git a/plugins/shadow-block-converter/package.json b/plugins/shadow-block-converter/package.json
index 41c6e8cd83..93fe936d09 100644
--- a/plugins/shadow-block-converter/package.json
+++ b/plugins/shadow-block-converter/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/shadow-block-converter",
- "version": "6.0.12",
+ "version": "6.0.15",
"description": "A workspace change listener that converts shadow blocks to real blocks when the user edits them.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -39,8 +39,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"chai": "^4.2.0",
"jsdom": "^19.0.0",
"jsdom-global": "^3.0.2",
diff --git a/plugins/strict-connection-checker/CHANGELOG.md b/plugins/strict-connection-checker/CHANGELOG.md
index b33ff707c0..31a27ec151 100644
--- a/plugins/strict-connection-checker/CHANGELOG.md
+++ b/plugins/strict-connection-checker/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [5.0.14](https://github.com/google/blockly-samples/compare/@blockly/plugin-strict-connection-checker@5.0.13...@blockly/plugin-strict-connection-checker@5.0.14) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/plugin-strict-connection-checker
+
+
+
+
+
+## [5.0.13](https://github.com/google/blockly-samples/compare/@blockly/plugin-strict-connection-checker@5.0.12...@blockly/plugin-strict-connection-checker@5.0.13) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/plugin-strict-connection-checker
+
+
+
+
+
+## [5.0.12](https://github.com/google/blockly-samples/compare/@blockly/plugin-strict-connection-checker@5.0.11...@blockly/plugin-strict-connection-checker@5.0.12) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/plugin-strict-connection-checker
+
+
+
+
+
## [5.0.11](https://github.com/google/blockly-samples/compare/@blockly/plugin-strict-connection-checker@5.0.10...@blockly/plugin-strict-connection-checker@5.0.11) (2024-11-07)
**Note:** Version bump only for package @blockly/plugin-strict-connection-checker
diff --git a/plugins/strict-connection-checker/package-lock.json b/plugins/strict-connection-checker/package-lock.json
index edc591e1df..2b487deaa7 100644
--- a/plugins/strict-connection-checker/package-lock.json
+++ b/plugins/strict-connection-checker/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/plugin-strict-connection-checker",
- "version": "5.0.11",
+ "version": "5.0.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/plugin-strict-connection-checker",
- "version": "5.0.11",
+ "version": "5.0.14",
"license": "Apache 2.0",
"devDependencies": {
"chai": "^4.2.0"
diff --git a/plugins/strict-connection-checker/package.json b/plugins/strict-connection-checker/package.json
index cd6acf00d1..abd03b83c4 100644
--- a/plugins/strict-connection-checker/package.json
+++ b/plugins/strict-connection-checker/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/plugin-strict-connection-checker",
- "version": "5.0.11",
+ "version": "5.0.14",
"description": "A connection checker that prevents blocks that don't provide type information from being connected to blocks that do.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -40,8 +40,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"chai": "^4.2.0"
},
"peerDependencies": {
diff --git a/plugins/suggested-blocks/CHANGELOG.md b/plugins/suggested-blocks/CHANGELOG.md
index 7569bf71e9..8b31d6a7a7 100644
--- a/plugins/suggested-blocks/CHANGELOG.md
+++ b/plugins/suggested-blocks/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [5.0.14](https://github.com/google/blockly-samples/compare/@blockly/suggested-blocks@5.0.13...@blockly/suggested-blocks@5.0.14) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/suggested-blocks
+
+
+
+
+
+## [5.0.13](https://github.com/google/blockly-samples/compare/@blockly/suggested-blocks@5.0.12...@blockly/suggested-blocks@5.0.13) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/suggested-blocks
+
+
+
+
+
+## [5.0.12](https://github.com/google/blockly-samples/compare/@blockly/suggested-blocks@5.0.11...@blockly/suggested-blocks@5.0.12) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/suggested-blocks
+
+
+
+
+
## [5.0.11](https://github.com/google/blockly-samples/compare/@blockly/suggested-blocks@5.0.10...@blockly/suggested-blocks@5.0.11) (2024-11-07)
**Note:** Version bump only for package @blockly/suggested-blocks
diff --git a/plugins/suggested-blocks/package-lock.json b/plugins/suggested-blocks/package-lock.json
index 932fb8b3fc..b90f616abc 100644
--- a/plugins/suggested-blocks/package-lock.json
+++ b/plugins/suggested-blocks/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/suggested-blocks",
- "version": "5.0.11",
+ "version": "5.0.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/suggested-blocks",
- "version": "5.0.11",
+ "version": "5.0.14",
"license": "Apache-2.0",
"devDependencies": {
"chai": "^4.3.6",
diff --git a/plugins/suggested-blocks/package.json b/plugins/suggested-blocks/package.json
index 2c743f79e7..b0029974f4 100644
--- a/plugins/suggested-blocks/package.json
+++ b/plugins/suggested-blocks/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/suggested-blocks",
- "version": "5.0.11",
+ "version": "5.0.14",
"description": "A plugin that adds toolbox panes with suggested blocks based on the user's past usage of blocks.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -40,8 +40,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"chai": "^4.3.6",
"sinon": "^14.0.0"
},
diff --git a/plugins/theme-dark/CHANGELOG.md b/plugins/theme-dark/CHANGELOG.md
index 8bb46b9689..749e6d7653 100644
--- a/plugins/theme-dark/CHANGELOG.md
+++ b/plugins/theme-dark/CHANGELOG.md
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [7.0.10](https://github.com/google/blockly-samples/compare/@blockly/theme-dark@7.0.9...@blockly/theme-dark@7.0.10) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/theme-dark
+
+
+
+
+
## [7.0.9](https://github.com/google/blockly-samples/compare/@blockly/theme-dark@7.0.8...@blockly/theme-dark@7.0.9) (2024-11-07)
**Note:** Version bump only for package @blockly/theme-dark
diff --git a/plugins/theme-dark/package-lock.json b/plugins/theme-dark/package-lock.json
index de6b71c0d0..f10f30ece3 100644
--- a/plugins/theme-dark/package-lock.json
+++ b/plugins/theme-dark/package-lock.json
@@ -1,15 +1,15 @@
{
"name": "@blockly/theme-dark",
- "version": "7.0.9",
+ "version": "7.0.10",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/theme-dark",
- "version": "7.0.9",
+ "version": "7.0.10",
"license": "Apache-2.0",
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"engines": {
"node": ">=8.17.0"
diff --git a/plugins/theme-dark/package.json b/plugins/theme-dark/package.json
index 131b65085e..cfeac6d660 100644
--- a/plugins/theme-dark/package.json
+++ b/plugins/theme-dark/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/theme-dark",
- "version": "7.0.9",
+ "version": "7.0.10",
"description": "A Blockly dark theme.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -40,7 +40,7 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"peerDependencies": {
"blockly": "^11.0.0"
diff --git a/plugins/theme-deuteranopia/CHANGELOG.md b/plugins/theme-deuteranopia/CHANGELOG.md
index 14a4149caa..9edc14361f 100644
--- a/plugins/theme-deuteranopia/CHANGELOG.md
+++ b/plugins/theme-deuteranopia/CHANGELOG.md
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [6.0.10](https://github.com/google/blockly-samples/compare/@blockly/theme-deuteranopia@6.0.9...@blockly/theme-deuteranopia@6.0.10) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/theme-deuteranopia
+
+
+
+
+
## [6.0.9](https://github.com/google/blockly-samples/compare/@blockly/theme-deuteranopia@6.0.8...@blockly/theme-deuteranopia@6.0.9) (2024-11-07)
**Note:** Version bump only for package @blockly/theme-deuteranopia
diff --git a/plugins/theme-deuteranopia/package-lock.json b/plugins/theme-deuteranopia/package-lock.json
index 6178e9d7cf..38cba68ab6 100644
--- a/plugins/theme-deuteranopia/package-lock.json
+++ b/plugins/theme-deuteranopia/package-lock.json
@@ -1,15 +1,15 @@
{
"name": "@blockly/theme-deuteranopia",
- "version": "6.0.9",
+ "version": "6.0.10",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/theme-deuteranopia",
- "version": "6.0.9",
+ "version": "6.0.10",
"license": "Apache-2.0",
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"engines": {
"node": ">=8.17.0"
diff --git a/plugins/theme-deuteranopia/package.json b/plugins/theme-deuteranopia/package.json
index 0b95497730..ac9b0936b5 100644
--- a/plugins/theme-deuteranopia/package.json
+++ b/plugins/theme-deuteranopia/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/theme-deuteranopia",
- "version": "6.0.9",
+ "version": "6.0.10",
"description": "A Blockly theme for people that have deuteranopia.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -40,7 +40,7 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"peerDependencies": {
"blockly": "^11.0.0"
diff --git a/plugins/theme-highcontrast/CHANGELOG.md b/plugins/theme-highcontrast/CHANGELOG.md
index 1a86faa465..14aa9d636e 100644
--- a/plugins/theme-highcontrast/CHANGELOG.md
+++ b/plugins/theme-highcontrast/CHANGELOG.md
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [6.0.10](https://github.com/google/blockly-samples/compare/@blockly/theme-highcontrast@6.0.9...@blockly/theme-highcontrast@6.0.10) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/theme-highcontrast
+
+
+
+
+
## [6.0.9](https://github.com/google/blockly-samples/compare/@blockly/theme-highcontrast@6.0.8...@blockly/theme-highcontrast@6.0.9) (2024-11-07)
**Note:** Version bump only for package @blockly/theme-highcontrast
diff --git a/plugins/theme-highcontrast/package-lock.json b/plugins/theme-highcontrast/package-lock.json
index 9ba8d520f0..b99c1ec691 100644
--- a/plugins/theme-highcontrast/package-lock.json
+++ b/plugins/theme-highcontrast/package-lock.json
@@ -1,15 +1,15 @@
{
"name": "@blockly/theme-highcontrast",
- "version": "6.0.9",
+ "version": "6.0.10",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/theme-highcontrast",
- "version": "6.0.9",
+ "version": "6.0.10",
"license": "Apache-2.0",
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"engines": {
"node": ">=8.17.0"
diff --git a/plugins/theme-highcontrast/package.json b/plugins/theme-highcontrast/package.json
index d35daf54cf..a264dcd52b 100644
--- a/plugins/theme-highcontrast/package.json
+++ b/plugins/theme-highcontrast/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/theme-highcontrast",
- "version": "6.0.9",
+ "version": "6.0.10",
"description": "A Blockly high contrast theme.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -40,7 +40,7 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"peerDependencies": {
"blockly": "^11.0.0"
diff --git a/plugins/theme-modern/CHANGELOG.md b/plugins/theme-modern/CHANGELOG.md
index 90ea69d3ba..0ed1f1a4de 100644
--- a/plugins/theme-modern/CHANGELOG.md
+++ b/plugins/theme-modern/CHANGELOG.md
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [6.0.10](https://github.com/google/blockly-samples/compare/@blockly/theme-modern@6.0.9...@blockly/theme-modern@6.0.10) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/theme-modern
+
+
+
+
+
## [6.0.9](https://github.com/google/blockly-samples/compare/@blockly/theme-modern@6.0.8...@blockly/theme-modern@6.0.9) (2024-11-07)
**Note:** Version bump only for package @blockly/theme-modern
diff --git a/plugins/theme-modern/package-lock.json b/plugins/theme-modern/package-lock.json
index bc79786b39..1da58cb6b6 100644
--- a/plugins/theme-modern/package-lock.json
+++ b/plugins/theme-modern/package-lock.json
@@ -1,15 +1,15 @@
{
"name": "@blockly/theme-modern",
- "version": "6.0.9",
+ "version": "6.0.10",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/theme-modern",
- "version": "6.0.9",
+ "version": "6.0.10",
"license": "Apache-2.0",
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"engines": {
"node": ">=8.17.0"
diff --git a/plugins/theme-modern/package.json b/plugins/theme-modern/package.json
index c4c283f4ac..37862bc36e 100644
--- a/plugins/theme-modern/package.json
+++ b/plugins/theme-modern/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/theme-modern",
- "version": "6.0.9",
+ "version": "6.0.10",
"description": "A Blockly modern theme with darker block borders.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -40,7 +40,7 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"peerDependencies": {
"blockly": "^11.0.0"
diff --git a/plugins/theme-tritanopia/CHANGELOG.md b/plugins/theme-tritanopia/CHANGELOG.md
index d242843678..e70f985331 100644
--- a/plugins/theme-tritanopia/CHANGELOG.md
+++ b/plugins/theme-tritanopia/CHANGELOG.md
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [6.0.10](https://github.com/google/blockly-samples/compare/@blockly/theme-tritanopia@6.0.9...@blockly/theme-tritanopia@6.0.10) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/theme-tritanopia
+
+
+
+
+
## [6.0.9](https://github.com/google/blockly-samples/compare/@blockly/theme-tritanopia@6.0.8...@blockly/theme-tritanopia@6.0.9) (2024-11-07)
**Note:** Version bump only for package @blockly/theme-tritanopia
diff --git a/plugins/theme-tritanopia/package-lock.json b/plugins/theme-tritanopia/package-lock.json
index e5dde935da..d22bea9cb1 100644
--- a/plugins/theme-tritanopia/package-lock.json
+++ b/plugins/theme-tritanopia/package-lock.json
@@ -1,15 +1,15 @@
{
"name": "@blockly/theme-tritanopia",
- "version": "6.0.9",
+ "version": "6.0.10",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/theme-tritanopia",
- "version": "6.0.9",
+ "version": "6.0.10",
"license": "Apache-2.0",
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"engines": {
"node": ">=8.17.0"
diff --git a/plugins/theme-tritanopia/package.json b/plugins/theme-tritanopia/package.json
index 70d1630294..965b77dc5d 100644
--- a/plugins/theme-tritanopia/package.json
+++ b/plugins/theme-tritanopia/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/theme-tritanopia",
- "version": "6.0.9",
+ "version": "6.0.10",
"description": "A Blockly theme for people that have tritanopia.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -40,7 +40,7 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6"
+ "@blockly/dev-scripts": "^4.0.7"
},
"peerDependencies": {
"blockly": "^11.0.0"
diff --git a/plugins/toolbox-search/CHANGELOG.md b/plugins/toolbox-search/CHANGELOG.md
index 20df03c229..eab82421bf 100644
--- a/plugins/toolbox-search/CHANGELOG.md
+++ b/plugins/toolbox-search/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [2.0.14](https://github.com/google/blockly-samples/compare/@blockly/toolbox-search@2.0.13...@blockly/toolbox-search@2.0.14) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/toolbox-search
+
+
+
+
+
+## [2.0.13](https://github.com/google/blockly-samples/compare/@blockly/toolbox-search@2.0.12...@blockly/toolbox-search@2.0.13) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/toolbox-search
+
+
+
+
+
+## [2.0.12](https://github.com/google/blockly-samples/compare/@blockly/toolbox-search@2.0.11...@blockly/toolbox-search@2.0.12) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/toolbox-search
+
+
+
+
+
## [2.0.11](https://github.com/google/blockly-samples/compare/@blockly/toolbox-search@2.0.10...@blockly/toolbox-search@2.0.11) (2024-11-07)
**Note:** Version bump only for package @blockly/toolbox-search
diff --git a/plugins/toolbox-search/package-lock.json b/plugins/toolbox-search/package-lock.json
index c6776174aa..145c69b2ac 100644
--- a/plugins/toolbox-search/package-lock.json
+++ b/plugins/toolbox-search/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/toolbox-search",
- "version": "2.0.11",
+ "version": "2.0.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/toolbox-search",
- "version": "2.0.11",
+ "version": "2.0.14",
"license": "Apache-2.0",
"devDependencies": {
"chai": "^4.3.7",
diff --git a/plugins/toolbox-search/package.json b/plugins/toolbox-search/package.json
index 795cfc1b0f..92f3716999 100644
--- a/plugins/toolbox-search/package.json
+++ b/plugins/toolbox-search/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/toolbox-search",
- "version": "2.0.11",
+ "version": "2.0.14",
"description": "A Blockly plugin that adds a toolbox category that allows searching for blocks.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -40,8 +40,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"chai": "^4.3.7",
"typescript": "^5.4.5"
},
diff --git a/plugins/typed-variable-modal/CHANGELOG.md b/plugins/typed-variable-modal/CHANGELOG.md
index 025704d33c..9cba36691e 100644
--- a/plugins/typed-variable-modal/CHANGELOG.md
+++ b/plugins/typed-variable-modal/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [8.0.14](https://github.com/google/blockly-samples/compare/@blockly/plugin-typed-variable-modal@8.0.13...@blockly/plugin-typed-variable-modal@8.0.14) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/plugin-typed-variable-modal
+
+
+
+
+
+## [8.0.13](https://github.com/google/blockly-samples/compare/@blockly/plugin-typed-variable-modal@8.0.12...@blockly/plugin-typed-variable-modal@8.0.13) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/plugin-typed-variable-modal
+
+
+
+
+
+## [8.0.12](https://github.com/google/blockly-samples/compare/@blockly/plugin-typed-variable-modal@8.0.11...@blockly/plugin-typed-variable-modal@8.0.12) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/plugin-typed-variable-modal
+
+
+
+
+
## [8.0.11](https://github.com/google/blockly-samples/compare/@blockly/plugin-typed-variable-modal@8.0.10...@blockly/plugin-typed-variable-modal@8.0.11) (2024-11-07)
**Note:** Version bump only for package @blockly/plugin-typed-variable-modal
diff --git a/plugins/typed-variable-modal/package-lock.json b/plugins/typed-variable-modal/package-lock.json
index 7c0a428a86..b27ce0145f 100644
--- a/plugins/typed-variable-modal/package-lock.json
+++ b/plugins/typed-variable-modal/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/plugin-typed-variable-modal",
- "version": "8.0.11",
+ "version": "8.0.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/plugin-typed-variable-modal",
- "version": "8.0.11",
+ "version": "8.0.14",
"license": "Apache-2.0",
"devDependencies": {
"jsdom": "^19.0.0",
diff --git a/plugins/typed-variable-modal/package.json b/plugins/typed-variable-modal/package.json
index 3bab1ba27c..18bca88d7d 100644
--- a/plugins/typed-variable-modal/package.json
+++ b/plugins/typed-variable-modal/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/plugin-typed-variable-modal",
- "version": "8.0.11",
+ "version": "8.0.14",
"description": "A Blockly plugin to create a modal for creating typed variables.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -39,8 +39,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"jsdom": "^19.0.0",
"jsdom-global": "3.0.2",
"mocha": "^10.1.0",
@@ -50,7 +50,7 @@
"blockly": "^11.0.0"
},
"dependencies": {
- "@blockly/plugin-modal": "^7.0.11"
+ "@blockly/plugin-modal": "^7.0.14"
},
"publishConfig": {
"access": "public",
diff --git a/plugins/workspace-backpack/CHANGELOG.md b/plugins/workspace-backpack/CHANGELOG.md
index 7e25b368a0..a27e14b919 100644
--- a/plugins/workspace-backpack/CHANGELOG.md
+++ b/plugins/workspace-backpack/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [6.0.14](https://github.com/google/blockly-samples/compare/@blockly/workspace-backpack@6.0.13...@blockly/workspace-backpack@6.0.14) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/workspace-backpack
+
+
+
+
+
+## [6.0.13](https://github.com/google/blockly-samples/compare/@blockly/workspace-backpack@6.0.12...@blockly/workspace-backpack@6.0.13) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/workspace-backpack
+
+
+
+
+
+## [6.0.12](https://github.com/google/blockly-samples/compare/@blockly/workspace-backpack@6.0.11...@blockly/workspace-backpack@6.0.12) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/workspace-backpack
+
+
+
+
+
## [6.0.11](https://github.com/google/blockly-samples/compare/@blockly/workspace-backpack@6.0.10...@blockly/workspace-backpack@6.0.11) (2024-11-07)
**Note:** Version bump only for package @blockly/workspace-backpack
diff --git a/plugins/workspace-backpack/package-lock.json b/plugins/workspace-backpack/package-lock.json
index a4f56a628d..13ffe72b5d 100644
--- a/plugins/workspace-backpack/package-lock.json
+++ b/plugins/workspace-backpack/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/workspace-backpack",
- "version": "6.0.11",
+ "version": "6.0.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/workspace-backpack",
- "version": "6.0.11",
+ "version": "6.0.14",
"license": "Apache-2.0",
"devDependencies": {
"typescript": "^5.4.5"
diff --git a/plugins/workspace-backpack/package.json b/plugins/workspace-backpack/package.json
index 9216a40033..474968d045 100644
--- a/plugins/workspace-backpack/package.json
+++ b/plugins/workspace-backpack/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/workspace-backpack",
- "version": "6.0.11",
+ "version": "6.0.14",
"description": "A Blockly plugin that adds Backpack support.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -40,8 +40,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"typescript": "^5.4.5"
},
"peerDependencies": {
diff --git a/plugins/workspace-minimap/CHANGELOG.md b/plugins/workspace-minimap/CHANGELOG.md
index 67f3c8b886..65acd9b28a 100644
--- a/plugins/workspace-minimap/CHANGELOG.md
+++ b/plugins/workspace-minimap/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [0.2.14](https://github.com/google/blockly-samples/compare/@blockly/workspace-minimap@0.2.13...@blockly/workspace-minimap@0.2.14) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/workspace-minimap
+
+
+
+
+
+## [0.2.13](https://github.com/google/blockly-samples/compare/@blockly/workspace-minimap@0.2.12...@blockly/workspace-minimap@0.2.13) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/workspace-minimap
+
+
+
+
+
+## [0.2.12](https://github.com/google/blockly-samples/compare/@blockly/workspace-minimap@0.2.11...@blockly/workspace-minimap@0.2.12) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/workspace-minimap
+
+
+
+
+
## [0.2.11](https://github.com/google/blockly-samples/compare/@blockly/workspace-minimap@0.2.10...@blockly/workspace-minimap@0.2.11) (2024-11-07)
**Note:** Version bump only for package @blockly/workspace-minimap
diff --git a/plugins/workspace-minimap/package-lock.json b/plugins/workspace-minimap/package-lock.json
index 5c9c59de53..f50f1003f6 100644
--- a/plugins/workspace-minimap/package-lock.json
+++ b/plugins/workspace-minimap/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/workspace-minimap",
- "version": "0.2.11",
+ "version": "0.2.14",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@blockly/workspace-minimap",
- "version": "0.2.11",
+ "version": "0.2.14",
"license": "Apache-2.0",
"devDependencies": {
"chai": "^4.2.0",
diff --git a/plugins/workspace-minimap/package.json b/plugins/workspace-minimap/package.json
index c7cd28ea46..6c00eb4d45 100644
--- a/plugins/workspace-minimap/package.json
+++ b/plugins/workspace-minimap/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/workspace-minimap",
- "version": "0.2.11",
+ "version": "0.2.14",
"description": "A Blockly plugin.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -39,8 +39,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"chai": "^4.2.0",
"typescript": "^5.4.5"
},
diff --git a/plugins/workspace-search/CHANGELOG.md b/plugins/workspace-search/CHANGELOG.md
index 831cd9fb88..cb7d6b86ee 100644
--- a/plugins/workspace-search/CHANGELOG.md
+++ b/plugins/workspace-search/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [9.1.8](https://github.com/google/blockly-samples/compare/@blockly/plugin-workspace-search@9.1.7...@blockly/plugin-workspace-search@9.1.8) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/plugin-workspace-search
+
+
+
+
+
+## [9.1.7](https://github.com/google/blockly-samples/compare/@blockly/plugin-workspace-search@9.1.6...@blockly/plugin-workspace-search@9.1.7) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/plugin-workspace-search
+
+
+
+
+
+## [9.1.6](https://github.com/google/blockly-samples/compare/@blockly/plugin-workspace-search@9.1.5...@blockly/plugin-workspace-search@9.1.6) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/plugin-workspace-search
+
+
+
+
+
## [9.1.5](https://github.com/google/blockly-samples/compare/@blockly/plugin-workspace-search@9.1.4...@blockly/plugin-workspace-search@9.1.5) (2024-11-07)
**Note:** Version bump only for package @blockly/plugin-workspace-search
diff --git a/plugins/workspace-search/package-lock.json b/plugins/workspace-search/package-lock.json
index dbe488bebb..82c30c72a2 100644
--- a/plugins/workspace-search/package-lock.json
+++ b/plugins/workspace-search/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/plugin-workspace-search",
- "version": "9.1.5",
+ "version": "9.1.8",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/plugin-workspace-search",
- "version": "9.1.5",
+ "version": "9.1.8",
"license": "Apache-2.0",
"devDependencies": {
"jsdom": "^19.0.0",
diff --git a/plugins/workspace-search/package.json b/plugins/workspace-search/package.json
index 0a44dc5479..f24519ba4e 100644
--- a/plugins/workspace-search/package.json
+++ b/plugins/workspace-search/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/plugin-workspace-search",
- "version": "9.1.5",
+ "version": "9.1.8",
"description": "A Blockly plugin that adds workspace search support.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -39,8 +39,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"jsdom": "^19.0.0",
"jsdom-global": "3.0.2",
"sinon": "^9.0.1",
diff --git a/plugins/zoom-to-fit/CHANGELOG.md b/plugins/zoom-to-fit/CHANGELOG.md
index 9f79a278ae..bb32f3d93b 100644
--- a/plugins/zoom-to-fit/CHANGELOG.md
+++ b/plugins/zoom-to-fit/CHANGELOG.md
@@ -3,6 +3,30 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [6.0.14](https://github.com/google/blockly-samples/compare/@blockly/zoom-to-fit@6.0.13...@blockly/zoom-to-fit@6.0.14) (2025-02-13)
+
+**Note:** Version bump only for package @blockly/zoom-to-fit
+
+
+
+
+
+## [6.0.13](https://github.com/google/blockly-samples/compare/@blockly/zoom-to-fit@6.0.12...@blockly/zoom-to-fit@6.0.13) (2024-12-19)
+
+**Note:** Version bump only for package @blockly/zoom-to-fit
+
+
+
+
+
+## [6.0.12](https://github.com/google/blockly-samples/compare/@blockly/zoom-to-fit@6.0.11...@blockly/zoom-to-fit@6.0.12) (2024-12-03)
+
+**Note:** Version bump only for package @blockly/zoom-to-fit
+
+
+
+
+
## [6.0.11](https://github.com/google/blockly-samples/compare/@blockly/zoom-to-fit@6.0.10...@blockly/zoom-to-fit@6.0.11) (2024-11-07)
**Note:** Version bump only for package @blockly/zoom-to-fit
diff --git a/plugins/zoom-to-fit/package-lock.json b/plugins/zoom-to-fit/package-lock.json
index 040d020fb8..b3384a47e3 100644
--- a/plugins/zoom-to-fit/package-lock.json
+++ b/plugins/zoom-to-fit/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@blockly/zoom-to-fit",
- "version": "6.0.11",
+ "version": "6.0.14",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@blockly/zoom-to-fit",
- "version": "6.0.11",
+ "version": "6.0.14",
"license": "Apache-2.0",
"devDependencies": {
"typescript": "^5.4.5"
diff --git a/plugins/zoom-to-fit/package.json b/plugins/zoom-to-fit/package.json
index 7c5aab25b3..86b7fad92f 100644
--- a/plugins/zoom-to-fit/package.json
+++ b/plugins/zoom-to-fit/package.json
@@ -1,6 +1,6 @@
{
"name": "@blockly/zoom-to-fit",
- "version": "6.0.11",
+ "version": "6.0.14",
"description": "A Blockly plugin that adds a zoom-to-fit control to the workspace.",
"scripts": {
"audit:fix": "blockly-scripts auditFix",
@@ -38,8 +38,8 @@
"src"
],
"devDependencies": {
- "@blockly/dev-scripts": "^4.0.6",
- "@blockly/dev-tools": "^8.0.11",
+ "@blockly/dev-scripts": "^4.0.7",
+ "@blockly/dev-tools": "^8.1.0",
"typescript": "^5.4.5"
},
"peerDependencies": {