Skip to content

Commit

Permalink
Merge pull request #7789 from google/rc/v10.3.1
Browse files Browse the repository at this point in the history
release: v10.3.1
  • Loading branch information
maribethb authored Jan 17, 2024
2 parents 26ee8cf + 498fc2c commit 1ba0e55
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 17 deletions.
5 changes: 2 additions & 3 deletions core/flyout_base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ export abstract class Flyout
const parsedContent = toolbox.convertFlyoutDefToJsonArray(flyoutDef);
const flyoutInfo = this.createFlyoutInfo(parsedContent);

renderManagement.triggerQueuedRenders();
renderManagement.triggerQueuedRenders(this.workspace_);

this.layout_(flyoutInfo.contents, flyoutInfo.gaps);

Expand Down Expand Up @@ -1235,8 +1235,7 @@ export abstract class Flyout
}

// Clone the block.
// TODO(#7432): Add a saveIds parameter to `save`.
const json = blocks.save(oldBlock, {saveIds: false}) as blocks.State;
const json = blocks.save(oldBlock) as blocks.State;
// Normallly this resizes leading to weird jumps. Save it for terminateDrag.
targetWorkspace.setResizesEnabled(false);
const block = blocks.append(json, targetWorkspace) as BlockSvg;
Expand Down
41 changes: 30 additions & 11 deletions core/render_management.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

import {BlockSvg} from './block_svg.js';
import * as userAgent from './utils/useragent.js';
import type {WorkspaceSvg} from './workspace_svg.js';

/** The set of all blocks in need of rendering which don't have parents. */
const rootBlocks = new Set<BlockSvg>();

/** The set of all blocks in need of rendering. */
let dirtyBlocks = new WeakSet<BlockSvg>();
const dirtyBlocks = new WeakSet<BlockSvg>();

/**
* The promise which resolves after the current set of renders is completed. Or
Expand Down Expand Up @@ -75,12 +76,14 @@ export function finishQueuedRenders(): Promise<void> {
* cases where queueing renders breaks functionality + backwards compatibility
* (such as rendering icons).
*
* @param workspace If provided, only rerender blocks in this workspace.
*
* @internal
*/
export function triggerQueuedRenders() {
window.cancelAnimationFrame(animationRequestId);
doRenders();
if (afterRendersResolver) afterRendersResolver();
export function triggerQueuedRenders(workspace?: WorkspaceSvg) {
if (!workspace) window.cancelAnimationFrame(animationRequestId);
doRenders(workspace);
if (!workspace && afterRendersResolver) afterRendersResolver();
}

/**
Expand Down Expand Up @@ -110,10 +113,16 @@ function queueBlock(block: BlockSvg) {

/**
* Rerenders all of the blocks in the queue.
*
* @param workspace If provided, only rerender blocks in this workspace.
*/
function doRenders() {
const workspaces = new Set([...rootBlocks].map((block) => block.workspace));
const blocks = [...rootBlocks].filter(shouldRenderRootBlock);
function doRenders(workspace?: WorkspaceSvg) {
const workspaces = workspace
? new Set([workspace])
: new Set([...rootBlocks].map((block) => block.workspace));
const blocks = [...rootBlocks]
.filter(shouldRenderRootBlock)
.filter((b) => workspaces.has(b.workspace));
for (const block of blocks) {
renderBlock(block);
}
Expand All @@ -125,9 +134,19 @@ function doRenders() {
block.updateComponentLocations(blockOrigin);
}

rootBlocks.clear();
dirtyBlocks = new Set();
afterRendersPromise = null;
for (const block of blocks) {
dequeueBlock(block);
}
if (!workspace) afterRendersPromise = null;
}

/** Removes the given block and children from the render queue. */
function dequeueBlock(block: BlockSvg) {
rootBlocks.delete(block);
dirtyBlocks.delete(block);
for (const child of block.getChildren(false)) {
dequeueBlock(child);
}
}

/**
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "blockly",
"version": "10.3.0",
"version": "10.3.1",
"description": "Blockly is a library for building visual programming editors.",
"keywords": [
"blockly"
Expand Down
65 changes: 65 additions & 0 deletions tests/mocha/render_management_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,69 @@ suite('Render Management', function () {
return promise;
});
});

suite('triggering queued renders', function () {
function createMockBlock(ws) {
return {
hasRendered: false,
renderEfficiently: function () {
this.hasRendered = true;
},

// All of the APIs the render management system needs.
getParent: () => null,
getChildren: () => [],
isDisposed: () => false,
getRelativeToSurfaceXY: () => ({x: 0, y: 0}),
updateComponentLocations: () => {},
workspace: ws || createMockWorkspace(),
};
}

function createMockWorkspace() {
return {
resizeContents: () => {},
};
}

test('triggering queued renders rerenders blocks', function () {
const block = createMockBlock();
Blockly.renderManagement.queueRender(block);

Blockly.renderManagement.triggerQueuedRenders();

chai.assert.isTrue(block.hasRendered, 'Expected block to be rendered');
});

test('triggering queued renders rerenders blocks in all workspaces', function () {
const workspace1 = createMockWorkspace();
const workspace2 = createMockWorkspace();
const block1 = createMockBlock(workspace1);
const block2 = createMockBlock(workspace2);
Blockly.renderManagement.queueRender(block1);
Blockly.renderManagement.queueRender(block2);

Blockly.renderManagement.triggerQueuedRenders();

chai.assert.isTrue(block1.hasRendered, 'Expected block1 to be rendered');
chai.assert.isTrue(block2.hasRendered, 'Expected block2 to be rendered');
});

test('triggering queued renders in one workspace does not rerender blocks in another workspace', function () {
const workspace1 = createMockWorkspace();
const workspace2 = createMockWorkspace();
const block1 = createMockBlock(workspace1);
const block2 = createMockBlock(workspace2);
Blockly.renderManagement.queueRender(block1);
Blockly.renderManagement.queueRender(block2);

Blockly.renderManagement.triggerQueuedRenders(workspace1);

chai.assert.isTrue(block1.hasRendered, 'Expected block1 to be rendered');
chai.assert.isFalse(
block2.hasRendered,
'Expected block2 to not be rendered',
);
});
});
});

0 comments on commit 1ba0e55

Please sign in to comment.