mirror of
https://github.com/google/blockly.git
synced 2026-01-10 02:17:09 +01:00
fix!: have disposing be true from start of dispose (#7891)
This commit is contained in:
@@ -189,7 +189,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
/**
|
||||
* Is the current block currently in the process of being disposed?
|
||||
*/
|
||||
private disposing = false;
|
||||
protected disposing = false;
|
||||
|
||||
/**
|
||||
* Has this block been fully initialized? E.g. all fields initailized.
|
||||
@@ -319,7 +319,7 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
* children of this block.
|
||||
*/
|
||||
dispose(healStack: boolean) {
|
||||
if (this.isDeadOrDying()) return;
|
||||
this.disposing = true;
|
||||
|
||||
// Dispose of this change listener before unplugging.
|
||||
// Technically not necessary due to the event firing delay.
|
||||
@@ -342,15 +342,13 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
* E.g. does not fire events, unplug the block, etc.
|
||||
*/
|
||||
protected disposeInternal() {
|
||||
if (this.isDeadOrDying()) return;
|
||||
|
||||
this.disposing = true;
|
||||
if (this.onchangeWrapper_) {
|
||||
this.workspace.removeChangeListener(this.onchangeWrapper_);
|
||||
}
|
||||
|
||||
this.workspace.removeTypedBlock(this);
|
||||
this.workspace.removeBlockById(this.id);
|
||||
this.disposing = true;
|
||||
|
||||
if (typeof this.destroy === 'function') this.destroy();
|
||||
|
||||
|
||||
@@ -776,7 +776,7 @@ export class BlockSvg
|
||||
* @param animate If true, show a disposal animation and sound.
|
||||
*/
|
||||
override dispose(healStack?: boolean, animate?: boolean) {
|
||||
if (this.isDeadOrDying()) return;
|
||||
this.disposing = true;
|
||||
|
||||
Tooltip.dispose();
|
||||
ContextMenu.hide();
|
||||
@@ -795,7 +795,7 @@ export class BlockSvg
|
||||
* E.g. does trigger UI effects, remove nodes, etc.
|
||||
*/
|
||||
override disposeInternal() {
|
||||
if (this.isDeadOrDying()) return;
|
||||
this.disposing = true;
|
||||
super.disposeInternal();
|
||||
|
||||
if (common.getSelected() === this) {
|
||||
|
||||
@@ -153,8 +153,10 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
dispose() {
|
||||
// isConnected returns true for shadows and non-shadows.
|
||||
if (this.isConnected()) {
|
||||
// Destroy the attached shadow block & its children (if it exists).
|
||||
this.setShadowStateInternal();
|
||||
if (this.isSuperior()) {
|
||||
// Destroy the attached shadow block & its children (if it exists).
|
||||
this.setShadowStateInternal();
|
||||
}
|
||||
|
||||
const targetBlock = this.targetBlock();
|
||||
if (targetBlock && !targetBlock.isDeadOrDying()) {
|
||||
@@ -600,6 +602,8 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
this.shadowDom = shadowDom;
|
||||
this.shadowState = shadowState;
|
||||
|
||||
if (this.getSourceBlock().isDeadOrDying()) return;
|
||||
|
||||
const target = this.targetBlock();
|
||||
if (!target) {
|
||||
this.respawnShadow_();
|
||||
@@ -608,7 +612,6 @@ export class Connection implements IASTNodeLocationWithBlock {
|
||||
}
|
||||
} else if (target.isShadow()) {
|
||||
target.dispose(false);
|
||||
if (this.getSourceBlock().isDeadOrDying()) return;
|
||||
this.respawnShadow_();
|
||||
if (this.targetBlock() && this.targetBlock()!.isShadow()) {
|
||||
this.serializeShadow(this.targetBlock());
|
||||
|
||||
@@ -250,13 +250,13 @@ export function blockToDom(
|
||||
if (!block.isEnabled()) {
|
||||
element.setAttribute('disabled', 'true');
|
||||
}
|
||||
if (!block.isDeletable() && !block.isShadow()) {
|
||||
if (!block.isOwnDeletable()) {
|
||||
element.setAttribute('deletable', 'false');
|
||||
}
|
||||
if (!block.isMovable() && !block.isShadow()) {
|
||||
if (!block.isOwnMovable()) {
|
||||
element.setAttribute('movable', 'false');
|
||||
}
|
||||
if (!block.isEditable()) {
|
||||
if (!block.isOwnEditable()) {
|
||||
element.setAttribute('editable', 'false');
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +67,9 @@ suite('Blocks', function () {
|
||||
|
||||
function createTestBlocks(workspace, isRow) {
|
||||
const blockType = isRow ? 'row_block' : 'stack_block';
|
||||
const blockA = workspace.newBlock(blockType);
|
||||
const blockB = workspace.newBlock(blockType);
|
||||
const blockC = workspace.newBlock(blockType);
|
||||
const blockA = workspace.newBlock(blockType, 'a');
|
||||
const blockB = workspace.newBlock(blockType, 'b');
|
||||
const blockC = workspace.newBlock(blockType, 'c');
|
||||
|
||||
if (isRow) {
|
||||
blockA.inputList[0].connection.connect(blockB.outputConnection);
|
||||
@@ -386,8 +386,14 @@ suite('Blocks', function () {
|
||||
|
||||
test('Child is shadow', function () {
|
||||
const blocks = this.blocks;
|
||||
blocks.C.setShadow(true);
|
||||
blocks.C.dispose();
|
||||
blocks.B.inputList[0].connection.setShadowState({
|
||||
'type': 'row_block',
|
||||
'id': 'c',
|
||||
});
|
||||
|
||||
blocks.B.dispose(true);
|
||||
|
||||
// Even though we're asking to heal, it will appear as if it has not
|
||||
// healed because shadows always get destroyed.
|
||||
assertDisposedNoheal(blocks);
|
||||
@@ -423,8 +429,14 @@ suite('Blocks', function () {
|
||||
|
||||
test('Child is shadow', function () {
|
||||
const blocks = this.blocks;
|
||||
blocks.C.setShadow(true);
|
||||
blocks.C.dispose();
|
||||
blocks.B.nextConnection.setShadowState({
|
||||
'type': 'stack_block',
|
||||
'id': 'c',
|
||||
});
|
||||
|
||||
blocks.B.dispose(true);
|
||||
|
||||
// Even though we're asking to heal, it will appear as if it has not
|
||||
// healed because shadows always get destroyed.
|
||||
assertDisposedNoheal(blocks);
|
||||
|
||||
Reference in New Issue
Block a user