mirror of
https://github.com/google/blockly.git
synced 2026-01-08 17:40:09 +01:00
* refactor(interfaces): Use typeof ... === 'function' to test for methods
Testing for
'name' in object
or
obj.name !== undefined
only checks for the existence of the property (and in the latter
case that the property is not set to undefined). That's fine if
the interface specifies a property of indeterminate type, but in
the usual case that the interface member is a method we can do
one better and check to make sure the property's value is
callable.
* refactor(interfaces): Always check obj is not null/undefined
Since most type predicates take an argument of type any but then
check for the existence of certain properties, explicitly check
that the argument is not null or undefined (or check implicitly
by calling another type predicate that does so first, which
necessitates adding a few casts because tsc infers the type of
the argument too narrowly).
* fix(interfaces): Add missing check to hasBubble type predicate
This appears to have inadvertently been omitted in PR #9004.
* fix(interfaces): Fix misplaced typeof
* fix: Fix typos in JSDocs
* fix(tests): Make Mocks conform to corresponding interfaces
Introduce a new MockFocusable, and add methods to MockIcon,
MockBubbleIcon and MockComment, so that they fulfil the
IFocusableNode, IIcon, IHasBubble and ICommentIcon interfaces
respectively.
* chore(tests): Add assertions verifying mocks conform to predicates
Add (test) runtime assertions that:
- isFocusableNode(MockFocusable) returns true
- isIcon(MockIcon) returns true
- hasBubble(MockBubbleIcon) returns true
- isCommentIcon(MockCommentIcon) returns true
(The latter is currently failing because Blockly is undefined when
isCommentIcon calls the MockCommentIcon's getType method.)
* fix(tests): Don't rely on Blockly being set in Mock methods
For some reason the global Blockly binding is not visible at the
time when isCommentIcon calls MockCommentIcon's getType method,
and presumably this problem would apply to getBubbleSize too,
so directly import the required items.
* refactor(tests): Make MockCommentIcon a MockBubbleIcon
This slightly simplifies it and makes it less likely to accidentally
stop conforming to IHasBubble.
* fix(interfaces): Fix incorrect check in isSelectable
Fix an error which caused ISelectable instances to fail
isSelectable() checks, one of the results of which is that
Blockly.common.getSelected() would generally return null.
Whoops!
117 lines
3.8 KiB
TypeScript
117 lines
3.8 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2023 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import type {IconType} from '../icons/icon_types.js';
|
|
import type {Coordinate} from '../utils/coordinate.js';
|
|
import type {Size} from '../utils/size.js';
|
|
import {IFocusableNode, isFocusableNode} from './i_focusable_node.js';
|
|
|
|
export interface IIcon extends IFocusableNode {
|
|
/**
|
|
* @returns the IconType representing the type of the icon. This value should
|
|
* also be used to register the icon via `Blockly.icons.registry.register`.
|
|
*/
|
|
getType(): IconType<IIcon>;
|
|
|
|
/**
|
|
* Creates the SVG elements for the icon that will live on the block.
|
|
*
|
|
* @param pointerdownListener An event listener that must be attached to the
|
|
* root SVG element by the implementation of `initView`. Used by Blockly's
|
|
* gesture system to properly handle clicks and drags.
|
|
*/
|
|
initView(pointerdownListener: (e: PointerEvent) => void): void;
|
|
|
|
/**
|
|
* Disposes of any elements of the icon.
|
|
*
|
|
* @remarks
|
|
*
|
|
* In particular, if this icon is currently showing a bubble, this should be
|
|
* used to hide it.
|
|
*/
|
|
dispose(): void;
|
|
|
|
/**
|
|
* @returns the "weight" of the icon, which determines the static order which
|
|
* icons should be rendered in. More positive numbers are rendered farther
|
|
* toward the end of the block.
|
|
*/
|
|
getWeight(): number;
|
|
|
|
/** @returns The dimensions of the icon for use in rendering. */
|
|
getSize(): Size;
|
|
|
|
/** Updates the icon's color when the block's color changes.. */
|
|
applyColour(): void;
|
|
|
|
/** Hides the icon when it is part of an insertion marker. */
|
|
hideForInsertionMarker(): void;
|
|
|
|
/** Updates the icon's editability when the block's editability changes. */
|
|
updateEditable(): void;
|
|
|
|
/**
|
|
* Updates the icon's collapsed-ness/view when the block's collapsed-ness
|
|
* changes.
|
|
*/
|
|
updateCollapsed(): void;
|
|
|
|
/**
|
|
* @returns Whether this icon is shown when the block is collapsed. Used
|
|
* to allow renderers to account for padding.
|
|
*/
|
|
isShownWhenCollapsed(): boolean;
|
|
|
|
/**
|
|
* Notifies the icon where it is relative to its block's top-start, in
|
|
* workspace units.
|
|
*/
|
|
setOffsetInBlock(offset: Coordinate): void;
|
|
|
|
/**
|
|
* Notifies the icon that it has changed locations.
|
|
*
|
|
* @param blockOrigin The location of this icon's block's top-start corner
|
|
* in workspace coordinates.
|
|
*/
|
|
onLocationChange(blockOrigin: Coordinate): void;
|
|
|
|
/**
|
|
* Notifies the icon that it has been clicked.
|
|
*/
|
|
onClick(): void;
|
|
|
|
/**
|
|
* Check whether the icon should be clickable while the block is in a flyout.
|
|
* If this function is not defined, the icon will be clickable in all flyouts.
|
|
*
|
|
* @param autoClosingFlyout true if the containing flyout is an auto-closing one.
|
|
* @returns Whether the icon should be clickable while the block is in a flyout.
|
|
*/
|
|
isClickableInFlyout?(autoClosingFlyout: boolean): boolean;
|
|
}
|
|
|
|
/** Type guard that checks whether the given object is an IIcon. */
|
|
export function isIcon(obj: any): obj is IIcon {
|
|
return (
|
|
isFocusableNode(obj) &&
|
|
typeof (obj as IIcon).getType === 'function' &&
|
|
typeof (obj as IIcon).initView === 'function' &&
|
|
typeof (obj as IIcon).dispose === 'function' &&
|
|
typeof (obj as IIcon).getWeight === 'function' &&
|
|
typeof (obj as IIcon).getSize === 'function' &&
|
|
typeof (obj as IIcon).applyColour === 'function' &&
|
|
typeof (obj as IIcon).hideForInsertionMarker === 'function' &&
|
|
typeof (obj as IIcon).updateEditable === 'function' &&
|
|
typeof (obj as IIcon).updateCollapsed === 'function' &&
|
|
typeof (obj as IIcon).isShownWhenCollapsed === 'function' &&
|
|
typeof (obj as IIcon).setOffsetInBlock === 'function' &&
|
|
typeof (obj as IIcon).onLocationChange === 'function' &&
|
|
typeof (obj as IIcon).onClick === 'function'
|
|
);
|
|
}
|