fix: copy paste with json system (#5423)

* fix: copy paste w/ json system

* fix: pr comments
This commit is contained in:
Beka Westberg
2021-09-03 22:19:52 +00:00
committed by GitHub
parent 8e338b7b35
commit 9ffe272d13
5 changed files with 57 additions and 66 deletions
+4 -10
View File
@@ -45,7 +45,6 @@ goog.require('Blockly.utils.object');
goog.require('Blockly.utils.Rect');
goog.require('Blockly.utils.Svg');
goog.require('Blockly.utils.userAgent');
goog.require('Blockly.Xml');
goog.requireType('Blockly.blockRendering.Debug');
goog.requireType('Blockly.Comment');
@@ -963,17 +962,12 @@ Blockly.BlockSvg.prototype.toCopyData = function() {
if (this.isInsertionMarker_) {
return null;
}
var xml = /** @type {!Element} */ (Blockly.Xml.blockToDom(this, true));
// Copy only the selected block and internal blocks.
Blockly.Xml.deleteNext(xml);
// Encode start position in XML.
var xy = this.getRelativeToSurfaceXY();
xml.setAttribute('x', this.RTL ? -xy.x : xy.x);
xml.setAttribute('y', xy.y);
return {
xml: xml,
saveInfo: /** @type {!Blockly.serialization.blocks.State} */
(Blockly.serialization.blocks.save(
this, {addCoordinates: true, addNextBlocks: false})),
source: this.workspace,
typeCounts: Blockly.utils.getBlockTypeCounts(this, true)
typeCounts: Blockly.utils.getBlockTypeCounts(this, true),
};
};
+11 -37
View File
@@ -92,24 +92,10 @@ Blockly.draggingConnections = [];
/**
* Contents of the local clipboard.
* @type {Element}
* @type {?Blockly.ICopyable.CopyData}
* @private
*/
Blockly.clipboardXml_ = null;
/**
* Source of the local clipboard.
* @type {Blockly.WorkspaceSvg}
* @private
*/
Blockly.clipboardSource_ = null;
/**
* Map of types to type counts for the clipboard object and descendants.
* @type {Object}
* @private
*/
Blockly.clipboardTypeCounts_ = null;
Blockly.clipboardData_ = null;
/**
* Cached value for whether 3D is supported.
@@ -234,12 +220,7 @@ Blockly.deleteBlock = function(selected) {
* @package
*/
Blockly.copy = function(toCopy) {
var data = toCopy.toCopyData();
if (data) {
Blockly.clipboardXml_ = data.xml;
Blockly.clipboardSource_ = data.source;
Blockly.clipboardTypeCounts_ = data.typeCounts;
}
Blockly.clipboardData_ = toCopy.toCopyData();
};
/**
@@ -248,19 +229,19 @@ Blockly.copy = function(toCopy) {
* @package
*/
Blockly.paste = function() {
if (!Blockly.clipboardXml_) {
if (!Blockly.clipboardData_) {
return false;
}
// Pasting always pastes to the main workspace, even if the copy
// started in a flyout workspace.
var workspace = Blockly.clipboardSource_;
var workspace = Blockly.clipboardData_.source;
if (workspace.isFlyout) {
workspace = workspace.targetWorkspace;
}
if (Blockly.clipboardTypeCounts_ &&
workspace.isCapacityAvailable(Blockly.clipboardTypeCounts_)) {
if (Blockly.clipboardData_.typeCounts &&
workspace.isCapacityAvailable(Blockly.clipboardData_.typeCounts)) {
Blockly.Events.setGroup(true);
workspace.paste(Blockly.clipboardXml_);
workspace.paste(Blockly.clipboardData_.saveInfo);
Blockly.Events.setGroup(false);
return true;
}
@@ -274,17 +255,10 @@ Blockly.paste = function() {
* @package
*/
Blockly.duplicate = function(toDuplicate) {
// Save the clipboard.
var clipboardXml = Blockly.clipboardXml_;
var clipboardSource = Blockly.clipboardSource_;
// Create a duplicate via a copy/paste operation.
var data = Blockly.clipboardData_;
Blockly.copy(toDuplicate);
toDuplicate.workspace.paste(Blockly.clipboardXml_);
// Restore the clipboard.
Blockly.clipboardXml_ = clipboardXml;
Blockly.clipboardSource_ = clipboardSource;
toDuplicate.workspace.paste(Blockly.clipboardData_.saveInfo);
Blockly.clipboardData_ = data;
};
/**
+2 -1
View File
@@ -26,13 +26,14 @@ Blockly.ICopyable = function() {};
/**
* Encode for copying.
* @return {?Blockly.ICopyable.CopyData} Copy metadata.
* @package
*/
Blockly.ICopyable.prototype.toCopyData;
/**
* Copy Metadata.
* @typedef {{
* xml:!Element,
* saveInfo:(!Object|!Element),
* source:Blockly.WorkspaceSvg,
* typeCounts:?Object
* }}
+5 -1
View File
@@ -643,7 +643,11 @@ Blockly.WorkspaceCommentSvg.prototype.toXmlWithXY = function(opt_noId) {
* @package
*/
Blockly.WorkspaceCommentSvg.prototype.toCopyData = function() {
return {xml: this.toXmlWithXY(), source: this.workspace, typeCounts: null};
return {
saveInfo: this.toXmlWithXY(),
source: this.workspace,
typeCounts: null
};
};
/**
+35 -17
View File
@@ -1467,40 +1467,58 @@ Blockly.WorkspaceSvg.prototype.highlightBlock = function(id, opt_state) {
};
/**
* Paste the provided block onto the workspace.
* @param {!Element|!DocumentFragment} xmlBlock XML block element or an empty
* DocumentFragment if the block was an insertion marker.
* Pastes the provided block or workspace comment onto the workspace.
* Does not check whether there is remaining capacity for the object, that
* should be done before calling this method.
* @param {!Object|!Element|!DocumentFragment} state The representation of the
* thing to paste.
*/
Blockly.WorkspaceSvg.prototype.paste = function(xmlBlock) {
if (!this.rendered || !xmlBlock.tagName || xmlBlock.getElementsByTagName('block').length >=
this.remainingCapacity()) {
Blockly.WorkspaceSvg.prototype.paste = function(state) {
if (!this.rendered || !state['type'] && !state.tagName) {
return;
}
// The check above for tagName rules out the possibility of this being a DocumentFragment.
xmlBlock = /** @type {!Element} */ (xmlBlock);
if (this.currentGesture_) {
this.currentGesture_.cancel(); // Dragging while pasting? No.
}
if (xmlBlock.tagName.toLowerCase() == 'comment') {
this.pasteWorkspaceComment_(xmlBlock);
// Checks if this is JSON. JSON has a type property, while elements don't.
if (state['type']) {
this.pasteBlock_(
null, /** @type {!Blockly.serialization.blocks.State} */ (state));
} else {
this.pasteBlock_(xmlBlock);
var xmlBlock = /** @type {!Element} */ (state);
if (xmlBlock.tagName.toLowerCase() == 'comment') {
this.pasteWorkspaceComment_(xmlBlock);
} else {
this.pasteBlock_(xmlBlock, null);
}
}
};
/**
* Paste the provided block onto the workspace.
* @param {!Element} xmlBlock XML block element.
* @param {?Element} xmlBlock XML block element.
* @param {?Blockly.serialization.blocks.State} jsonBlock JSON block
* representation.
* @private
*/
Blockly.WorkspaceSvg.prototype.pasteBlock_ = function(xmlBlock) {
Blockly.WorkspaceSvg.prototype.pasteBlock_ = function(xmlBlock, jsonBlock) {
Blockly.Events.disable();
try {
var block = Blockly.Xml.domToBlock(xmlBlock, this);
var block;
var blockX;
var blockY;
if (xmlBlock) {
block = Blockly.Xml.domToBlock(xmlBlock, this);
blockX = parseInt(xmlBlock.getAttribute('x'), 10);
blockY = parseInt(xmlBlock.getAttribute('y'), 10);
} else if (jsonBlock) {
block = Blockly.serialization.blocks.load(jsonBlock, this);
blockX = jsonBlock['x'] || 10;
blockY = jsonBlock['y'] || 10;
}
// Move the duplicate to original position.
var blockX = parseInt(xmlBlock.getAttribute('x'), 10);
var blockY = parseInt(xmlBlock.getAttribute('y'), 10);
if (!isNaN(blockX) && !isNaN(blockY)) {
if (this.RTL) {
blockX = -blockX;
@@ -1539,7 +1557,7 @@ Blockly.WorkspaceSvg.prototype.pasteBlock_ = function(xmlBlock) {
blockY += Blockly.SNAP_RADIUS * 2;
}
} while (collide);
block.moveBy(blockX, blockY);
block.moveTo(new Blockly.utils.Coordinate(blockX, blockY));
}
} finally {
Blockly.Events.enable();