From 961254663d1a0347e664638c077af54d3fbc6002 Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Wed, 28 Jul 2021 11:57:24 -0700 Subject: [PATCH 1/5] Move clipboard functions to a separate namespace --- core/blockly.js | 50 ++---------- core/clipboard.js | 106 ++++++++++++++++++++++++++ core/contextmenu_items.js | 4 +- core/shortcut_items.js | 7 +- tests/deps.js | 7 +- tests/mocha/contextmenu_items_test.js | 10 +-- tests/mocha/keydown_test.js | 2 +- 7 files changed, 129 insertions(+), 57 deletions(-) create mode 100644 core/clipboard.js diff --git a/core/blockly.js b/core/blockly.js index 94f485c99..808c035b0 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -17,6 +17,7 @@ goog.provide('Blockly'); goog.require('Blockly.browserEvents'); +goog.require('Blockly.clipboard'); goog.require('Blockly.ComponentManager'); goog.require('Blockly.connectionTypes'); goog.require('Blockly.constants'); @@ -96,21 +97,21 @@ Blockly.draggingConnections = []; * @type {Element} * @private */ -Blockly.clipboardXml_ = null; +Blockly.clipboardXml_ = Blockly.clipboard.xml; /** * Source of the local clipboard. * @type {Blockly.WorkspaceSvg} * @private */ -Blockly.clipboardSource_ = null; +Blockly.clipboardSource_ = Blockly.clipboard.source; /** * Map of types to type counts for the clipboard object and descendants. * @type {Object} * @private */ -Blockly.clipboardTypeCounts_ = null; +Blockly.clipboardTypeCounts_ = Blockly.clipboard.typeCounts; /** * Cached value for whether 3D is supported. @@ -234,39 +235,14 @@ Blockly.deleteBlock = function(selected) { * @param {!Blockly.ICopyable} toCopy Block or Workspace Comment to be copied. * @package */ -Blockly.copy = function(toCopy) { - var data = toCopy.toCopyData(); - if (data) { - Blockly.clipboardXml_ = data.xml; - Blockly.clipboardSource_ = data.source; - Blockly.clipboardTypeCounts_ = data.typeCounts; - } -}; +Blockly.copy = Blockly.clipboard.copy; /** * Paste a block or workspace comment on to the main workspace. * @return {boolean} True if the paste was successful, false otherwise. * @package */ -Blockly.paste = function() { - if (!Blockly.clipboardXml_) { - return false; - } - // Pasting always pastes to the main workspace, even if the copy - // started in a flyout workspace. - var workspace = Blockly.clipboardSource_; - if (workspace.isFlyout) { - workspace = workspace.targetWorkspace; - } - if (Blockly.clipboardTypeCounts_ && - workspace.isCapacityAvailable(Blockly.clipboardTypeCounts_)) { - Blockly.Events.setGroup(true); - workspace.paste(Blockly.clipboardXml_); - Blockly.Events.setGroup(false); - return true; - } - return false; -}; +Blockly.paste = Blockly.clipboard.paste; /** * Duplicate this block and its children, or a workspace comment. @@ -274,19 +250,7 @@ Blockly.paste = function() { * copied. * @package */ -Blockly.duplicate = function(toDuplicate) { - // Save the clipboard. - var clipboardXml = Blockly.clipboardXml_; - var clipboardSource = Blockly.clipboardSource_; - - // Create a duplicate via a copy/paste operation. - Blockly.copy(toDuplicate); - toDuplicate.workspace.paste(Blockly.clipboardXml_); - - // Restore the clipboard. - Blockly.clipboardXml_ = clipboardXml; - Blockly.clipboardSource_ = clipboardSource; -}; +Blockly.duplicate = Blockly.clipboard.duplicate; /** * Cancel the native context menu, unless the focus is on an HTML input widget. diff --git a/core/clipboard.js b/core/clipboard.js new file mode 100644 index 000000000..887346a58 --- /dev/null +++ b/core/clipboard.js @@ -0,0 +1,106 @@ +/** + * @license + * Copyright 2021 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Blockly's internal clipboard for managing copy-paste. + * @author fenichel@google.com (Rachel Fenichel) + */ +'use strict'; + +goog.module('Blockly.clipboard'); +goog.module.declareLegacyNamespace(); + +const Events = goog.require('Blockly.Events'); +/* eslint-disable-next-line no-unused-vars */ +const ICopyable = goog.requireType('Blockly.ICopyable'); +/* eslint-disable-next-line no-unused-vars */ +const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg'); + + +/** + * Contents of the local clipboard. + * @type {Element} + * @private + */ +let xml = null; +exports.xml = xml; + +/** + * Source of the local clipboard. + * @type {WorkspaceSvg} + * @private + */ +let source = null; +exports.source = source; + +/** + * Map of types to type counts for the clipboard object and descendants. + * @type {Object} + * @private + */ +let typeCounts = null; +exports.typeCounts = typeCounts; + +/** + * Copy a block or workspace comment onto the local clipboard. + * @param {!ICopyable} toCopy Block or Workspace Comment to be copied. + * @package + */ +const copy = function(toCopy) { + var data = toCopy.toCopyData(); + if (data) { + xml = data.xml; + source = data.source; + typeCounts = data.typeCounts; + } +}; +exports.copy = copy; + +/** + * Paste a block or workspace comment on to the main workspace. + * @return {boolean} True if the paste was successful, false otherwise. + * @package + */ +const paste = function() { + if (!xml) { + return false; + } + // Pasting always pastes to the main workspace, even if the copy + // started in a flyout workspace. + var workspace = source; + if (workspace.isFlyout) { + workspace = workspace.targetWorkspace; + } + if (typeCounts && workspace.isCapacityAvailable(typeCounts)) { + Events.setGroup(true); + workspace.paste(xml); + Events.setGroup(false); + return true; + } + return false; +}; +exports.paste = paste; + +/** + * Duplicate this block and its children, or a workspace comment. + * @param {!ICopyable} toDuplicate Block or Workspace Comment to be + * copied. + * @package + */ +const duplicate = function(toDuplicate) { + // Save the clipboard. + const oldXml = xml; + const oldSource = source; + + // Create a duplicate via a copy/paste operation. + copy(toDuplicate); + toDuplicate.workspace.paste(xml); + + // Restore the clipboard. + xml = oldXml; + source = oldSource; +}; +exports.duplicate = duplicate; diff --git a/core/contextmenu_items.js b/core/contextmenu_items.js index dffd4a83d..e985a8e5c 100644 --- a/core/contextmenu_items.js +++ b/core/contextmenu_items.js @@ -15,7 +15,7 @@ * @namespace */ goog.provide('Blockly.ContextMenuItems'); - +goog.require('Blockly.clipboard'); /** @suppress {extraRequire} */ goog.require('Blockly.constants'); goog.require('Blockly.ContextMenuRegistry'); @@ -316,7 +316,7 @@ Blockly.ContextMenuItems.registerDuplicate = function() { }, callback: function(/** @type {!Blockly.ContextMenuRegistry.Scope} */ scope) { if (scope.block) { - Blockly.duplicate(scope.block); + Blockly.clipboard.duplicate(scope.block); } }, scopeType: Blockly.ContextMenuRegistry.ScopeType.BLOCK, diff --git a/core/shortcut_items.js b/core/shortcut_items.js index ef1cb07fc..494b64bfe 100644 --- a/core/shortcut_items.js +++ b/core/shortcut_items.js @@ -16,6 +16,7 @@ */ goog.provide('Blockly.ShortcutItems'); +goog.require('Blockly.clipboard'); goog.require('Blockly.Gesture'); goog.require('Blockly.ShortcutRegistry'); goog.require('Blockly.utils.KeyCodes'); @@ -104,7 +105,7 @@ Blockly.ShortcutItems.registerCopy = function() { // an error due to the lack of a selection. e.preventDefault(); Blockly.hideChaff(); - Blockly.copy(/** @type {!Blockly.ICopyable} */ (Blockly.selected)); + Blockly.clipboard.copy(/** @type {!Blockly.ICopyable} */ (Blockly.selected)); return true; } }; @@ -137,7 +138,7 @@ Blockly.ShortcutItems.registerCut = function() { !Blockly.selected.workspace.isFlyout; }, callback: function() { - Blockly.copy(/** @type {!Blockly.ICopyable} */ (Blockly.selected)); + Blockly.clipboard.copy(/** @type {!Blockly.ICopyable} */ (Blockly.selected)); Blockly.deleteBlock(/** @type {!Blockly.BlockSvg} */ (Blockly.selected)); return true; } @@ -167,7 +168,7 @@ Blockly.ShortcutItems.registerPaste = function() { return !workspace.options.readOnly && !Blockly.Gesture.inProgress(); }, callback: function() { - return Blockly.paste(); + return Blockly.clipboard.paste(); } }; diff --git a/tests/deps.js b/tests/deps.js index b28f86da2..44b852995 100644 --- a/tests/deps.js +++ b/tests/deps.js @@ -12,11 +12,12 @@ goog.addDependency('../../core/block_animations.js', ['Blockly.blockAnimations'] goog.addDependency('../../core/block_drag_surface.js', ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Svg', 'Blockly.utils.dom'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/block_dragger.js', ['Blockly.BlockDragger'], ['Blockly.Events', 'Blockly.Events.BlockDrag', 'Blockly.Events.BlockMove', 'Blockly.IBlockDragger', 'Blockly.InsertionMarkerManager', 'Blockly.blockAnimations', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/block_svg.js', ['Blockly.BlockSvg'], ['Blockly.ASTNode', 'Blockly.Block', 'Blockly.ContextMenu', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Events.Selected', 'Blockly.IASTNodeLocationSvg', 'Blockly.IBoundedElement', 'Blockly.ICopyable', 'Blockly.IDraggable', 'Blockly.Msg', 'Blockly.RenderedConnection', 'Blockly.TabNavigateCursor', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Xml', 'Blockly.blockAnimations', 'Blockly.blockRendering.IPathObject', 'Blockly.browserEvents', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.internalConstants', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.Svg', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent']); -goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.ComponentManager', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.FinishedLoading', 'Blockly.Events.Ui', 'Blockly.Events.UiBase', 'Blockly.Events.VarCreate', 'Blockly.Procedures', 'Blockly.ShortcutRegistry', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Variables', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.inject', 'Blockly.inputTypes', 'Blockly.internalConstants', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.colour', 'Blockly.utils.deprecation', 'Blockly.utils.toolbox']); +goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.ComponentManager', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.FinishedLoading', 'Blockly.Events.Ui', 'Blockly.Events.UiBase', 'Blockly.Events.VarCreate', 'Blockly.Procedures', 'Blockly.ShortcutRegistry', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Variables', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.clipboard', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.inject', 'Blockly.inputTypes', 'Blockly.internalConstants', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.colour', 'Blockly.utils.deprecation', 'Blockly.utils.toolbox']); goog.addDependency('../../core/blocks.js', ['Blockly.Blocks'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/browser_events.js', ['Blockly.browserEvents'], ['Blockly.Touch', 'Blockly.utils.global']); goog.addDependency('../../core/bubble.js', ['Blockly.Bubble'], ['Blockly.IBubble', 'Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.Workspace', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Size', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.userAgent']); goog.addDependency('../../core/bubble_dragger.js', ['Blockly.BubbleDragger'], ['Blockly.Bubble', 'Blockly.ComponentManager', 'Blockly.Events', 'Blockly.Events.CommentMove', 'Blockly.constants', 'Blockly.utils', 'Blockly.utils.Coordinate'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../core/clipboard.js', ['Blockly.clipboard'], ['Blockly.Events'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/comment.js', ['Blockly.Comment'], ['Blockly.Bubble', 'Blockly.Css', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.BubbleOpen', 'Blockly.Icon', 'Blockly.Warning', 'Blockly.browserEvents', 'Blockly.utils.Svg', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/component_manager.js', ['Blockly.ComponentManager'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/connection.js', ['Blockly.Connection'], ['Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.IASTNodeLocationWithBlock', 'Blockly.Xml', 'Blockly.connectionTypes', 'Blockly.constants', 'Blockly.utils.deprecation'], {'lang': 'es6', 'module': 'goog'}); @@ -25,7 +26,7 @@ goog.addDependency('../../core/connection_db.js', ['Blockly.ConnectionDB'], ['Bl goog.addDependency('../../core/connection_types.js', ['Blockly.connectionTypes'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/constants.js', ['Blockly.constants'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/contextmenu.js', ['Blockly.ContextMenu'], ['Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Menu', 'Blockly.MenuItem', 'Blockly.Msg', 'Blockly.WidgetDiv', 'Blockly.Xml', 'Blockly.browserEvents', 'Blockly.internalConstants', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.dom', 'Blockly.utils.userAgent']); -goog.addDependency('../../core/contextmenu_items.js', ['Blockly.ContextMenuItems'], ['Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.constants', 'Blockly.inputTypes'], {'lang': 'es5'}); +goog.addDependency('../../core/contextmenu_items.js', ['Blockly.ContextMenuItems'], ['Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.clipboard', 'Blockly.constants', 'Blockly.inputTypes'], {'lang': 'es5'}); goog.addDependency('../../core/contextmenu_registry.js', ['Blockly.ContextMenuRegistry'], [], {'lang': 'es5'}); goog.addDependency('../../core/css.js', ['Blockly.Css'], [], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/delete_area.js', ['Blockly.DeleteArea'], ['Blockly.BlockSvg', 'Blockly.DragTarget', 'Blockly.IDeleteArea', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); @@ -159,7 +160,7 @@ goog.addDependency('../../core/renderers/zelos/path_object.js', ['Blockly.zelos. goog.addDependency('../../core/renderers/zelos/renderer.js', ['Blockly.zelos.Renderer'], ['Blockly.InsertionMarkerManager', 'Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.connectionTypes', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider', 'Blockly.zelos.Drawer', 'Blockly.zelos.MarkerSvg', 'Blockly.zelos.PathObject', 'Blockly.zelos.RenderInfo']); goog.addDependency('../../core/requires.js', ['Blockly.requires'], ['Blockly', 'Blockly.Comment', 'Blockly.ContextMenuItems', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.FlyoutButton', 'Blockly.Generator', 'Blockly.HorizontalFlyout', 'Blockly.Mutator', 'Blockly.ShortcutItems', 'Blockly.Themes.Classic', 'Blockly.Toolbox', 'Blockly.Trashcan', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.ZoomControls', 'Blockly.geras.Renderer', 'Blockly.thrasos.Renderer', 'Blockly.zelos.Renderer']); goog.addDependency('../../core/scrollbar.js', ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Events', 'Blockly.Touch', 'Blockly.browserEvents', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Svg', 'Blockly.utils.dom']); -goog.addDependency('../../core/shortcut_items.js', ['Blockly.ShortcutItems'], ['Blockly.Gesture', 'Blockly.ShortcutRegistry', 'Blockly.utils.KeyCodes']); +goog.addDependency('../../core/shortcut_items.js', ['Blockly.ShortcutItems'], ['Blockly.Gesture', 'Blockly.ShortcutRegistry', 'Blockly.clipboard', 'Blockly.utils.KeyCodes']); goog.addDependency('../../core/shortcut_registry.js', ['Blockly.ShortcutRegistry'], ['Blockly.utils.KeyCodes', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/theme.js', ['Blockly.Theme'], ['Blockly.registry', 'Blockly.utils', 'Blockly.utils.object']); goog.addDependency('../../core/theme/classic.js', ['Blockly.Themes.Classic'], ['Blockly.Theme']); diff --git a/tests/mocha/contextmenu_items_test.js b/tests/mocha/contextmenu_items_test.js index 62dd6f9ea..0d69fa77e 100644 --- a/tests/mocha/contextmenu_items_test.js +++ b/tests/mocha/contextmenu_items_test.js @@ -17,11 +17,11 @@ suite('Context Menu Items', function() { Blockly.ContextMenuItems.registerDefaultOptions(); this.registry = Blockly.ContextMenuRegistry.registry; }); - + teardown(function() { sharedTestTeardown.call(this); }); - + suite('Workspace Items', function() { setup(function() { this.scope = {workspace: this.workspace}; @@ -328,12 +328,12 @@ suite('Context Menu Items', function() { }); test('Calls duplicate', function() { - var stub = sinon.stub(Blockly, 'duplicate'); + var spy = sinon.spy(Blockly.clipboard, 'duplicate'); this.duplicateOption.callback(this.scope); - sinon.assert.calledOnce(stub); - sinon.assert.calledWith(stub, this.block); + sinon.assert.calledOnce(spy); + sinon.assert.calledWith(spy, this.block); }); test('Has correct label', function() { diff --git a/tests/mocha/keydown_test.js b/tests/mocha/keydown_test.js index aec646111..22fdbf96e 100644 --- a/tests/mocha/keydown_test.js +++ b/tests/mocha/keydown_test.js @@ -93,7 +93,7 @@ suite('Key Down', function() { suite('Copy', function() { setup(function() { setSelectedBlock(this.workspace); - this.copySpy = sinon.spy(Blockly, 'copy'); + this.copySpy = sinon.spy(Blockly.clipboard, 'copy'); this.hideChaffSpy = sinon.spy(Blockly, 'hideChaff'); }); var testCases = [ From d58a878fad99b4eedc4db2f09d6ee1820cb0c110 Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 29 Jul 2021 12:43:49 -0700 Subject: [PATCH 2/5] Switch to getter for keyboard contents. --- core/blockly.js | 34 +++++++++------------------------- core/clipboard.js | 21 ++++++++++++++------- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/core/blockly.js b/core/blockly.js index 808c035b0..ab82638fe 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -93,25 +93,12 @@ Blockly.selected = null; Blockly.draggingConnections = []; /** - * Contents of the local clipboard. - * @type {Element} - * @private + * Get the current contents of the clipboard and associated metadata. + * @return {{xml: Element, source: WorkspaceSvg, typeCounts: Object}} An object + * containing the clipboard contents and associated metadata. + * @public */ -Blockly.clipboardXml_ = Blockly.clipboard.xml; - -/** - * Source of the local clipboard. - * @type {Blockly.WorkspaceSvg} - * @private - */ -Blockly.clipboardSource_ = Blockly.clipboard.source; - -/** - * Map of types to type counts for the clipboard object and descendants. - * @type {Object} - * @private - */ -Blockly.clipboardTypeCounts_ = Blockly.clipboard.typeCounts; +Blockly.getClipboardInfo = Blockly.common.getClipboardInfo; /** * Cached value for whether 3D is supported. @@ -137,9 +124,7 @@ Blockly.svgSize = function(svg) { // When removing this function, remove svg.cachedWidth_ and svg.cachedHeight_ // from setCachedParentSvgSize. Blockly.utils.deprecation.warn( - 'Blockly.svgSize', - 'March 2021', - 'March 2022', + 'Blockly.svgSize', 'March 2021', 'March 2022', 'workspace.getCachedParentSvgSize'); svg = /** @type {?} */ (svg); return new Blockly.utils.Size(svg.cachedWidth_, svg.cachedHeight_); @@ -221,7 +206,8 @@ Blockly.deleteBlock = function(selected) { Blockly.Events.setGroup(true); Blockly.hideChaff(); if (selected.outputConnection) { - // Do not attempt to heal rows (https://github.com/google/blockly/issues/4832) + // Do not attempt to heal rows + // (https://github.com/google/blockly/issues/4832) selected.dispose(false, true); } else { selected.dispose(/* heal */ true, true); @@ -366,9 +352,7 @@ Blockly.defineBlocksWithJsonArray = function(jsonArray) { 'Block definition #' + i + ' in JSON array' + ' overwrites prior definition of "' + typename + '".'); } - Blockly.Blocks[typename] = { - init: Blockly.jsonInitFactory_(elem) - }; + Blockly.Blocks[typename] = {init: Blockly.jsonInitFactory_(elem)}; } } } diff --git a/core/clipboard.js b/core/clipboard.js index 887346a58..b93f92530 100644 --- a/core/clipboard.js +++ b/core/clipboard.js @@ -26,7 +26,6 @@ const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg'); * @private */ let xml = null; -exports.xml = xml; /** * Source of the local clipboard. @@ -34,7 +33,6 @@ exports.xml = xml; * @private */ let source = null; -exports.source = source; /** * Map of types to type counts for the clipboard object and descendants. @@ -42,12 +40,20 @@ exports.source = source; * @private */ let typeCounts = null; -exports.typeCounts = typeCounts; + +/** + * Get the current contents of the clipboard and associated metadata. + * @return {{xml: Element, source: WorkspaceSvg, typeCounts: Object}} An object + * containing the clipboard contents and associated metadata. + */ +const getClipboardInfo = function() { + return {xml: xml, source: source, typeCounts: typeCounts}; +}; +exports.getClipboardInfo = getClipboardInfo; /** * Copy a block or workspace comment onto the local clipboard. * @param {!ICopyable} toCopy Block or Workspace Comment to be copied. - * @package */ const copy = function(toCopy) { var data = toCopy.toCopyData(); @@ -57,12 +63,12 @@ const copy = function(toCopy) { typeCounts = data.typeCounts; } }; +/** @package */ exports.copy = copy; /** * Paste a block or workspace comment on to the main workspace. * @return {boolean} True if the paste was successful, false otherwise. - * @package */ const paste = function() { if (!xml) { @@ -82,13 +88,13 @@ const paste = function() { } return false; }; +/** @package */ exports.paste = paste; /** * Duplicate this block and its children, or a workspace comment. * @param {!ICopyable} toDuplicate Block or Workspace Comment to be - * copied. - * @package + * duplicated. */ const duplicate = function(toDuplicate) { // Save the clipboard. @@ -103,4 +109,5 @@ const duplicate = function(toDuplicate) { xml = oldXml; source = oldSource; }; +/** @package */ exports.duplicate = duplicate; From 714bb6120f9caebc04dc6707d300f784924b33b7 Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 29 Jul 2021 12:52:14 -0700 Subject: [PATCH 3/5] Fix annotations --- core/blockly.js | 6 +++--- core/clipboard.js | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/blockly.js b/core/blockly.js index ab82638fe..9fae4e84a 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -94,11 +94,11 @@ Blockly.draggingConnections = []; /** * Get the current contents of the clipboard and associated metadata. - * @return {{xml: Element, source: WorkspaceSvg, typeCounts: Object}} An object - * containing the clipboard contents and associated metadata. + * @return {{xml: ?Element, source: ?Blockly.WorkspaceSvg, typeCounts: ?Object}} + * An object containing the clipboard contents and associated metadata. * @public */ -Blockly.getClipboardInfo = Blockly.common.getClipboardInfo; +Blockly.getClipboardInfo = Blockly.clipboard.getClipboardInfo; /** * Cached value for whether 3D is supported. diff --git a/core/clipboard.js b/core/clipboard.js index b93f92530..9f7097f71 100644 --- a/core/clipboard.js +++ b/core/clipboard.js @@ -22,29 +22,29 @@ const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg'); /** * Contents of the local clipboard. - * @type {Element} + * @type {?Element} * @private */ let xml = null; /** * Source of the local clipboard. - * @type {WorkspaceSvg} + * @type {?WorkspaceSvg} * @private */ let source = null; /** * Map of types to type counts for the clipboard object and descendants. - * @type {Object} + * @type {?Object} * @private */ let typeCounts = null; /** * Get the current contents of the clipboard and associated metadata. - * @return {{xml: Element, source: WorkspaceSvg, typeCounts: Object}} An object - * containing the clipboard contents and associated metadata. + * @return {{xml: ?Element, source: ?WorkspaceSvg, typeCounts: ?Object}} An + * object containing the clipboard contents and associated metadata. */ const getClipboardInfo = function() { return {xml: xml, source: source, typeCounts: typeCounts}; From f7549f73a6c39f4136617bdfda33da496371236e Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 29 Jul 2021 17:09:47 -0700 Subject: [PATCH 4/5] Use CopyData type --- core/blockly.js | 8 ------- core/clipboard.js | 53 ++++++++++++++--------------------------------- 2 files changed, 15 insertions(+), 46 deletions(-) diff --git a/core/blockly.js b/core/blockly.js index 9fae4e84a..91c643e39 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -92,14 +92,6 @@ Blockly.selected = null; */ Blockly.draggingConnections = []; -/** - * Get the current contents of the clipboard and associated metadata. - * @return {{xml: ?Element, source: ?Blockly.WorkspaceSvg, typeCounts: ?Object}} - * An object containing the clipboard contents and associated metadata. - * @public - */ -Blockly.getClipboardInfo = Blockly.clipboard.getClipboardInfo; - /** * Cached value for whether 3D is supported. * @type {?boolean} diff --git a/core/clipboard.js b/core/clipboard.js index 9f7097f71..c6a9bb8a0 100644 --- a/core/clipboard.js +++ b/core/clipboard.js @@ -16,38 +16,20 @@ goog.module.declareLegacyNamespace(); const Events = goog.require('Blockly.Events'); /* eslint-disable-next-line no-unused-vars */ const ICopyable = goog.requireType('Blockly.ICopyable'); -/* eslint-disable-next-line no-unused-vars */ -const WorkspaceSvg = goog.requireType('Blockly.WorkspaceSvg'); - /** - * Contents of the local clipboard. - * @type {?Element} - * @private + * Metadata about the object that is currently on the clipboard. + * @type {?ICopyable.CopyData} */ -let xml = null; - -/** - * Source of the local clipboard. - * @type {?WorkspaceSvg} - * @private - */ -let source = null; - -/** - * Map of types to type counts for the clipboard object and descendants. - * @type {?Object} - * @private - */ -let typeCounts = null; +let copyData = null; /** * Get the current contents of the clipboard and associated metadata. - * @return {{xml: ?Element, source: ?WorkspaceSvg, typeCounts: ?Object}} An + * @return {?ICopyable.CopyData} An * object containing the clipboard contents and associated metadata. */ const getClipboardInfo = function() { - return {xml: xml, source: source, typeCounts: typeCounts}; + return copyData; }; exports.getClipboardInfo = getClipboardInfo; @@ -56,12 +38,7 @@ exports.getClipboardInfo = getClipboardInfo; * @param {!ICopyable} toCopy Block or Workspace Comment to be copied. */ const copy = function(toCopy) { - var data = toCopy.toCopyData(); - if (data) { - xml = data.xml; - source = data.source; - typeCounts = data.typeCounts; - } + copyData = toCopy.toCopyData(); }; /** @package */ exports.copy = copy; @@ -71,18 +48,19 @@ exports.copy = copy; * @return {boolean} True if the paste was successful, false otherwise. */ const paste = function() { - if (!xml) { + if (!copyData.xml) { return false; } // Pasting always pastes to the main workspace, even if the copy // started in a flyout workspace. - var workspace = source; + var workspace = copyData.source; if (workspace.isFlyout) { workspace = workspace.targetWorkspace; } - if (typeCounts && workspace.isCapacityAvailable(typeCounts)) { + if (copyData.typeCounts && + workspace.isCapacityAvailable(copyData.typeCounts)) { Events.setGroup(true); - workspace.paste(xml); + workspace.paste(copyData.xml); Events.setGroup(false); return true; } @@ -98,16 +76,15 @@ exports.paste = paste; */ const duplicate = function(toDuplicate) { // Save the clipboard. - const oldXml = xml; - const oldSource = source; + const oldCopyData = copyData; // Create a duplicate via a copy/paste operation. copy(toDuplicate); - toDuplicate.workspace.paste(xml); + // copy() replaced the value of copyData. + toDuplicate.workspace.paste(copyData.xml); // Restore the clipboard. - xml = oldXml; - source = oldSource; + copyData = oldCopyData; }; /** @package */ exports.duplicate = duplicate; From f72c5cea805a3f4f02670b3e43f106b26721c86d Mon Sep 17 00:00:00 2001 From: Rachel Fenichel Date: Thu, 29 Jul 2021 17:19:57 -0700 Subject: [PATCH 5/5] Remove getClipboardInfo --- core/clipboard.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/core/clipboard.js b/core/clipboard.js index c6a9bb8a0..9810836f9 100644 --- a/core/clipboard.js +++ b/core/clipboard.js @@ -23,16 +23,6 @@ const ICopyable = goog.requireType('Blockly.ICopyable'); */ let copyData = null; -/** - * Get the current contents of the clipboard and associated metadata. - * @return {?ICopyable.CopyData} An - * object containing the clipboard contents and associated metadata. - */ -const getClipboardInfo = function() { - return copyData; -}; -exports.getClipboardInfo = getClipboardInfo; - /** * Copy a block or workspace comment onto the local clipboard. * @param {!ICopyable} toCopy Block or Workspace Comment to be copied.