fix: Fix positioning of pasted blocks and comments in RTL. (#9302)

* fix: Fix positioning of pasted blocks in RTL.

* fix: Clean up after temporarily making the workspace RTL.

* fix: Remove .only.

* fix: Fix positioning of pasted comments in RTL.

* fix: Fix positioning of text preview on collapsed comments in RTL.
This commit is contained in:
Aaron Dodson
2025-08-19 08:32:31 -07:00
parent 29d5b43cd3
commit 10b1d1e848
4 changed files with 59 additions and 2 deletions

View File

@@ -83,6 +83,9 @@ export function moveBlockToNotConflict(
block: BlockSvg, block: BlockSvg,
originalPosition: Coordinate, originalPosition: Coordinate,
) { ) {
if (block.workspace.RTL) {
originalPosition.x = block.workspace.getWidth() - originalPosition.x;
}
const workspace = block.workspace; const workspace = block.workspace;
const snapRadius = config.snapRadius; const snapRadius = config.snapRadius;
const bumpOffset = Coordinate.difference( const bumpOffset = Coordinate.difference(

View File

@@ -368,7 +368,10 @@ export class CommentView implements IRenderedElement {
const textPreviewWidth = const textPreviewWidth =
size.width - foldoutSize.getWidth() - deleteSize.getWidth(); size.width - foldoutSize.getWidth() - deleteSize.getWidth();
this.textPreview.setAttribute('x', `${foldoutSize.getWidth()}`); this.textPreview.setAttribute(
'x',
`${(this.workspace.RTL ? -1 : 1) * foldoutSize.getWidth()}`,
);
this.textPreview.setAttribute( this.textPreview.setAttribute(
'y', 'y',
`${textPreviewMargin + textPreviewSize.height / 2}`, `${textPreviewMargin + textPreviewSize.height / 2}`,

View File

@@ -68,7 +68,7 @@ export function saveWorkspaceComment(
if (!skipId) elem.setAttribute('id', comment.id); if (!skipId) elem.setAttribute('id', comment.id);
const workspace = comment.workspace; const workspace = comment.workspace;
const loc = comment.getRelativeToSurfaceXY(); const loc = comment.getRelativeToSurfaceXY().clone();
loc.x = workspace.RTL ? workspace.getWidth() - loc.x : loc.x; loc.x = workspace.RTL ? workspace.getWidth() - loc.x : loc.x;
elem.setAttribute('x', `${loc.x}`); elem.setAttribute('x', `${loc.x}`);
elem.setAttribute('y', `${loc.y}`); elem.setAttribute('y', `${loc.y}`);

View File

@@ -157,6 +157,34 @@ suite('Clipboard', function () {
); );
}); });
test('pasted blocks are bumped to not overlap in RTL', function () {
this.workspace.dispose();
this.workspace = Blockly.inject('blocklyDiv', {rtl: true});
const block = Blockly.serialization.blocks.append(
{
'type': 'controls_if',
'x': 38,
'y': 13,
},
this.workspace,
);
const data = block.toCopyData();
const newBlock = Blockly.clipboard.paste(data, this.workspace);
const oldBlockXY = block.getRelativeToSurfaceXY();
assert.deepEqual(
newBlock.getRelativeToSurfaceXY(),
new Blockly.utils.Coordinate(
oldBlockXY.x - Blockly.config.snapRadius,
oldBlockXY.y + Blockly.config.snapRadius * 2,
),
);
// Restore an LTR workspace.
this.workspace.dispose();
this.workspace = Blockly.inject('blocklyDiv');
});
test('pasted blocks are bumped to be outside the connection snap radius', function () { test('pasted blocks are bumped to be outside the connection snap radius', function () {
Blockly.serialization.workspaces.load( Blockly.serialization.workspaces.load(
{ {
@@ -208,5 +236,28 @@ suite('Clipboard', function () {
new Blockly.utils.Coordinate(40, 40), new Blockly.utils.Coordinate(40, 40),
); );
}); });
test('pasted comments are bumped to not overlap in RTL', function () {
this.workspace.dispose();
this.workspace = Blockly.inject('blocklyDiv', {rtl: true});
Blockly.Xml.domToWorkspace(
Blockly.utils.xml.textToDom(
'<xml><comment id="test" x=10 y=10/></xml>',
),
this.workspace,
);
const comment = this.workspace.getTopComments(false)[0];
const data = comment.toCopyData();
const newComment = Blockly.clipboard.paste(data, this.workspace);
const oldCommentXY = comment.getRelativeToSurfaceXY();
assert.deepEqual(
newComment.getRelativeToSurfaceXY(),
new Blockly.utils.Coordinate(oldCommentXY.x - 30, oldCommentXY.y + 30),
);
// Restore an LTR workspace.
this.workspace.dispose();
this.workspace = Blockly.inject('blocklyDiv');
});
}); });
}); });