mirror of
https://github.com/google/blockly.git
synced 2026-01-08 17:40:09 +01:00
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "blockly",
|
||||
"version": "10.3.0",
|
||||
"version": "10.3.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "blockly",
|
||||
"version": "10.3.0",
|
||||
"version": "10.3.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user