select.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. define(function(require, exports, module) {
  2. var kity = require('./kity');
  3. var utils = require('./utils');
  4. var Minder = require('./minder');
  5. var MinderNode = require('./node');
  6. Minder.registerInitHook(function() {
  7. this._initSelection();
  8. });
  9. // 选区管理
  10. kity.extendClass(Minder, {
  11. _initSelection: function() {
  12. this._selectedNodes = [];
  13. },
  14. renderChangedSelection: function(last) {
  15. var current = this.getSelectedNodes();
  16. var changed = [];
  17. current.forEach(function(node) {
  18. if (last.indexOf(node) == -1) {
  19. changed.push(node);
  20. }
  21. });
  22. last.forEach(function(node) {
  23. if (current.indexOf(node) == -1) {
  24. changed.push(node);
  25. }
  26. });
  27. if (changed.length) {
  28. this._interactChange();
  29. this.fire('selectionchange');
  30. }
  31. while (changed.length) {
  32. changed.shift().render();
  33. }
  34. },
  35. getSelectedNodes: function() {
  36. //不能克隆返回,会对当前选区操作,从而影响querycommand
  37. return this._selectedNodes;
  38. },
  39. getSelectedNode: function() {
  40. return this.getSelectedNodes()[0] || null;
  41. },
  42. removeAllSelectedNodes: function() {
  43. var me = this;
  44. var last = this._selectedNodes.splice(0);
  45. this._selectedNodes = [];
  46. this.renderChangedSelection(last);
  47. return this.fire('selectionclear');
  48. },
  49. removeSelectedNodes: function(nodes) {
  50. var me = this;
  51. var last = this._selectedNodes.slice(0);
  52. nodes = utils.isArray(nodes) ? nodes : [nodes];
  53. nodes.forEach(function(node) {
  54. var index;
  55. if ((index = me._selectedNodes.indexOf(node)) === -1) return;
  56. me._selectedNodes.splice(index, 1);
  57. });
  58. this.renderChangedSelection(last);
  59. return this;
  60. },
  61. select: function(nodes, isSingleSelect) {
  62. var lastSelect = this.getSelectedNodes().slice(0);
  63. if (isSingleSelect) {
  64. this._selectedNodes = [];
  65. }
  66. var me = this;
  67. nodes = utils.isArray(nodes) ? nodes : [nodes];
  68. nodes.forEach(function(node) {
  69. if (me._selectedNodes.indexOf(node) !== -1) return;
  70. me._selectedNodes.unshift(node);
  71. });
  72. this.renderChangedSelection(lastSelect);
  73. return this;
  74. },
  75. selectById: function(ids, isSingleSelect) {
  76. ids = utils.isArray(ids) ? ids : [ids];
  77. var nodes = this.getNodesById(ids);
  78. return this.select(nodes, isSingleSelect);
  79. },
  80. //当前选区中的节点在给定的节点范围内的保留选中状态,
  81. //没在给定范围的取消选中,给定范围中的但没在当前选中范围的也做选中效果
  82. toggleSelect: function(node) {
  83. if (utils.isArray(node)) {
  84. node.forEach(this.toggleSelect.bind(this));
  85. } else {
  86. if (node.isSelected()) this.removeSelectedNodes(node);
  87. else this.select(node);
  88. }
  89. return this;
  90. },
  91. isSingleSelect: function() {
  92. return this._selectedNodes.length == 1;
  93. },
  94. getSelectedAncestors: function(includeRoot) {
  95. var nodes = this.getSelectedNodes().slice(0),
  96. ancestors = [],
  97. judge;
  98. // 根节点不参与计算
  99. var rootIndex = nodes.indexOf(this.getRoot());
  100. if (~rootIndex && !includeRoot) {
  101. nodes.splice(rootIndex, 1);
  102. }
  103. // 判断 nodes 列表中是否存在 judge 的祖先
  104. function hasAncestor(nodes, judge) {
  105. for (var i = nodes.length - 1; i >= 0; --i) {
  106. if (nodes[i].isAncestorOf(judge)) return true;
  107. }
  108. return false;
  109. }
  110. // 按照拓扑排序
  111. nodes.sort(function(node1, node2) {
  112. return node1.getLevel() - node2.getLevel();
  113. });
  114. // 因为是拓扑有序的,所以只需往上查找
  115. while ((judge = nodes.pop())) {
  116. if (!hasAncestor(nodes, judge)) {
  117. ancestors.push(judge);
  118. }
  119. }
  120. return ancestors;
  121. }
  122. });
  123. kity.extendClass(MinderNode, {
  124. isSelected: function() {
  125. var minder = this.getMinder();
  126. return minder && minder.getSelectedNodes().indexOf(this) != -1;
  127. }
  128. });
  129. });