mirror of
https://github.com/scratchfoundation/scratch-blocks.git
synced 2025-08-28 22:10:31 -04:00
172 lines
6.2 KiB
JavaScript
172 lines
6.2 KiB
JavaScript
/**
|
|
* AccessibleBlockly
|
|
*
|
|
* Copyright 2016 Google Inc.
|
|
* https://developers.google.com/blockly/
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the 'License');
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an 'AS IS' BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @fileoverview Angular2 Service that handles the clipboard and marked spots.
|
|
* @author madeeha@google.com (Madeeha Ghori)
|
|
*/
|
|
|
|
blocklyApp.ClipboardService = ng.core
|
|
.Class({
|
|
constructor: [
|
|
blocklyApp.NotificationsService, blocklyApp.UtilsService,
|
|
blocklyApp.AudioService,
|
|
function(_notificationsService, _utilsService, _audioService) {
|
|
this.clipboardBlockXml_ = null;
|
|
this.clipboardBlockPreviousConnection_ = null;
|
|
this.clipboardBlockNextConnection_ = null;
|
|
this.clipboardBlockOutputConnection_ = null;
|
|
this.markedConnection_ = null;
|
|
this.notificationsService = _notificationsService;
|
|
this.utilsService = _utilsService;
|
|
this.audioService = _audioService;
|
|
}],
|
|
areConnectionsCompatible_: function(blockConnection, connection) {
|
|
// Check that both connections exist, that it's the right kind of
|
|
// connection, and that the types match.
|
|
return Boolean(
|
|
connection && blockConnection &&
|
|
Blockly.OPPOSITE_TYPE[blockConnection.type] == connection.type &&
|
|
connection.checkType_(blockConnection));
|
|
},
|
|
isCompatibleWithClipboard: function(connection) {
|
|
var previousConnection = this.clipboardBlockPreviousConnection_;
|
|
var nextConnection = this.clipboardBlockNextConnection_;
|
|
var outputConnection = this.clipboardBlockOutputConnection_;
|
|
return Boolean(
|
|
this.areConnectionsCompatible_(connection, previousConnection) ||
|
|
this.areConnectionsCompatible_(connection, nextConnection) ||
|
|
this.areConnectionsCompatible_(connection, outputConnection));
|
|
},
|
|
getMarkedConnectionBlock: function() {
|
|
if (!this.markedConnection_) {
|
|
return null;
|
|
} else {
|
|
return this.markedConnection_.getSourceBlock();
|
|
}
|
|
},
|
|
isMovableToMarkedConnection: function(block) {
|
|
// It should not be possible to move any ancestor of the block containing
|
|
// the marked spot to the marked spot.
|
|
if (!this.markedConnection_) {
|
|
return false;
|
|
}
|
|
|
|
var markedSpotAncestorBlock = this.getMarkedConnectionBlock();
|
|
while (markedSpotAncestorBlock) {
|
|
if (markedSpotAncestorBlock.id == block.id) {
|
|
return false;
|
|
}
|
|
markedSpotAncestorBlock = markedSpotAncestorBlock.getParent();
|
|
}
|
|
|
|
return this.canBeCopiedToMarkedConnection(block);
|
|
},
|
|
canBeCopiedToMarkedConnection: function(block) {
|
|
if (!this.markedConnection_ ||
|
|
!this.markedConnection_.getSourceBlock().workspace) {
|
|
return false;
|
|
}
|
|
|
|
var potentialConnections = [
|
|
block.outputConnection,
|
|
block.previousConnection,
|
|
block.nextConnection
|
|
];
|
|
|
|
var that = this;
|
|
return potentialConnections.some(function(connection) {
|
|
return that.areConnectionsCompatible_(
|
|
connection, that.markedConnection_);
|
|
});
|
|
},
|
|
markConnection: function(connection) {
|
|
this.markedConnection_ = connection;
|
|
this.notificationsService.setStatusMessage(Blockly.Msg.MARKED_SPOT_MSG);
|
|
},
|
|
cut: function(block) {
|
|
this.copy(block);
|
|
block.dispose(true);
|
|
},
|
|
copy: function(block) {
|
|
this.clipboardBlockXml_ = Blockly.Xml.blockToDom(block);
|
|
this.clipboardBlockPreviousConnection_ = block.previousConnection;
|
|
this.clipboardBlockNextConnection_ = block.nextConnection;
|
|
this.clipboardBlockOutputConnection_ = block.outputConnection;
|
|
},
|
|
pasteFromClipboard: function(inputConnection) {
|
|
var connection = inputConnection;
|
|
// If the connection is a 'previousConnection' and that connection is
|
|
// already joined to something, use the 'nextConnection' of the
|
|
// previous block instead in order to do an insertion.
|
|
if (inputConnection.type == Blockly.PREVIOUS_STATEMENT &&
|
|
inputConnection.isConnected()) {
|
|
connection = inputConnection.targetConnection;
|
|
}
|
|
|
|
var reconstitutedBlock = Blockly.Xml.domToBlock(blocklyApp.workspace,
|
|
this.clipboardBlockXml_);
|
|
switch (connection.type) {
|
|
case Blockly.NEXT_STATEMENT:
|
|
connection.connect(reconstitutedBlock.previousConnection);
|
|
break;
|
|
case Blockly.PREVIOUS_STATEMENT:
|
|
connection.connect(reconstitutedBlock.nextConnection);
|
|
break;
|
|
default:
|
|
connection.connect(reconstitutedBlock.outputConnection);
|
|
}
|
|
this.audioService.playConnectSound();
|
|
this.notificationsService.setStatusMessage(
|
|
this.utilsService.getBlockDescription(reconstitutedBlock) + ' ' +
|
|
Blockly.Msg.PASTED_BLOCK_FROM_CLIPBOARD_MSG);
|
|
return reconstitutedBlock.id;
|
|
},
|
|
pasteToMarkedConnection: function(block) {
|
|
var xml = Blockly.Xml.blockToDom(block);
|
|
var reconstitutedBlock = Blockly.Xml.domToBlock(
|
|
blocklyApp.workspace, xml);
|
|
|
|
var potentialConnections = [
|
|
reconstitutedBlock.outputConnection,
|
|
reconstitutedBlock.previousConnection,
|
|
reconstitutedBlock.nextConnection
|
|
];
|
|
|
|
var connectionSuccessful = false;
|
|
for (var i = 0; i < potentialConnections.length; i++) {
|
|
if (this.areConnectionsCompatible_(
|
|
this.markedConnection_, potentialConnections[i])) {
|
|
this.markedConnection_.connect(potentialConnections[i]);
|
|
this.audioService.playConnectSound();
|
|
connectionSuccessful = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!connectionSuccessful) {
|
|
console.error('ERROR: Could not connect block to marked spot.');
|
|
return;
|
|
}
|
|
|
|
this.markedConnection_ = null;
|
|
|
|
return reconstitutedBlock.id;
|
|
}
|
|
});
|