clipboard.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * @Desc: 处理editor的clipboard事件,只在支持ClipboardEvent并且不是FF的情况下工作
  3. * @Editor: Naixor
  4. * @Date: 2015.9.21
  5. */
  6. define(function(require, exports, module) {
  7. function ClipboardRuntime () {
  8. var minder = this.minder;
  9. var Data = window.kityminder.data;
  10. if (!minder.supportClipboardEvent || kity.Browser.gecko) {
  11. return;
  12. };
  13. var fsm = this.fsm;
  14. var receiver = this.receiver;
  15. var MimeType = this.MimeType;
  16. var kmencode = MimeType.getMimeTypeProtocol('application/km'),
  17. decode = Data.getRegisterProtocol('json').decode;
  18. var _selectedNodes = [];
  19. /*
  20. * 增加对多节点赋值粘贴的处理
  21. */
  22. function encode (nodes) {
  23. var _nodes = [];
  24. for (var i = 0, l = nodes.length; i < l; i++) {
  25. _nodes.push(minder.exportNode(nodes[i]));
  26. }
  27. return kmencode(Data.getRegisterProtocol('json').encode(_nodes));
  28. }
  29. var beforeCopy = function (e) {
  30. if (document.activeElement == receiver.element) {
  31. var clipBoardEvent = e;
  32. var state = fsm.state();
  33. switch (state) {
  34. case 'input': {
  35. break;
  36. }
  37. case 'normal': {
  38. var nodes = [].concat(minder.getSelectedNodes());
  39. if (nodes.length) {
  40. // 这里由于被粘贴复制的节点的id信息也都一样,故做此算法
  41. // 这里有个疑问,使用node.getParent()或者node.parent会离奇导致出现非选中节点被渲染成选中节点,因此使用isAncestorOf,而没有使用自行回溯的方式
  42. if (nodes.length > 1) {
  43. var targetLevel;
  44. nodes.sort(function(a, b) {
  45. return a.getLevel() - b.getLevel();
  46. });
  47. targetLevel = nodes[0].getLevel();
  48. if (targetLevel !== nodes[nodes.length-1].getLevel()) {
  49. var plevel, pnode,
  50. idx = 0, l = nodes.length, pidx = l-1;
  51. pnode = nodes[pidx];
  52. while (pnode.getLevel() !== targetLevel) {
  53. idx = 0;
  54. while (idx < l && nodes[idx].getLevel() === targetLevel) {
  55. if (nodes[idx].isAncestorOf(pnode)) {
  56. nodes.splice(pidx, 1);
  57. break;
  58. }
  59. idx++;
  60. }
  61. pidx--;
  62. pnode = nodes[pidx];
  63. }
  64. };
  65. };
  66. var str = encode(nodes);
  67. clipBoardEvent.clipboardData.setData('text/plain', str);
  68. }
  69. e.preventDefault();
  70. break;
  71. }
  72. }
  73. }
  74. }
  75. var beforeCut = function (e) {
  76. if (document.activeElement == receiver.element) {
  77. if (minder.getStatus() !== 'normal') {
  78. e.preventDefault();
  79. return;
  80. };
  81. var clipBoardEvent = e;
  82. var state = fsm.state();
  83. switch (state) {
  84. case 'input': {
  85. break;
  86. }
  87. case 'normal': {
  88. var nodes = minder.getSelectedNodes();
  89. if (nodes.length) {
  90. clipBoardEvent.clipboardData.setData('text/plain', encode(nodes));
  91. minder.execCommand('removenode');
  92. }
  93. e.preventDefault();
  94. break;
  95. }
  96. }
  97. };
  98. }
  99. var beforePaste = function(e) {
  100. if (document.activeElement == receiver.element) {
  101. if (minder.getStatus() !== 'normal') {
  102. e.preventDefault();
  103. return;
  104. };
  105. var clipBoardEvent = e;
  106. var state = fsm.state();
  107. var textData = clipBoardEvent.clipboardData.getData('text/plain');
  108. switch (state) {
  109. case 'input': {
  110. // input状态下如果格式为application/km则不进行paste操作
  111. if (!MimeType.isPureText(textData)) {
  112. e.preventDefault();
  113. return;
  114. };
  115. break;
  116. }
  117. case 'normal': {
  118. /*
  119. * 针对normal状态下通过对选中节点粘贴导入子节点文本进行单独处理
  120. */
  121. var sNodes = minder.getSelectedNodes();
  122. if (MimeType.whichMimeType(textData) === 'application/km') {
  123. var nodes = decode(MimeType.getPureText(textData));
  124. var _node;
  125. sNodes.forEach(function(node) {
  126. // 由于粘贴逻辑中为了排除子节点重新排序导致逆序,因此复制的时候倒过来
  127. for (var i = nodes.length-1; i >= 0; i--) {
  128. _node = minder.createNode(null, node);
  129. minder.importNode(_node, nodes[i]);
  130. _selectedNodes.push(_node);
  131. node.appendChild(_node);
  132. }
  133. });
  134. minder.select(_selectedNodes, true);
  135. _selectedNodes = [];
  136. minder.refresh();
  137. }
  138. else if (clipBoardEvent.clipboardData && clipBoardEvent.clipboardData.items[0].type.indexOf('image') > -1) {
  139. var imageFile = clipBoardEvent.clipboardData.items[0].getAsFile();
  140. var serverService = angular.element(document.body).injector().get('server');
  141. return serverService.uploadImage(imageFile).then(function (json) {
  142. var resp = json.data;
  143. if (resp.errno === 0) {
  144. minder.execCommand('image', resp.data.url);
  145. }
  146. });
  147. }
  148. else {
  149. sNodes.forEach(function(node) {
  150. minder.Text2Children(node, textData);
  151. });
  152. }
  153. e.preventDefault();
  154. break;
  155. }
  156. }
  157. }
  158. }
  159. /**
  160. * 由editor的receiver统一处理全部事件,包括clipboard事件
  161. * @Editor: Naixor
  162. * @Date: 2015.9.24
  163. */
  164. document.addEventListener('copy', beforeCopy);
  165. document.addEventListener('cut', beforeCut);
  166. document.addEventListener('paste', beforePaste);
  167. }
  168. return module.exports = ClipboardRuntime;
  169. });