mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
276 lines
9.8 KiB
JavaScript
276 lines
9.8 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2020 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
/**
|
|
* @fileoverview Registers default keyboard shortcuts.
|
|
* @author aschmiedt@google.com (Abby Schmiedt)
|
|
*/
|
|
'use strict';
|
|
|
|
/**
|
|
* @name Blockly.ShortcutItems
|
|
* @namespace
|
|
*/
|
|
goog.provide('Blockly.ShortcutItems');
|
|
|
|
goog.require('Blockly.Gesture');
|
|
goog.require('Blockly.ShortcutRegistry');
|
|
goog.require('Blockly.utils.KeyCodes');
|
|
|
|
goog.requireType('Blockly.BlockSvg');
|
|
goog.requireType('Blockly.ICopyable');
|
|
|
|
|
|
/**
|
|
* Object holding the names of the default shortcut items.
|
|
* @enum {string}
|
|
*/
|
|
Blockly.ShortcutItems.names = {
|
|
ESCAPE: 'escape',
|
|
DELETE: 'delete',
|
|
COPY: 'copy',
|
|
CUT: 'cut',
|
|
PASTE: 'paste',
|
|
UNDO: 'undo',
|
|
REDO: 'redo'
|
|
};
|
|
|
|
/** Keyboard shortcut to hide chaff on escape. */
|
|
Blockly.ShortcutItems.registerEscape = function() {
|
|
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
|
|
var escapeAction = {
|
|
name: Blockly.ShortcutItems.names.ESCAPE,
|
|
preconditionFn: function(workspace) {
|
|
return !workspace.options.readOnly;
|
|
},
|
|
callback: function() {
|
|
Blockly.hideChaff();
|
|
return true;
|
|
}
|
|
};
|
|
Blockly.ShortcutRegistry.registry.register(escapeAction);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(
|
|
Blockly.utils.KeyCodes.ESC, escapeAction.name);
|
|
};
|
|
|
|
/** Keyboard shortcut to delete a block on delete or backspace */
|
|
Blockly.ShortcutItems.registerDelete = function() {
|
|
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
|
|
var deleteShortcut = {
|
|
name: Blockly.ShortcutItems.names.DELETE,
|
|
preconditionFn: function(workspace) {
|
|
return !workspace.options.readOnly &&
|
|
Blockly.selected &&
|
|
Blockly.selected.isDeletable();
|
|
},
|
|
callback: function(workspace, e) {
|
|
// Delete or backspace.
|
|
// Stop the browser from going back to the previous page.
|
|
// Do this first to prevent an error in the delete code from resulting in
|
|
// data loss.
|
|
e.preventDefault();
|
|
// Don't delete while dragging. Jeez.
|
|
if (Blockly.Gesture.inProgress()) {
|
|
return false;
|
|
}
|
|
Blockly.deleteBlock(/** @type {!Blockly.BlockSvg} */ (Blockly.selected));
|
|
return true;
|
|
}
|
|
};
|
|
Blockly.ShortcutRegistry.registry.register(deleteShortcut);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(
|
|
Blockly.utils.KeyCodes.DELETE, deleteShortcut.name);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(
|
|
Blockly.utils.KeyCodes.BACKSPACE, deleteShortcut.name);
|
|
};
|
|
|
|
/** Keyboard shortcut to copy a block on ctrl+c, cmd+c, or alt+c. */
|
|
Blockly.ShortcutItems.registerCopy = function() {
|
|
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
|
|
var copyShortcut = {
|
|
name: Blockly.ShortcutItems.names.COPY,
|
|
preconditionFn: function(workspace) {
|
|
return !workspace.options.readOnly &&
|
|
!Blockly.Gesture.inProgress() &&
|
|
Blockly.selected &&
|
|
Blockly.selected.isDeletable() &&
|
|
Blockly.selected.isMovable();
|
|
},
|
|
callback: function(workspace, e) {
|
|
// Prevent the default copy behavior, which may beep or otherwise indicate
|
|
// an error due to the lack of a selection.
|
|
e.preventDefault();
|
|
Blockly.hideChaff();
|
|
Blockly.copy(/** @type {!Blockly.ICopyable} */ (Blockly.selected));
|
|
return true;
|
|
}
|
|
};
|
|
Blockly.ShortcutRegistry.registry.register(copyShortcut);
|
|
|
|
var ctrlC = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.C, [Blockly.utils.KeyCodes.CTRL]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlC, copyShortcut.name);
|
|
|
|
var altC = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.C, [Blockly.utils.KeyCodes.ALT]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(altC, copyShortcut.name);
|
|
|
|
var metaC = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.C, [Blockly.utils.KeyCodes.META]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(metaC, copyShortcut.name);
|
|
};
|
|
|
|
/** Keyboard shortcut to copy and delete a block on ctrl+x, cmd+x, or alt+x. */
|
|
Blockly.ShortcutItems.registerCut = function() {
|
|
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
|
|
var cutShortcut = {
|
|
name: Blockly.ShortcutItems.names.CUT,
|
|
preconditionFn: function(workspace) {
|
|
return !workspace.options.readOnly &&
|
|
!Blockly.Gesture.inProgress() &&
|
|
Blockly.selected &&
|
|
Blockly.selected.isDeletable() &&
|
|
Blockly.selected.isMovable() &&
|
|
!Blockly.selected.workspace.isFlyout;
|
|
},
|
|
callback: function() {
|
|
Blockly.copy(/** @type {!Blockly.ICopyable} */ (Blockly.selected));
|
|
Blockly.deleteBlock(/** @type {!Blockly.BlockSvg} */ (Blockly.selected));
|
|
return true;
|
|
}
|
|
};
|
|
|
|
Blockly.ShortcutRegistry.registry.register(cutShortcut);
|
|
|
|
var ctrlX = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.X, [Blockly.utils.KeyCodes.CTRL]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlX, cutShortcut.name);
|
|
|
|
var altX = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.X, [Blockly.utils.KeyCodes.ALT]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(altX, cutShortcut.name);
|
|
|
|
var metaX = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.X, [Blockly.utils.KeyCodes.META]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(metaX, cutShortcut.name);
|
|
};
|
|
|
|
/** Keyboard shortcut to paste a block on ctrl+v, cmd+v, or alt+v. */
|
|
Blockly.ShortcutItems.registerPaste = function() {
|
|
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
|
|
var pasteShortcut = {
|
|
name: Blockly.ShortcutItems.names.PASTE,
|
|
preconditionFn: function(workspace) {
|
|
return !workspace.options.readOnly && !Blockly.Gesture.inProgress();
|
|
},
|
|
callback: function() {
|
|
return Blockly.paste();
|
|
}
|
|
};
|
|
|
|
Blockly.ShortcutRegistry.registry.register(pasteShortcut);
|
|
|
|
var ctrlV = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.V, [Blockly.utils.KeyCodes.CTRL]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlV, pasteShortcut.name);
|
|
|
|
var altV = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.V, [Blockly.utils.KeyCodes.ALT]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(altV, pasteShortcut.name);
|
|
|
|
var metaV = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.V, [Blockly.utils.KeyCodes.META]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(metaV, pasteShortcut.name);
|
|
};
|
|
|
|
/** Keyboard shortcut to undo the previous action on ctrl+z, cmd+z, or alt+z. */
|
|
Blockly.ShortcutItems.registerUndo = function() {
|
|
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
|
|
var undoShortcut = {
|
|
name: Blockly.ShortcutItems.names.UNDO,
|
|
preconditionFn: function(workspace) {
|
|
return !workspace.options.readOnly &&
|
|
!Blockly.Gesture.inProgress();
|
|
},
|
|
callback: function(workspace) {
|
|
// 'z' for undo 'Z' is for redo.
|
|
Blockly.hideChaff();
|
|
workspace.undo(false);
|
|
return true;
|
|
}
|
|
};
|
|
Blockly.ShortcutRegistry.registry.register(undoShortcut);
|
|
|
|
var ctrlZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.Z, [Blockly.utils.KeyCodes.CTRL]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlZ, undoShortcut.name);
|
|
|
|
var altZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.Z, [Blockly.utils.KeyCodes.ALT]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(altZ, undoShortcut.name);
|
|
|
|
var metaZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.Z, [Blockly.utils.KeyCodes.META]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(metaZ, undoShortcut.name);
|
|
};
|
|
|
|
/** Keyboard shortcut to redo the previous action on ctrl+shift+z, cmd+shift+z, or alt+shift+z. */
|
|
Blockly.ShortcutItems.registerRedo = function() {
|
|
/** @type {!Blockly.ShortcutRegistry.KeyboardShortcut} */
|
|
var redoShortcut = {
|
|
name: Blockly.ShortcutItems.names.REDO,
|
|
preconditionFn: function(workspace) {
|
|
return !Blockly.Gesture.inProgress() && !workspace.options.readOnly;
|
|
},
|
|
callback: function(workspace) {
|
|
// 'z' for undo 'Z' is for redo.
|
|
Blockly.hideChaff();
|
|
workspace.undo(true);
|
|
return true;
|
|
}
|
|
};
|
|
Blockly.ShortcutRegistry.registry.register(redoShortcut);
|
|
|
|
var ctrlShiftZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.Z,
|
|
[Blockly.utils.KeyCodes.SHIFT, Blockly.utils.KeyCodes.CTRL]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(
|
|
ctrlShiftZ, redoShortcut.name);
|
|
|
|
var altShiftZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.Z,
|
|
[Blockly.utils.KeyCodes.SHIFT, Blockly.utils.KeyCodes.ALT]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(altShiftZ, redoShortcut.name);
|
|
|
|
var metaShiftZ = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.Z,
|
|
[Blockly.utils.KeyCodes.SHIFT, Blockly.utils.KeyCodes.META]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(
|
|
metaShiftZ, redoShortcut.name);
|
|
|
|
// Ctrl-y is redo in Windows. Command-y is never valid on Macs.
|
|
var ctrlY = Blockly.ShortcutRegistry.registry.createSerializedKey(
|
|
Blockly.utils.KeyCodes.Y, [Blockly.utils.KeyCodes.CTRL]);
|
|
Blockly.ShortcutRegistry.registry.addKeyMapping(ctrlY, redoShortcut.name);
|
|
};
|
|
|
|
/**
|
|
* Registers all default keyboard shortcut item. This should be called once per instance of
|
|
* KeyboardShortcutRegistry.
|
|
* @package
|
|
*/
|
|
Blockly.ShortcutItems.registerDefaultShortcuts = function() {
|
|
Blockly.ShortcutItems.registerEscape();
|
|
Blockly.ShortcutItems.registerDelete();
|
|
Blockly.ShortcutItems.registerCopy();
|
|
Blockly.ShortcutItems.registerCut();
|
|
Blockly.ShortcutItems.registerPaste();
|
|
Blockly.ShortcutItems.registerUndo();
|
|
Blockly.ShortcutItems.registerRedo();
|
|
};
|
|
|
|
Blockly.ShortcutItems.registerDefaultShortcuts();
|