mirror of
https://github.com/google/blockly.git
synced 2026-01-09 18:10:08 +01:00
* chore: add support for copying and pasting workspace comments * chore: fix build * fix: PR comments
144 lines
4.1 KiB
TypeScript
144 lines
4.1 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2024 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import {ISerializer} from '../interfaces/i_serializer.js';
|
|
import {Workspace} from '../workspace.js';
|
|
import * as priorities from './priorities.js';
|
|
import type {WorkspaceComment} from '../comments/workspace_comment.js';
|
|
import * as eventUtils from '../events/utils.js';
|
|
import {Coordinate} from '../utils/coordinate.js';
|
|
import * as serializationRegistry from './registry.js';
|
|
import {Size} from '../utils/size.js';
|
|
|
|
export interface State {
|
|
id?: string;
|
|
text?: string;
|
|
x?: number;
|
|
y?: number;
|
|
width?: number;
|
|
height?: number;
|
|
collapsed?: boolean;
|
|
editable?: boolean;
|
|
movable?: boolean;
|
|
deletable?: boolean;
|
|
}
|
|
|
|
/** Serializes the state of the given comment to JSON. */
|
|
export function save(
|
|
comment: WorkspaceComment,
|
|
{
|
|
addCoordinates = false,
|
|
saveIds = true,
|
|
}: {
|
|
addCoordinates?: boolean;
|
|
saveIds?: boolean;
|
|
} = {},
|
|
): State {
|
|
const workspace = comment.workspace;
|
|
const state: State = Object.create(null);
|
|
|
|
state.height = comment.getSize().height;
|
|
state.width = comment.getSize().width;
|
|
|
|
if (saveIds) state.id = comment.id;
|
|
if (addCoordinates) {
|
|
const loc = comment.getRelativeToSurfaceXY();
|
|
state.x = workspace.RTL ? workspace.getWidth() - loc.x : loc.x;
|
|
state.y = loc.y;
|
|
}
|
|
|
|
if (comment.getText()) state.text = comment.getText();
|
|
if (comment.isCollapsed()) state.collapsed = true;
|
|
if (!comment.isOwnEditable()) state.editable = false;
|
|
if (!comment.isOwnMovable()) state.movable = false;
|
|
if (!comment.isOwnDeletable()) state.deletable = false;
|
|
|
|
return state;
|
|
}
|
|
|
|
/** Appends the comment defined by the given state to the given workspace. */
|
|
export function append(
|
|
state: State,
|
|
workspace: Workspace,
|
|
{recordUndo = false}: {recordUndo?: boolean} = {},
|
|
): WorkspaceComment {
|
|
const prevRecordUndo = eventUtils.getRecordUndo();
|
|
eventUtils.setRecordUndo(recordUndo);
|
|
|
|
const comment = workspace.newComment(state.id);
|
|
|
|
if (state.text !== undefined) comment.setText(state.text);
|
|
if (state.x !== undefined || state.y !== undefined) {
|
|
const defaultLoc = comment.getRelativeToSurfaceXY();
|
|
let x = state.x ?? defaultLoc.x;
|
|
x = workspace.RTL ? workspace.getWidth() - x : x;
|
|
const y = state.y ?? defaultLoc.y;
|
|
comment.moveTo(new Coordinate(x, y));
|
|
}
|
|
if (state.width !== undefined || state.height) {
|
|
const defaultSize = comment.getSize();
|
|
comment.setSize(
|
|
new Size(
|
|
state.width ?? defaultSize.width,
|
|
state.height ?? defaultSize.height,
|
|
),
|
|
);
|
|
}
|
|
if (state.collapsed !== undefined) comment.setCollapsed(state.collapsed);
|
|
if (state.editable !== undefined) comment.setEditable(state.editable);
|
|
if (state.movable !== undefined) comment.setMovable(state.movable);
|
|
if (state.deletable !== undefined) comment.setDeletable(state.deletable);
|
|
|
|
eventUtils.setRecordUndo(prevRecordUndo);
|
|
|
|
return comment;
|
|
}
|
|
|
|
// Alias to disambiguate saving within the serializer.
|
|
const saveComment = save;
|
|
|
|
/** Serializer for saving and loading workspace comment state. */
|
|
export class WorkspaceCommentSerializer implements ISerializer {
|
|
priority = priorities.WORKSPACE_COMMENTS;
|
|
|
|
/**
|
|
* Returns the state of all workspace comments in the given workspace.
|
|
*/
|
|
save(workspace: Workspace): State[] | null {
|
|
const commentStates = [];
|
|
for (const comment of workspace.getTopComments()) {
|
|
const state = saveComment(comment as AnyDuringMigration, {
|
|
addCoordinates: true,
|
|
saveIds: true,
|
|
});
|
|
if (state) commentStates.push(state);
|
|
}
|
|
return commentStates.length ? commentStates : null;
|
|
}
|
|
|
|
/**
|
|
* Deserializes the comments defined by the given state into the given
|
|
* workspace.
|
|
*/
|
|
load(state: State[], workspace: Workspace) {
|
|
for (const commentState of state) {
|
|
append(commentState, workspace, {recordUndo: eventUtils.getRecordUndo()});
|
|
}
|
|
}
|
|
|
|
/** Disposes of any comments that exist on the given workspace. */
|
|
clear(workspace: Workspace) {
|
|
for (const comment of workspace.getTopComments()) {
|
|
comment.dispose();
|
|
}
|
|
}
|
|
}
|
|
|
|
serializationRegistry.register(
|
|
'workspaceComments',
|
|
new WorkspaceCommentSerializer(),
|
|
);
|