Skip to content

Commit

Permalink
feat: add IIcon interface, and related interfaces (#7054)
Browse files Browse the repository at this point in the history
* feat: add IIcon interface

* feat: add ISerializable interface

* feat: add IHasBubble interface

* feat: add type guards for icon interfaces

* chore: PR comments
  • Loading branch information
BeksOmega authored May 9, 2023
1 parent cdea0ee commit 07db0c2
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 1 deletion.
3 changes: 2 additions & 1 deletion core/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import * as userAgent from './utils/useragent.js';
import * as utilsXml from './utils/xml.js';
import * as WidgetDiv from './widgetdiv.js';
import type {WorkspaceSvg} from './workspace_svg.js';
import {ISerializable} from './interfaces/i_serializable.js';

/**
* A function that is called to validate changes to the field's value before
Expand All @@ -68,7 +69,7 @@ export type FieldValidator<T = any> = (newValue: T) => T|null|undefined;
export abstract class Field<T = any> implements IASTNodeLocationSvg,
IASTNodeLocationWithBlock,
IKeyboardAccessible,
IRegistrable {
IRegistrable, ISerializable {
/**
* To overwrite the default value which is set in **Field**, directly update
* the prototype.
Expand Down
20 changes: 20 additions & 0 deletions core/interfaces/i_has_bubble.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/


export interface IHasBubble {
/** @return True if the bubble is currently open, false otherwise. */
isBubbleVisible(): boolean;

/** Sets whether the bubble is open or not. */
setBubbleVisible(visible: boolean): void;
}

/** Type guard that checks whether the given object is a IHasBubble. */
export function hasBubble(obj: any): obj is IHasBubble {
return obj.isBubbleVisible !== undefined &&
obj.setBubbleVisible !== undefined;
}
92 changes: 92 additions & 0 deletions core/interfaces/i_icon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import type {Coordinate} from '../utils/coordinate.js';
import type {Size} from '../utils/size.js';


export interface IIcon {
/**
* @return the string representing the type of the icon.
* E.g. 'comment', 'warning', etc. This string should also be used when
* registering the icon class.
*/
getType(): string;

/**
* 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;

/**
* @return 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;

/** @return The dimensions of the icon for use in rendering. */
getSize(): Size;

/** Notifies the icon that the block's colour has changed. */
applyColour(): void;

/** Notifies the icon that the block's editability has changed. */
updateEditable(): void;

/** Notifies the icon that the block's collapsed-ness has changed. */
updateCollapsed(): void;

/**
* @return 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;
}

/** Type guard that checks whether the given object is an IIcon. */
export function isIcon(obj: any): obj is IIcon {
return obj.getType !== undefined && obj.initView !== undefined &&
obj.dispose !== undefined && obj.getWeight !== undefined &&
obj.getSize !== undefined && obj.applyColour !== undefined &&
obj.updateEditable !== undefined && obj.updateCollapsed !== undefined &&
obj.isShownWhenCollapsed !== undefined &&
obj.setOffsetInBlock !== undefined &&
obj.onLocationChange !== undefined && obj.onClick !== undefined;
}
29 changes: 29 additions & 0 deletions core/interfaces/i_serializable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/


export interface ISerializable {
/**
* @param doFullSerialization If true, this signals that any backing data
* structures used by this ISerializable should also be serialized. This
* is used for copy-paste.
* @return a JSON serializable value that records the icon's state.
*/
saveState(doFullSerialization: boolean): any;

/**
* Takes in a JSON serializable value and sets the ISerializable's state
* based on that.
*
* @param state The state to apply to the ISerializable.
*/
loadState(state: any): void;
}

/** Type guard that checks whether the given object is a ISerializable. */
export function isSerializable(obj: any): obj is ISerializable {
return obj.saveState !== undefined && obj.loadState !== undefined;
}

0 comments on commit 07db0c2

Please sign in to comment.