Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 22 additions & 12 deletions core/block_svg.js
Original file line number Diff line number Diff line change
Expand Up @@ -963,18 +963,28 @@ 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,
source: this.workspace,
typeCounts: Blockly.utils.getBlockTypeCounts(this, true)
};
if (this.mutationToDom && !this.saveExtraState) {
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 {
saveInfo: xml,
source: this.workspace,
typeCounts: Blockly.utils.getBlockTypeCounts(this, true)
};
} else {
return {
saveInfo: /** @type {!Blockly.serialization.blocks.State} */
(Blockly.serialization.blocks.save(
this, {addCoordinates: true, addNextBlocks: false})),
source: this.workspace,
typeCounts: Blockly.utils.getBlockTypeCounts(this, true)
};
}
};

/**
Expand Down
49 changes: 11 additions & 38 deletions core/blockly.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,9 @@ Blockly.draggingConnections = [];

/**
* Contents of the local clipboard.
* @type {Element}
* @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
* @type {?Blockly.ICopyable.CopyData}
*/
Blockly.clipboardTypeCounts_ = null;
Blockly.clipboardData_ = null;

/**
* Cached value for whether 3D is supported.
Expand Down Expand Up @@ -234,12 +219,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();
};

/**
Expand All @@ -248,19 +228,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;
}
Expand All @@ -274,17 +254,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;
};

/**
Expand Down
4 changes: 3 additions & 1 deletion core/interfaces/i_copyable.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,17 @@ 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
* }}
* @package
*/
Blockly.ICopyable.CopyData;
62 changes: 40 additions & 22 deletions core/workspace_svg.js
Original file line number Diff line number Diff line change
Expand Up @@ -1466,40 +1466,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.
* Paste the provided block or workspace comment onto the workspace.
* @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) {
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);
} else {
this.pasteBlock_(xmlBlock);
if (state['type']) {
if (this.currentGesture_) {
// Dragging while pasting? No.
this.currentGesture_.cancel();
}
this.pasteBlock_(
null, /** @type {!Blockly.serialization.blocks.State} */ (state));
} else if (state.tagName) { // Ignore document fragments.
if (this.currentGesture_) {
// Dragging while pasting? No.
this.currentGesture_.cancel();
}
var xml = /** @type {!Element} */ (state);
if (xml.tagName.toLowerCase() == 'comment') {
this.pasteWorkspaceComment_(xml);
} else {
this.pasteBlock_(xml, 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'];
blockY = jsonBlock['y'];
}

// 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;
Expand Down Expand Up @@ -1538,7 +1556,7 @@ Blockly.WorkspaceSvg.prototype.pasteBlock_ = function(xmlBlock) {
blockY += Blockly.SNAP_RADIUS * 2;
}
} while (collide);
block.moveBy(blockX, blockY);
block.moveTo({x: blockX, y: blockY});
}
} finally {
Blockly.Events.enable();
Expand Down