clipboard.service.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /**
  2. * AccessibleBlockly
  3. *
  4. * Copyright 2016 Google Inc.
  5. * https://developers.google.com/blockly/
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the 'License');
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an 'AS IS' BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. /**
  20. * @fileoverview Angular2 Service that handles the clipboard and marked spots.
  21. * @author madeeha@google.com (Madeeha Ghori)
  22. */
  23. blocklyApp.ClipboardService = ng.core
  24. .Class({
  25. constructor: function() {
  26. this.clipboardBlockXml_ = null;
  27. this.clipboardBlockSuperiorConnection_ = null;
  28. this.clipboardBlockNextConnection_ = null;
  29. this.markedConnection_ = null;
  30. },
  31. areConnectionsCompatible_: function(blockConnection, connection) {
  32. // Check that both connections exist, that it's the right kind of
  33. // connection, and that the types match.
  34. return Boolean(
  35. connection && blockConnection &&
  36. Blockly.OPPOSITE_TYPE[blockConnection.type] == connection.type &&
  37. connection.checkType_(blockConnection));
  38. },
  39. isCompatibleWithClipboard: function(connection) {
  40. var superiorConnection = this.clipboardBlockSuperiorConnection_;
  41. var nextConnection = this.clipboardBlockNextConnection_;
  42. return Boolean(
  43. this.areConnectionsCompatible_(connection, superiorConnection) ||
  44. this.areConnectionsCompatible_(connection, nextConnection));
  45. },
  46. isMovableToMarkedConnection: function(block) {
  47. // It should not be possible to move any ancestor of the block containing
  48. // the marked spot to the marked spot.
  49. if (!this.markedConnection_) {
  50. return false;
  51. }
  52. var markedSpotAncestorBlock = this.markedConnection_.getSourceBlock();
  53. while (markedSpotAncestorBlock) {
  54. if (markedSpotAncestorBlock.id == block.id) {
  55. return false;
  56. }
  57. markedSpotAncestorBlock = markedSpotAncestorBlock.getParent();
  58. }
  59. return this.canBeCopiedToMarkedConnection(block);
  60. },
  61. canBeCopiedToMarkedConnection: function(block) {
  62. if (!this.markedConnection_ ||
  63. !this.markedConnection_.getSourceBlock().workspace) {
  64. return false;
  65. }
  66. var potentialConnections = [
  67. block.outputConnection,
  68. block.previousConnection,
  69. block.nextConnection
  70. ];
  71. var that = this;
  72. return potentialConnections.some(function(connection) {
  73. return that.areConnectionsCompatible_(
  74. connection, that.markedConnection_);
  75. });
  76. },
  77. markConnection: function(connection) {
  78. this.markedConnection_ = connection;
  79. alert(Blockly.Msg.MARKED_SPOT_MSG);
  80. },
  81. cut: function(block) {
  82. var blockSummary = block.toString();
  83. this.copy(block, false);
  84. block.dispose(true);
  85. alert(Blockly.Msg.CUT_BLOCK_MSG + blockSummary);
  86. },
  87. copy: function(block, announce) {
  88. this.clipboardBlockXml_ = Blockly.Xml.blockToDom(block);
  89. this.clipboardBlockSuperiorConnection_ = block.outputConnection ||
  90. block.previousConnection;
  91. this.clipboardBlockNextConnection_ = block.nextConnection;
  92. if (announce) {
  93. alert(Blockly.Msg.COPIED_BLOCK_MSG + block.toString());
  94. }
  95. },
  96. pasteFromClipboard: function(connection) {
  97. var reconstitutedBlock = Blockly.Xml.domToBlock(blocklyApp.workspace,
  98. this.clipboardBlockXml_);
  99. switch (connection.type) {
  100. case Blockly.NEXT_STATEMENT:
  101. connection.connect(reconstitutedBlock.previousConnection);
  102. break;
  103. case Blockly.PREVIOUS_STATEMENT:
  104. connection.connect(reconstitutedBlock.nextConnection);
  105. break;
  106. default:
  107. connection.connect(reconstitutedBlock.outputConnection);
  108. }
  109. alert(
  110. Blockly.Msg.PASTED_BLOCK_FROM_CLIPBOARD_MSG +
  111. reconstitutedBlock.toString());
  112. },
  113. pasteToMarkedConnection: function(block, announce) {
  114. var xml = Blockly.Xml.blockToDom(block);
  115. var reconstitutedBlock = Blockly.Xml.domToBlock(
  116. blocklyApp.workspace, xml);
  117. var potentialConnections = [
  118. reconstitutedBlock.outputConnection,
  119. reconstitutedBlock.previousConnection,
  120. reconstitutedBlock.nextConnection
  121. ];
  122. var connectionSuccessful = false;
  123. for (var i = 0; i < potentialConnections.length; i++) {
  124. if (this.areConnectionsCompatible_(
  125. this.markedConnection_, potentialConnections[i])) {
  126. this.markedConnection_.connect(potentialConnections[i]);
  127. connectionSuccessful = true;
  128. break;
  129. }
  130. }
  131. if (!connectionSuccessful) {
  132. console.error('ERROR: Could not connect block to marked spot.');
  133. return;
  134. }
  135. if (announce) {
  136. alert(
  137. Blockly.Msg.PASTED_BLOCK_TO_MARKED_SPOT_MSG +
  138. reconstitutedBlock.toString());
  139. }
  140. this.markedConnection_ = null;
  141. }
  142. });