conductUtil.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import warning from "rc-util/es/warning";
  2. import getEntity from "./keyUtil";
  3. function removeFromCheckedKeys(halfCheckedKeys, checkedKeys) {
  4. var filteredKeys = new Set();
  5. halfCheckedKeys.forEach(function (key) {
  6. if (!checkedKeys.has(key)) {
  7. filteredKeys.add(key);
  8. }
  9. });
  10. return filteredKeys;
  11. }
  12. export function isCheckDisabled(node) {
  13. var _ref = node || {},
  14. disabled = _ref.disabled,
  15. disableCheckbox = _ref.disableCheckbox,
  16. checkable = _ref.checkable;
  17. return !!(disabled || disableCheckbox) || checkable === false;
  18. }
  19. // Fill miss keys
  20. function fillConductCheck(keys, levelEntities, maxLevel, syntheticGetCheckDisabled) {
  21. var checkedKeys = new Set(keys);
  22. var halfCheckedKeys = new Set();
  23. // Add checked keys top to bottom
  24. for (var level = 0; level <= maxLevel; level += 1) {
  25. var entities = levelEntities.get(level) || new Set();
  26. entities.forEach(function (entity) {
  27. var key = entity.key,
  28. node = entity.node,
  29. _entity$children = entity.children,
  30. children = _entity$children === void 0 ? [] : _entity$children;
  31. if (checkedKeys.has(key) && !syntheticGetCheckDisabled(node)) {
  32. children.filter(function (childEntity) {
  33. return !syntheticGetCheckDisabled(childEntity.node);
  34. }).forEach(function (childEntity) {
  35. checkedKeys.add(childEntity.key);
  36. });
  37. }
  38. });
  39. }
  40. // Add checked keys from bottom to top
  41. var visitedKeys = new Set();
  42. for (var _level = maxLevel; _level >= 0; _level -= 1) {
  43. var _entities = levelEntities.get(_level) || new Set();
  44. _entities.forEach(function (entity) {
  45. var parent = entity.parent,
  46. node = entity.node;
  47. // Skip if no need to check
  48. if (syntheticGetCheckDisabled(node) || !entity.parent || visitedKeys.has(entity.parent.key)) {
  49. return;
  50. }
  51. // Skip if parent is disabled
  52. if (syntheticGetCheckDisabled(entity.parent.node)) {
  53. visitedKeys.add(parent.key);
  54. return;
  55. }
  56. var allChecked = true;
  57. var partialChecked = false;
  58. (parent.children || []).filter(function (childEntity) {
  59. return !syntheticGetCheckDisabled(childEntity.node);
  60. }).forEach(function (_ref2) {
  61. var key = _ref2.key;
  62. var checked = checkedKeys.has(key);
  63. if (allChecked && !checked) {
  64. allChecked = false;
  65. }
  66. if (!partialChecked && (checked || halfCheckedKeys.has(key))) {
  67. partialChecked = true;
  68. }
  69. });
  70. if (allChecked) {
  71. checkedKeys.add(parent.key);
  72. }
  73. if (partialChecked) {
  74. halfCheckedKeys.add(parent.key);
  75. }
  76. visitedKeys.add(parent.key);
  77. });
  78. }
  79. return {
  80. checkedKeys: Array.from(checkedKeys),
  81. halfCheckedKeys: Array.from(removeFromCheckedKeys(halfCheckedKeys, checkedKeys))
  82. };
  83. }
  84. // Remove useless key
  85. function cleanConductCheck(keys, halfKeys, levelEntities, maxLevel, syntheticGetCheckDisabled) {
  86. var checkedKeys = new Set(keys);
  87. var halfCheckedKeys = new Set(halfKeys);
  88. // Remove checked keys from top to bottom
  89. for (var level = 0; level <= maxLevel; level += 1) {
  90. var entities = levelEntities.get(level) || new Set();
  91. entities.forEach(function (entity) {
  92. var key = entity.key,
  93. node = entity.node,
  94. _entity$children2 = entity.children,
  95. children = _entity$children2 === void 0 ? [] : _entity$children2;
  96. if (!checkedKeys.has(key) && !halfCheckedKeys.has(key) && !syntheticGetCheckDisabled(node)) {
  97. children.filter(function (childEntity) {
  98. return !syntheticGetCheckDisabled(childEntity.node);
  99. }).forEach(function (childEntity) {
  100. checkedKeys.delete(childEntity.key);
  101. });
  102. }
  103. });
  104. }
  105. // Remove checked keys form bottom to top
  106. halfCheckedKeys = new Set();
  107. var visitedKeys = new Set();
  108. for (var _level2 = maxLevel; _level2 >= 0; _level2 -= 1) {
  109. var _entities2 = levelEntities.get(_level2) || new Set();
  110. _entities2.forEach(function (entity) {
  111. var parent = entity.parent,
  112. node = entity.node;
  113. // Skip if no need to check
  114. if (syntheticGetCheckDisabled(node) || !entity.parent || visitedKeys.has(entity.parent.key)) {
  115. return;
  116. }
  117. // Skip if parent is disabled
  118. if (syntheticGetCheckDisabled(entity.parent.node)) {
  119. visitedKeys.add(parent.key);
  120. return;
  121. }
  122. var allChecked = true;
  123. var partialChecked = false;
  124. (parent.children || []).filter(function (childEntity) {
  125. return !syntheticGetCheckDisabled(childEntity.node);
  126. }).forEach(function (_ref3) {
  127. var key = _ref3.key;
  128. var checked = checkedKeys.has(key);
  129. if (allChecked && !checked) {
  130. allChecked = false;
  131. }
  132. if (!partialChecked && (checked || halfCheckedKeys.has(key))) {
  133. partialChecked = true;
  134. }
  135. });
  136. if (!allChecked) {
  137. checkedKeys.delete(parent.key);
  138. }
  139. if (partialChecked) {
  140. halfCheckedKeys.add(parent.key);
  141. }
  142. visitedKeys.add(parent.key);
  143. });
  144. }
  145. return {
  146. checkedKeys: Array.from(checkedKeys),
  147. halfCheckedKeys: Array.from(removeFromCheckedKeys(halfCheckedKeys, checkedKeys))
  148. };
  149. }
  150. /**
  151. * Conduct with keys.
  152. * @param keyList current key list
  153. * @param keyEntities key - dataEntity map
  154. * @param mode `fill` to fill missing key, `clean` to remove useless key
  155. */
  156. export function conductCheck(keyList, checked, keyEntities, getCheckDisabled) {
  157. var warningMissKeys = [];
  158. var syntheticGetCheckDisabled;
  159. if (getCheckDisabled) {
  160. syntheticGetCheckDisabled = getCheckDisabled;
  161. } else {
  162. syntheticGetCheckDisabled = isCheckDisabled;
  163. }
  164. // We only handle exist keys
  165. var keys = new Set(keyList.filter(function (key) {
  166. var hasEntity = !!getEntity(keyEntities, key);
  167. if (!hasEntity) {
  168. warningMissKeys.push(key);
  169. }
  170. return hasEntity;
  171. }));
  172. var levelEntities = new Map();
  173. var maxLevel = 0;
  174. // Convert entities by level for calculation
  175. Object.keys(keyEntities).forEach(function (key) {
  176. var entity = keyEntities[key];
  177. var level = entity.level;
  178. var levelSet = levelEntities.get(level);
  179. if (!levelSet) {
  180. levelSet = new Set();
  181. levelEntities.set(level, levelSet);
  182. }
  183. levelSet.add(entity);
  184. maxLevel = Math.max(maxLevel, level);
  185. });
  186. warning(!warningMissKeys.length, "Tree missing follow keys: ".concat(warningMissKeys.slice(0, 100).map(function (key) {
  187. return "'".concat(key, "'");
  188. }).join(', ')));
  189. var result;
  190. if (checked === true) {
  191. result = fillConductCheck(keys, levelEntities, maxLevel, syntheticGetCheckDisabled);
  192. } else {
  193. result = cleanConductCheck(keys, checked.halfCheckedKeys, levelEntities, maxLevel, syntheticGetCheckDisabled);
  194. }
  195. return result;
  196. }