Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/actions/enter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

import {
Events,
Msg,

Check warning on line 9 in src/actions/enter.ts

View workflow job for this annotation

GitHub Actions / Eslint check

'Msg' is defined but never used
ShortcutRegistry,
utils as BlocklyUtils,
getFocusManager,

Check warning on line 12 in src/actions/enter.ts

View workflow job for this annotation

GitHub Actions / Eslint check

'getFocusManager' is defined but never used
BlockSvg,
FlyoutButton,
RenderedConnection,
Expand Down Expand Up @@ -146,8 +146,6 @@

workspace.setResizesEnabled(true);

getFocusManager().focusTree(workspace);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line was pointless since setCurNode started moving focus.

workspace.getCursor()?.setCurNode(newBlock);
this.mover.startMove(workspace, newBlock, insertStartPoint);

const isStartBlock =
Expand Down
5 changes: 3 additions & 2 deletions src/actions/mover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,9 @@ export class Mover {
dragger.onDragStart(info.fakePointerEvent('pointerdown'));
info.updateTotalDelta();
// In case the block is detached, ensure that it still retains focus
// (otherwise dragging will break).
getFocusManager().focusNode(block);
// (otherwise dragging will break). This is also the point a new block's
// initial insert position is scrolled into view.
workspace.getCursor()?.setCurNode(block);
block.getFocusableElement().addEventListener('blur', blurListener);

// Register a keyboard shortcut under the key combos of all existing
Expand Down
74 changes: 74 additions & 0 deletions test/webdriverio/test/scroll_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import * as Blockly from 'blockly';
import * as chai from 'chai';
import {Key} from 'webdriverio';
import {
keyDown,
keyRight,
PAUSE_TIME,
tabNavigateToWorkspace,
testFileLocations,
testSetup,
} from './test_setup.js';

suite('Scrolling into view', function () {
// Setting timeout to unlimited as these tests take longer time to run
this.timeout(0);

// Clear the workspace and load start blocks
setup(async function () {
this.browser = await testSetup(testFileLocations.BASE);
// Predictable small window size for scrolling.
this.browser.setWindowSize(800, 600);
await this.browser.pause(PAUSE_TIME);
});

test('Insert scrolls new block into view', async function () {
await tabNavigateToWorkspace(this.browser);

// Separate the two top-level blocks by moving p5_draw_1 further down.
await keyDown(this.browser, 3);
await this.browser.keys('m');
await this.browser.keys([Key.Alt, ...new Array(25).fill(Key.ArrowDown)]);
await this.browser.keys(Key.Enter);
// Scroll back up, leaving cursor on the draw block out of the viewport.
await this.browser.execute(() => {
const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg;
workspace.scrollBoundsIntoView(
(
workspace.getTopBlocks(true)[0] as Blockly.BlockSvg
).getBoundingRectangleWithoutChildren(),
);
});

// Insert and confirm the test block which should be scrolled into view.
await this.browser.keys('t');
await keyRight(this.browser);
await this.browser.keys(Key.Enter);
await this.browser.keys(Key.Enter);

// Assert new block has been scrolled into the viewport.
await this.browser.pause(PAUSE_TIME);
const inViewport = await this.browser.execute(() => {
const workspace = Blockly.getMainWorkspace() as Blockly.WorkspaceSvg;
const block = workspace.getBlocksByType(
'controls_if',
)[0] as Blockly.BlockSvg;
const blockBounds = block.getBoundingRectangleWithoutChildren();
const rawViewport = workspace.getMetricsManager().getViewMetrics(true);
const viewport = new Blockly.utils.Rect(
rawViewport.top,
rawViewport.top + rawViewport.height,
rawViewport.left,
rawViewport.left + rawViewport.width,
);
return viewport.contains(blockBounds.left, blockBounds.top);
});
chai.assert.isTrue(inViewport);
});
});
Loading