ToggleShapeCollapseHandler.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import {
  2. assign,
  3. forEach
  4. } from 'min-dash';
  5. /**
  6. * A handler that toggles the collapsed state of an element
  7. * and the visibility of all its children.
  8. *
  9. * @param {Modeling} modeling
  10. */
  11. export default function ToggleShapeCollapseHandler(modeling) {
  12. this._modeling = modeling;
  13. }
  14. ToggleShapeCollapseHandler.$inject = [ 'modeling' ];
  15. ToggleShapeCollapseHandler.prototype.execute = function(context) {
  16. var shape = context.shape,
  17. children = shape.children;
  18. // recursively remember previous visibility of children
  19. context.oldChildrenVisibility = getElementsVisibilityRecursive(children);
  20. // toggle state
  21. shape.collapsed = !shape.collapsed;
  22. // recursively hide/show children
  23. var result = setHiddenRecursive(children, shape.collapsed);
  24. return [ shape ].concat(result);
  25. };
  26. ToggleShapeCollapseHandler.prototype.revert = function(context) {
  27. var shape = context.shape,
  28. oldChildrenVisibility = context.oldChildrenVisibility;
  29. var children = shape.children;
  30. // recursively set old visability of children
  31. var result = restoreVisibilityRecursive(children, oldChildrenVisibility);
  32. // retoggle state
  33. shape.collapsed = !shape.collapsed;
  34. return [ shape ].concat(result);
  35. };
  36. // helpers //////////////////////
  37. /**
  38. * Return a map { elementId -> hiddenState}.
  39. *
  40. * @param {Array<djs.model.Shape>} elements
  41. *
  42. * @return {Object}
  43. */
  44. function getElementsVisibilityRecursive(elements) {
  45. var result = {};
  46. forEach(elements, function(element) {
  47. result[element.id] = element.hidden;
  48. if (element.children) {
  49. result = assign({}, result, getElementsVisibilityRecursive(element.children));
  50. }
  51. });
  52. return result;
  53. }
  54. function setHiddenRecursive(elements, newHidden) {
  55. var result = [];
  56. forEach(elements, function(element) {
  57. element.hidden = newHidden;
  58. result = result.concat(element);
  59. if (element.children) {
  60. result = result.concat(setHiddenRecursive(element.children, element.collapsed || newHidden));
  61. }
  62. });
  63. return result;
  64. }
  65. function restoreVisibilityRecursive(elements, lastState) {
  66. var result = [];
  67. forEach(elements, function(element) {
  68. element.hidden = lastState[element.id];
  69. result = result.concat(element);
  70. if (element.children) {
  71. result = result.concat(restoreVisibilityRecursive(element.children, lastState));
  72. }
  73. });
  74. return result;
  75. }