fix: make deserialization use the new render management system (#7306)

* fix: make JSON use render queue

* fix: updating disabled for JSON system

* fix: make XML use render queue

* chore: make flyout use render queue explicitly
This commit is contained in:
Beka Westberg
2023-07-26 14:01:19 -07:00
committed by GitHub
parent 96c913ded8
commit 435e854b8e
7 changed files with 48 additions and 13 deletions

View File

@@ -651,7 +651,7 @@ export class Connection implements IASTNodeLocationWithBlock {
}
if (shadowDom) {
blockShadow = Xml.domToBlock(shadowDom, parentBlock.workspace);
blockShadow = Xml.domToBlockInternal(shadowDom, parentBlock.workspace);
if (attemptToConnect) {
if (this.type === ConnectionType.INPUT_VALUE) {
if (!blockShadow.outputConnection) {

View File

@@ -235,7 +235,7 @@ export function callbackFactory(block: Block, xml: Element): () => void {
eventUtils.disable();
let newBlock;
try {
newBlock = Xml.domToBlock(xml, block.workspace!) as BlockSvg;
newBlock = Xml.domToBlockInternal(xml, block.workspace!) as BlockSvg;
// Move the new block next to the old block.
const xy = block.getRelativeToSurfaceXY();
if (block.RTL) {

View File

@@ -36,6 +36,7 @@ import * as Variables from './variables.js';
import {WorkspaceSvg} from './workspace_svg.js';
import * as utilsXml from './utils/xml.js';
import * as Xml from './xml.js';
import * as renderManagement from './render_management.js';
enum FlyoutItemType {
BLOCK = 'block',
@@ -626,6 +627,8 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
const parsedContent = toolbox.convertFlyoutDefToJsonArray(flyoutDef);
const flyoutInfo = this.createFlyoutInfo(parsedContent);
renderManagement.triggerQueuedRenders();
this.layout_(flyoutInfo.contents, flyoutInfo.gaps);
if (this.horizontalLayout) {
@@ -770,7 +773,7 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
) as Element;
block = this.getRecycledBlock(xml.getAttribute('type')!);
if (!block) {
block = Xml.domToBlock(xml, this.workspace_);
block = Xml.domToBlockInternal(xml, this.workspace_);
}
} else {
block = this.getRecycledBlock(blockInfo['type']!);
@@ -779,7 +782,10 @@ export abstract class Flyout extends DeleteArea implements IFlyout {
blockInfo['enabled'] =
blockInfo['disabled'] !== 'true' && blockInfo['disabled'] !== true;
}
block = blocks.append(blockInfo as blocks.State, this.workspace_);
block = blocks.appendInternal(
blockInfo as blocks.State,
this.workspace_
);
}
}

View File

@@ -18,6 +18,7 @@ import * as registry from '../registry.js';
import * as utilsXml from '../utils/xml.js';
import type {Workspace} from '../workspace.js';
import * as Xml from '../xml.js';
import * as renderManagement from '../render_management.js';
import {
BadConnectionCheck,
@@ -349,7 +350,9 @@ export function append(
workspace: Workspace,
{recordUndo = false}: {recordUndo?: boolean} = {},
): Block {
return appendInternal(state, workspace, {recordUndo});
const block = appendInternal(state, workspace, {recordUndo});
if (workspace.rendered) renderManagement.triggerQueuedRenders();
return block;
}
/**
@@ -701,7 +704,9 @@ function initBlock(block: Block, rendered: boolean) {
blockSvg.setConnectionTracking(false);
blockSvg.initSvg();
blockSvg.render(false);
blockSvg.queueRender();
blockSvg.updateDisabled();
// fixes #6076 JSO deserialization doesn't
// set .iconXY_ property so here it will be set
for (const icon of blockSvg.getIcons()) {

View File

@@ -1349,7 +1349,7 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
let blockX = 0;
let blockY = 0;
if (xmlBlock) {
block = Xml.domToBlock(xmlBlock, this) as BlockSvg;
block = Xml.domToBlockInternal(xmlBlock, this) as BlockSvg;
blockX = parseInt(xmlBlock.getAttribute('x') ?? '0');
if (this.RTL) {
blockX = -blockX;

View File

@@ -23,6 +23,7 @@ import type {Workspace} from './workspace.js';
import {WorkspaceComment} from './workspace_comment.js';
import {WorkspaceCommentSvg} from './workspace_comment_svg.js';
import type {WorkspaceSvg} from './workspace_svg.js';
import * as renderManagement from './render_management.js';
/**
* Encode a block tree as XML.
@@ -430,7 +431,7 @@ export function domToWorkspace(xml: Element, workspace: Workspace): string[] {
// Allow top-level shadow blocks if recordUndo is disabled since
// that means an undo is in progress. Such a block is expected
// to be moved to a nested destination in the next operation.
const block = domToBlock(xmlChildElement, workspace);
const block = domToBlockInternal(xmlChildElement, workspace);
newBlockIds.push(block.id);
const blockX = parseInt(xmlChildElement.getAttribute('x') ?? '10', 10);
const blockY = parseInt(xmlChildElement.getAttribute('y') ?? '10', 10);
@@ -467,12 +468,13 @@ export function domToWorkspace(xml: Element, workspace: Workspace): string[] {
}
} finally {
eventUtils.setGroup(existingGroup);
if ((workspace as WorkspaceSvg).setResizesEnabled) {
(workspace as WorkspaceSvg).setResizesEnabled(true);
}
if (workspace.rendered) renderManagement.triggerQueuedRenders();
dom.stopTextWidthCache();
}
// Re-enable workspace resizing.
if ((workspace as WorkspaceSvg).setResizesEnabled) {
(workspace as WorkspaceSvg).setResizesEnabled(true);
}
eventUtils.fire(new (eventUtils.get(eventUtils.FINISHED_LOADING))(workspace));
return newBlockIds;
}
@@ -545,6 +547,27 @@ export function appendDomToWorkspace(
* @returns The root block created.
*/
export function domToBlock(xmlBlock: Element, workspace: Workspace): Block {
const block = domToBlockInternal(xmlBlock, workspace);
if (workspace.rendered) renderManagement.triggerQueuedRenders();
return block;
}
/**
* Decode an XML block tag and create a block (and possibly sub blocks) on the
* workspace.
*
* This is defined internally so that it doesn't trigger an immediate render,
* which we do want to happen for external calls.
*
* @param xmlBlock XML block element.
* @param workspace The workspace.
* @returns The root block created.
* @internal
*/
export function domToBlockInternal(
xmlBlock: Element,
workspace: Workspace
): Block {
// Create top-level block.
eventUtils.disable();
const variablesBeforeCreation = workspace.getAllVariables();
@@ -561,7 +584,7 @@ export function domToBlock(xmlBlock: Element, workspace: Workspace): Block {
(blocks[i] as BlockSvg).initSvg();
}
for (let i = blocks.length - 1; i >= 0; i--) {
(blocks[i] as BlockSvg).render(false);
(blocks[i] as BlockSvg).queueRender();
}
// Populating the connection database may be deferred until after the
// blocks have rendered.

View File

@@ -27,7 +27,7 @@ import {
suite('Flyout', function () {
setup(function () {
sharedTestSetup.call(this);
this.clock = sharedTestSetup.call(this, {fireEventsNow: false}).clock;
Blockly.defineBlocksWithJsonArray([
{
'type': 'basic_block',
@@ -48,6 +48,7 @@ suite('Flyout', function () {
});
teardown(function () {
this.clock.runAll();
sharedTestTeardown.call(this);
});