mirror of
https://github.com/google/blockly.git
synced 2026-01-04 15:40:08 +01:00
feat!: Invalid Blocks (#7958)
* feat: Invalid Blocks * Rename the new json property from invalid to invalidReasons. * Merged isValid into isEnabled. * Minor fixes. * More minor fixes. * Reverting some stuff that didn't need to change. * Addressing PR feedback. * Update the BlockInfo interface to match State. * Make BlockChange.disabledReason private.
This commit is contained in:
114
core/block.ts
114
core/block.ts
@@ -25,7 +25,9 @@ import {ConnectionType} from './connection_type.js';
|
||||
import * as constants from './constants.js';
|
||||
import {DuplicateIconType} from './icons/exceptions.js';
|
||||
import type {Abstract} from './events/events_abstract.js';
|
||||
import type {BlockChange} from './events/events_block_change.js';
|
||||
import type {BlockMove} from './events/events_block_move.js';
|
||||
import * as deprecation from './utils/deprecation.js';
|
||||
import * as eventUtils from './events/utils.js';
|
||||
import * as Extensions from './extensions.js';
|
||||
import type {Field} from './field.js';
|
||||
@@ -166,7 +168,7 @@ export class Block implements IASTNodeLocation {
|
||||
inputList: Input[] = [];
|
||||
inputsInline?: boolean;
|
||||
icons: IIcon[] = [];
|
||||
private disabled = false;
|
||||
private disabledReasons = new Set<string>();
|
||||
tooltip: Tooltip.TipInfo = '';
|
||||
contextMenu = true;
|
||||
|
||||
@@ -1390,32 +1392,89 @@ export class Block implements IASTNodeLocation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether this block is enabled or not.
|
||||
* Get whether this block is enabled or not. A block is considered enabled
|
||||
* if there aren't any reasons why it would be disabled. A block may still
|
||||
* be disabled for other reasons even if the user attempts to manually
|
||||
* enable it, such as when the block is in an invalid location.
|
||||
*
|
||||
* @returns True if enabled.
|
||||
*/
|
||||
isEnabled(): boolean {
|
||||
return !this.disabled;
|
||||
return this.disabledReasons.size === 0;
|
||||
}
|
||||
|
||||
/** @deprecated v11 - Get whether the block is manually disabled. */
|
||||
private get disabled(): boolean {
|
||||
deprecation.warn(
|
||||
'disabled',
|
||||
'v11',
|
||||
'v12',
|
||||
'the isEnabled or hasDisabledReason methods of Block',
|
||||
);
|
||||
return this.hasDisabledReason(constants.MANUALLY_DISABLED);
|
||||
}
|
||||
|
||||
/** @deprecated v11 - Set whether the block is manually disabled. */
|
||||
private set disabled(value: boolean) {
|
||||
deprecation.warn(
|
||||
'disabled',
|
||||
'v11',
|
||||
'v12',
|
||||
'the setDisabledReason method of Block',
|
||||
);
|
||||
this.setDisabledReason(value, constants.MANUALLY_DISABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the block is enabled or not.
|
||||
* @deprecated v11 - Set whether the block is manually enabled or disabled.
|
||||
* The user can toggle whether a block is disabled from a context menu
|
||||
* option. A block may still be disabled for other reasons even if the user
|
||||
* attempts to manually enable it, such as when the block is in an invalid
|
||||
* location. This method is deprecated and setDisabledReason should be used
|
||||
* instead.
|
||||
*
|
||||
* @param enabled True if enabled.
|
||||
*/
|
||||
setEnabled(enabled: boolean) {
|
||||
if (this.isEnabled() !== enabled) {
|
||||
const oldValue = this.disabled;
|
||||
this.disabled = !enabled;
|
||||
eventUtils.fire(
|
||||
new (eventUtils.get(eventUtils.BLOCK_CHANGE))(
|
||||
this,
|
||||
'disabled',
|
||||
null,
|
||||
oldValue,
|
||||
!enabled,
|
||||
),
|
||||
);
|
||||
deprecation.warn(
|
||||
'setEnabled',
|
||||
'v11',
|
||||
'v12',
|
||||
'the setDisabledReason method of Block',
|
||||
);
|
||||
this.setDisabledReason(!enabled, constants.MANUALLY_DISABLED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or remove a reason why the block might be disabled. If a block has
|
||||
* any reasons to be disabled, then the block itself will be considered
|
||||
* disabled. A block could be disabled for multiple independent reasons
|
||||
* simultaneously, such as when the user manually disables it, or the block
|
||||
* is invalid.
|
||||
*
|
||||
* @param disabled If true, then the block should be considered disabled for
|
||||
* at least the provided reason, otherwise the block is no longer disabled
|
||||
* for that reason.
|
||||
* @param reason A language-neutral identifier for a reason why the block
|
||||
* could be disabled. Call this method again with the same identifier to
|
||||
* update whether the block is currently disabled for this reason.
|
||||
*/
|
||||
setDisabledReason(disabled: boolean, reason: string): void {
|
||||
if (this.disabledReasons.has(reason) !== disabled) {
|
||||
if (disabled) {
|
||||
this.disabledReasons.add(reason);
|
||||
} else {
|
||||
this.disabledReasons.delete(reason);
|
||||
}
|
||||
const blockChangeEvent = new (eventUtils.get(eventUtils.BLOCK_CHANGE))(
|
||||
this,
|
||||
'disabled',
|
||||
/* name= */ null,
|
||||
/* oldValue= */ !disabled,
|
||||
/* newValue= */ disabled,
|
||||
) as BlockChange;
|
||||
blockChangeEvent.setDisabledReason(reason);
|
||||
eventUtils.fire(blockChangeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1428,7 +1487,7 @@ export class Block implements IASTNodeLocation {
|
||||
getInheritedDisabled(): boolean {
|
||||
let ancestor = this.getSurroundParent();
|
||||
while (ancestor) {
|
||||
if (ancestor.disabled) {
|
||||
if (!ancestor.isEnabled()) {
|
||||
return true;
|
||||
}
|
||||
ancestor = ancestor.getSurroundParent();
|
||||
@@ -1437,6 +1496,27 @@ export class Block implements IASTNodeLocation {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the block is currently disabled for the provided reason.
|
||||
*
|
||||
* @param reason A language-neutral identifier for a reason why the block
|
||||
* could be disabled.
|
||||
* @returns Whether the block is disabled for the provided reason.
|
||||
*/
|
||||
hasDisabledReason(reason: string): boolean {
|
||||
return this.disabledReasons.has(reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a set of reasons why the block is currently disabled, if any. If the
|
||||
* block is enabled, this set will be empty.
|
||||
*
|
||||
* @returns The set of reasons why the block is disabled, if any.
|
||||
*/
|
||||
getDisabledReasons(): ReadonlySet<string> {
|
||||
return this.disabledReasons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether the block is collapsed or not.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user