gridstack 8.2.3 → 8.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/angular/projects/demo/src/app/app.component.html +32 -0
  2. package/angular/projects/demo/src/app/app.component.ts +20 -5
  3. package/angular/projects/demo/src/styles.css +37 -0
  4. package/angular/projects/lib/package.json +1 -1
  5. package/angular/projects/lib/src/lib/base-widget.ts +1 -1
  6. package/angular/projects/lib/src/lib/gridstack-item.component.ts +1 -1
  7. package/angular/projects/lib/src/lib/gridstack.component.ts +1 -1
  8. package/angular/projects/lib/src/lib/gridstack.module.ts +1 -1
  9. package/dist/angular/esm2020/lib/base-widget.mjs +2 -2
  10. package/dist/angular/esm2020/lib/gridstack-item.component.mjs +2 -2
  11. package/dist/angular/esm2020/lib/gridstack.component.mjs +2 -2
  12. package/dist/angular/esm2020/lib/gridstack.module.mjs +2 -2
  13. package/dist/angular/fesm2015/gridstack-angular.mjs +4 -4
  14. package/dist/angular/fesm2015/gridstack-angular.mjs.map +1 -1
  15. package/dist/angular/fesm2020/gridstack-angular.mjs +4 -4
  16. package/dist/angular/fesm2020/gridstack-angular.mjs.map +1 -1
  17. package/dist/angular/lib/gridstack-item.component.d.ts +1 -1
  18. package/dist/angular/lib/gridstack.component.d.ts +1 -1
  19. package/dist/angular/package.json +1 -1
  20. package/dist/angular/src/base-widget.ts +1 -1
  21. package/dist/angular/src/gridstack-item.component.ts +1 -1
  22. package/dist/angular/src/gridstack.component.ts +1 -1
  23. package/dist/angular/src/gridstack.module.ts +1 -1
  24. package/dist/dd-base-impl.d.ts +1 -1
  25. package/dist/dd-base-impl.js +1 -1
  26. package/dist/dd-base-impl.js.map +1 -1
  27. package/dist/dd-draggable.d.ts +1 -1
  28. package/dist/dd-draggable.js +1 -1
  29. package/dist/dd-draggable.js.map +1 -1
  30. package/dist/dd-droppable.d.ts +1 -1
  31. package/dist/dd-droppable.js +2 -2
  32. package/dist/dd-droppable.js.map +1 -1
  33. package/dist/dd-element.d.ts +1 -1
  34. package/dist/dd-element.js +1 -1
  35. package/dist/dd-element.js.map +1 -1
  36. package/dist/dd-gridstack.d.ts +1 -1
  37. package/dist/dd-gridstack.js +1 -1
  38. package/dist/dd-gridstack.js.map +1 -1
  39. package/dist/dd-manager.d.ts +1 -1
  40. package/dist/dd-manager.js +1 -1
  41. package/dist/dd-manager.js.map +1 -1
  42. package/dist/dd-resizable-handle.d.ts +1 -1
  43. package/dist/dd-resizable-handle.js +1 -1
  44. package/dist/dd-resizable-handle.js.map +1 -1
  45. package/dist/dd-resizable.d.ts +1 -1
  46. package/dist/dd-resizable.js +1 -1
  47. package/dist/dd-resizable.js.map +1 -1
  48. package/dist/dd-touch.d.ts +1 -1
  49. package/dist/dd-touch.js +1 -1
  50. package/dist/dd-touch.js.map +1 -1
  51. package/dist/es5/dd-base-impl.d.ts +1 -1
  52. package/dist/es5/dd-base-impl.js +1 -1
  53. package/dist/es5/dd-base-impl.js.map +1 -1
  54. package/dist/es5/dd-draggable.d.ts +1 -1
  55. package/dist/es5/dd-draggable.js +1 -1
  56. package/dist/es5/dd-draggable.js.map +1 -1
  57. package/dist/es5/dd-droppable.d.ts +1 -1
  58. package/dist/es5/dd-droppable.js +2 -2
  59. package/dist/es5/dd-droppable.js.map +1 -1
  60. package/dist/es5/dd-element.d.ts +1 -1
  61. package/dist/es5/dd-element.js +1 -1
  62. package/dist/es5/dd-element.js.map +1 -1
  63. package/dist/es5/dd-gridstack.d.ts +1 -1
  64. package/dist/es5/dd-gridstack.js +1 -1
  65. package/dist/es5/dd-gridstack.js.map +1 -1
  66. package/dist/es5/dd-manager.d.ts +1 -1
  67. package/dist/es5/dd-manager.js +1 -1
  68. package/dist/es5/dd-manager.js.map +1 -1
  69. package/dist/es5/dd-resizable-handle.d.ts +1 -1
  70. package/dist/es5/dd-resizable-handle.js +1 -1
  71. package/dist/es5/dd-resizable-handle.js.map +1 -1
  72. package/dist/es5/dd-resizable.d.ts +1 -1
  73. package/dist/es5/dd-resizable.js +1 -1
  74. package/dist/es5/dd-resizable.js.map +1 -1
  75. package/dist/es5/dd-touch.d.ts +1 -1
  76. package/dist/es5/dd-touch.js +1 -1
  77. package/dist/es5/dd-touch.js.map +1 -1
  78. package/dist/es5/gridstack-all.js +1 -1
  79. package/dist/es5/gridstack-all.js.LICENSE.txt +1 -1
  80. package/dist/es5/gridstack-all.js.map +1 -1
  81. package/dist/es5/gridstack-engine.d.ts +9 -8
  82. package/dist/es5/gridstack-engine.js +119 -75
  83. package/dist/es5/gridstack-engine.js.map +1 -1
  84. package/dist/es5/gridstack-poly.js +1 -1
  85. package/dist/es5/gridstack.d.ts +11 -5
  86. package/dist/es5/gridstack.js +54 -32
  87. package/dist/es5/gridstack.js.map +1 -1
  88. package/dist/es5/types.d.ts +14 -5
  89. package/dist/es5/types.js +3 -2
  90. package/dist/es5/types.js.map +1 -1
  91. package/dist/es5/utils.d.ts +2 -2
  92. package/dist/es5/utils.js +4 -3
  93. package/dist/es5/utils.js.map +1 -1
  94. package/dist/gridstack-all.js +1 -1
  95. package/dist/gridstack-all.js.LICENSE.txt +1 -1
  96. package/dist/gridstack-all.js.map +1 -1
  97. package/dist/gridstack-engine.d.ts +9 -8
  98. package/dist/gridstack-engine.js +114 -75
  99. package/dist/gridstack-engine.js.map +1 -1
  100. package/dist/gridstack.css +1 -1
  101. package/dist/gridstack.d.ts +11 -5
  102. package/dist/gridstack.js +49 -30
  103. package/dist/gridstack.js.map +1 -1
  104. package/dist/src/gridstack.scss +1 -1
  105. package/dist/types.d.ts +14 -5
  106. package/dist/types.js +3 -2
  107. package/dist/types.js.map +1 -1
  108. package/dist/utils.d.ts +2 -2
  109. package/dist/utils.js +4 -4
  110. package/dist/utils.js.map +1 -1
  111. package/doc/CHANGES.md +10 -0
  112. package/doc/README.md +17 -8
  113. package/package.json +1 -1
  114. package/angular/projects/demo/src/environments/environment.prod.ts +0 -3
@@ -1,8 +1,8 @@
1
1
  /**
2
- * gridstack-engine.ts 8.2.3
2
+ * gridstack-engine.ts 8.4.0
3
3
  * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license
4
4
  */
5
- import { GridStackNode, GridStackPosition, GridStackMoveOpts, SaveFcn } from './types';
5
+ import { GridStackNode, GridStackPosition, GridStackMoveOpts, SaveFcn, CompactOptions } from './types';
6
6
  /** callback to update the DOM attributes since this class is generic (no HTML or other info) for items that changed - see _notify() */
7
7
  type OnChangeCB = (nodes: GridStackNode[]) => void;
8
8
  /** options used during creation - similar to GridStackOptions */
@@ -27,7 +27,7 @@ export declare class GridStackEngine {
27
27
  removedNodes: GridStackNode[];
28
28
  batchMode: boolean;
29
29
  constructor(opts?: GridStackEngineOptions);
30
- batchUpdate(flag?: boolean): GridStackEngine;
30
+ batchUpdate(flag?: boolean, doPack?: boolean): GridStackEngine;
31
31
  protected _useEntireRowArea(node: GridStackNode, nn: GridStackPosition): boolean;
32
32
  /** return the nodes that intercept the given node. Optionally a different area can be used, as well as a second node to skip */
33
33
  collide(skip: GridStackNode, area?: GridStackNode, skip2?: GridStackNode): GridStackNode;
@@ -40,14 +40,14 @@ export declare class GridStackEngine {
40
40
  /** called to possibly swap between 2 nodes (same size or column, not locked, touching), returning true if successful */
41
41
  swap(a: GridStackNode, b: GridStackNode): boolean;
42
42
  isAreaEmpty(x: number, y: number, w: number, h: number): boolean;
43
- /** re-layout grid items to reclaim any empty space */
44
- compact(): GridStackEngine;
43
+ /** re-layout grid items to reclaim any empty space - optionally keeping the sort order exactly the same ('list' mode) vs truly finding an empty spaces */
44
+ compact(layout?: CompactOptions, doSort?: boolean): GridStackEngine;
45
45
  /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */
46
46
  set float(val: boolean);
47
47
  /** float getter method */
48
48
  get float(): boolean;
49
49
  /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */
50
- sortNodes(dir?: -1 | 1): GridStackEngine;
50
+ sortNodes(dir?: 1 | -1, column?: number): GridStackEngine;
51
51
  /**
52
52
  * given a random node, makes sure it's coordinates/values are valid in the current grid
53
53
  * @param node to adjust
@@ -60,10 +60,11 @@ export declare class GridStackEngine {
60
60
  getDirtyNodes(verify?: boolean): GridStackNode[];
61
61
  /** find the first available empty spot for the given node width/height, updating the x,y attributes. return true if found.
62
62
  * optionally you can pass your own existing node list and column count, otherwise defaults to that engine data.
63
+ * Optionally pass a widget to start search AFTER, meaning the order will remain the same but possibly have empty slots we skipped
63
64
  */
64
- findEmptyPosition(node: GridStackNode, nodeList?: GridStackNode[], column?: number): boolean;
65
+ findEmptyPosition(node: GridStackNode, nodeList?: GridStackNode[], column?: number, after?: GridStackNode): boolean;
65
66
  /** call to add the given node to our list, fixing collision and re-packing */
66
- addNode(node: GridStackNode, triggerAddEvent?: boolean): GridStackNode;
67
+ addNode(node: GridStackNode, triggerAddEvent?: boolean, after?: GridStackNode): GridStackNode;
67
68
  removeNode(node: GridStackNode, removeDOM?: boolean, triggerEvent?: boolean): GridStackEngine;
68
69
  removeAll(removeDOM?: boolean): GridStackEngine;
69
70
  /** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * gridstack-engine.ts 8.2.3
2
+ * gridstack-engine.ts 8.4.0
3
3
  * Copyright (c) 2021-2022 Alain Dumesny - see GridStack root license
4
4
  */
5
5
  import { Utils } from './utils';
@@ -19,7 +19,7 @@ class GridStackEngine {
19
19
  this.nodes = opts.nodes || [];
20
20
  this.onChange = opts.onChange;
21
21
  }
22
- batchUpdate(flag = true) {
22
+ batchUpdate(flag = true, doPack = true) {
23
23
  if (!!this.batchMode === flag)
24
24
  return this;
25
25
  this.batchMode = flag;
@@ -31,7 +31,9 @@ class GridStackEngine {
31
31
  else {
32
32
  this._float = this._prevFloat;
33
33
  delete this._prevFloat;
34
- this._packNodes()._notify();
34
+ if (doPack)
35
+ this._packNodes();
36
+ this._notify();
35
37
  }
36
38
  return this;
37
39
  }
@@ -232,22 +234,34 @@ class GridStackEngine {
232
234
  let nn = { x: x || 0, y: y || 0, w: w || 1, h: h || 1 };
233
235
  return !this.collide(nn);
234
236
  }
235
- /** re-layout grid items to reclaim any empty space */
236
- compact() {
237
+ /** re-layout grid items to reclaim any empty space - optionally keeping the sort order exactly the same ('list' mode) vs truly finding an empty spaces */
238
+ compact(layout = 'compact', doSort = true) {
237
239
  if (this.nodes.length === 0)
238
240
  return this;
239
- this.batchUpdate()
240
- .sortNodes();
241
+ if (doSort)
242
+ this.sortNodes();
243
+ const wasBatch = this.batchMode;
244
+ if (!wasBatch)
245
+ this.batchUpdate();
246
+ const wasColumnResize = this._inColumnResize;
247
+ if (!wasColumnResize)
248
+ this._inColumnResize = true; // faster addNode()
241
249
  let copyNodes = this.nodes;
242
250
  this.nodes = []; // pretend we have no nodes to conflict layout to start with...
243
- copyNodes.forEach(node => {
244
- if (!node.locked) {
245
- node.autoPosition = true;
251
+ copyNodes.forEach((n, index, list) => {
252
+ let after;
253
+ if (!n.locked) {
254
+ n.autoPosition = true;
255
+ if (layout === 'list' && index)
256
+ after = list[index - 1];
246
257
  }
247
- this.addNode(node, false); // 'false' for add event trigger
248
- node._dirty = true; // will force attr update
258
+ this.addNode(n, false, after); // 'false' for add event trigger
249
259
  });
250
- return this.batchUpdate(false);
260
+ if (!wasColumnResize)
261
+ delete this._inColumnResize;
262
+ if (!wasBatch)
263
+ this.batchUpdate(false);
264
+ return this;
251
265
  }
252
266
  /** enable/disable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) */
253
267
  set float(val) {
@@ -261,8 +275,8 @@ class GridStackEngine {
261
275
  /** float getter method */
262
276
  get float() { return this._float || false; }
263
277
  /** sort the nodes array from first to last, or reverse. Called during collision/placement to force an order */
264
- sortNodes(dir) {
265
- this.nodes = Utils.sort(this.nodes, dir, this.column);
278
+ sortNodes(dir = 1, column = this.column) {
279
+ this.nodes = Utils.sort(this.nodes, dir, column);
266
280
  return this;
267
281
  }
268
282
  /** @internal called to top gravity pack the items back OR revert back to original Y positions when floating */
@@ -480,11 +494,12 @@ class GridStackEngine {
480
494
  }
481
495
  /** find the first available empty spot for the given node width/height, updating the x,y attributes. return true if found.
482
496
  * optionally you can pass your own existing node list and column count, otherwise defaults to that engine data.
497
+ * Optionally pass a widget to start search AFTER, meaning the order will remain the same but possibly have empty slots we skipped
483
498
  */
484
- findEmptyPosition(node, nodeList = this.nodes, column = this.column) {
485
- nodeList = Utils.sort(nodeList, -1, column);
499
+ findEmptyPosition(node, nodeList = this.nodes, column = this.column, after) {
500
+ let start = after ? after.y * column + (after.x + after.w) : 0;
486
501
  let found = false;
487
- for (let i = 0; !found; ++i) {
502
+ for (let i = start; !found; ++i) {
488
503
  let x = i % column;
489
504
  let y = Math.floor(i / column);
490
505
  if (x + node.w > column) {
@@ -492,6 +507,8 @@ class GridStackEngine {
492
507
  }
493
508
  let box = { x, y, w: node.w, h: node.h };
494
509
  if (!nodeList.find(n => Utils.isIntercepted(box, n))) {
510
+ if (node.x !== x || node.y !== y)
511
+ node._dirty = true;
495
512
  node.x = x;
496
513
  node.y = y;
497
514
  delete node.autoPosition;
@@ -501,7 +518,7 @@ class GridStackEngine {
501
518
  return found;
502
519
  }
503
520
  /** call to add the given node to our list, fixing collision and re-packing */
504
- addNode(node, triggerAddEvent = false) {
521
+ addNode(node, triggerAddEvent = false, after) {
505
522
  let dup = this.nodes.find(n => n._id === node._id);
506
523
  if (dup)
507
524
  return dup; // prevent inserting twice! return it instead.
@@ -509,14 +526,17 @@ class GridStackEngine {
509
526
  node = this._inColumnResize ? this.nodeBoundFix(node) : this.prepareNode(node);
510
527
  delete node._temporaryRemoved;
511
528
  delete node._removeDOM;
512
- if (node.autoPosition && this.findEmptyPosition(node)) {
529
+ let skipCollision;
530
+ if (node.autoPosition && this.findEmptyPosition(node, this.nodes, this.column, after)) {
513
531
  delete node.autoPosition; // found our slot
532
+ skipCollision = true;
514
533
  }
515
534
  this.nodes.push(node);
516
535
  if (triggerAddEvent) {
517
536
  this.addedNodes.push(node);
518
537
  }
519
- this._fixCollisions(node);
538
+ if (!skipCollision)
539
+ this._fixCollisions(node);
520
540
  if (!this.batchMode) {
521
541
  this._packNodes()._notify();
522
542
  }
@@ -534,8 +554,10 @@ class GridStackEngine {
534
554
  node._removeDOM = true; // let CB remove actual HTML (used to set _id to null, but then we loose layout info)
535
555
  // don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times.
536
556
  this.nodes = this.nodes.filter(n => n._id !== node._id);
537
- return this._packNodes()
538
- ._notify([node]);
557
+ if (!node._isAboutToRemove)
558
+ this._packNodes(); // if dragged out, no need to relayout as already done...
559
+ this._notify([node]);
560
+ return this;
539
561
  }
540
562
  removeAll(removeDOM = true) {
541
563
  delete this._layouts;
@@ -805,14 +827,20 @@ class GridStackEngine {
805
827
  * @param layout specify the type of re-layout that will happen (position, size, etc...).
806
828
  * Note: items will never be outside of the current column boundaries. default (moveScale). Ignored for 1 column
807
829
  */
808
- updateNodeWidths(prevColumn, column, nodes, layout = 'moveScale') {
830
+ columnChanged(prevColumn, column, nodes, layout = 'moveScale') {
809
831
  if (!this.nodes.length || !column || prevColumn === column)
810
832
  return this;
811
- // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data
812
- this.cacheLayout(this.nodes, prevColumn);
833
+ // simpler shortcuts layouts
834
+ const doCompact = layout === 'compact' || layout === 'list';
835
+ if (doCompact) {
836
+ this.sortNodes(1, prevColumn); // sort with original layout once and only once (new column will affect order otherwise)
837
+ }
838
+ // cache the current layout in case they want to go back (like 12 -> 1 -> 12) as it requires original data IFF we're sizing down (see below)
839
+ if (column < prevColumn)
840
+ this.cacheLayout(this.nodes, prevColumn);
813
841
  this.batchUpdate(); // do this EARLY as it will call saveInitial() so we can detect where we started for _dirty and collision
814
842
  let newNodes = [];
815
- // if we're going to 1 column and using DOM order rather than default sorting, then generate that layout
843
+ // if we're going to 1 column and using DOM order (item passed in) rather than default sorting, then generate that layout
816
844
  let domOrder = false;
817
845
  if (column === 1 && nodes?.length) {
818
846
  domOrder = true;
@@ -827,13 +855,12 @@ class GridStackEngine {
827
855
  nodes = [];
828
856
  }
829
857
  else {
830
- nodes = Utils.sort(this.nodes, -1, prevColumn); // current column reverse sorting so we can insert last to front (limit collision)
858
+ nodes = doCompact ? this.nodes : Utils.sort(this.nodes, -1, prevColumn); // current column reverse sorting so we can insert last to front (limit collision)
831
859
  }
832
860
  // see if we have cached previous layout IFF we are going up in size (restore) otherwise always
833
861
  // generate next size down from where we are (looks more natural as you gradually size down).
834
- let cacheNodes = [];
835
- if (column > prevColumn) {
836
- cacheNodes = this._layouts[column] || [];
862
+ if (column > prevColumn && this._layouts) {
863
+ const cacheNodes = this._layouts[column] || [];
837
864
  // ...if not, start with the largest layout (if not already there) as down-scaling is more accurate
838
865
  // by pretending we came from that larger column by assigning those values as starting point
839
866
  let lastIndex = this._layouts.length - 1;
@@ -843,59 +870,71 @@ class GridStackEngine {
843
870
  let n = nodes.find(n => n._id === cacheNode._id);
844
871
  if (n) {
845
872
  // still current, use cache info positions
846
- n.x = cacheNode.x;
847
- n.y = cacheNode.y;
873
+ if (!doCompact) {
874
+ n.x = cacheNode.x;
875
+ n.y = cacheNode.y;
876
+ }
848
877
  n.w = cacheNode.w;
849
878
  }
850
879
  });
851
880
  }
881
+ // if we found cache re-use those nodes that are still current
882
+ cacheNodes.forEach(cacheNode => {
883
+ let j = nodes.findIndex(n => n._id === cacheNode._id);
884
+ if (j !== -1) {
885
+ // still current, use cache info positions
886
+ if (doCompact) {
887
+ nodes[j].w = cacheNode.w; // only w is used, and don't trim the list
888
+ return;
889
+ }
890
+ if (cacheNode.autoPosition || isNaN(cacheNode.x) || isNaN(cacheNode.y)) {
891
+ this.findEmptyPosition(cacheNode, newNodes);
892
+ }
893
+ if (!cacheNode.autoPosition) {
894
+ nodes[j].x = cacheNode.x;
895
+ nodes[j].y = cacheNode.y;
896
+ nodes[j].w = cacheNode.w;
897
+ newNodes.push(nodes[j]);
898
+ }
899
+ nodes.splice(j, 1);
900
+ }
901
+ });
902
+ }
903
+ // much simpler layout that just compacts
904
+ if (doCompact) {
905
+ this.compact(layout, false);
852
906
  }
853
- // if we found cache re-use those nodes that are still current
854
- cacheNodes.forEach(cacheNode => {
855
- let j = nodes.findIndex(n => n._id === cacheNode._id);
856
- if (j !== -1) {
857
- // still current, use cache info positions
858
- if (cacheNode.autoPosition || isNaN(cacheNode.x) || isNaN(cacheNode.y)) {
859
- this.findEmptyPosition(cacheNode, newNodes);
907
+ else {
908
+ // ...and add any extra non-cached ones
909
+ if (nodes.length) {
910
+ if (typeof layout === 'function') {
911
+ layout(column, prevColumn, newNodes, nodes);
860
912
  }
861
- if (!cacheNode.autoPosition) {
862
- nodes[j].x = cacheNode.x;
863
- nodes[j].y = cacheNode.y;
864
- nodes[j].w = cacheNode.w;
865
- newNodes.push(nodes[j]);
913
+ else if (!domOrder) {
914
+ let ratio = (doCompact || layout === 'none') ? 1 : column / prevColumn;
915
+ let move = (layout === 'move' || layout === 'moveScale');
916
+ let scale = (layout === 'scale' || layout === 'moveScale');
917
+ nodes.forEach(node => {
918
+ // NOTE: x + w could be outside of the grid, but addNode() below will handle that
919
+ node.x = (column === 1 ? 0 : (move ? Math.round(node.x * ratio) : Math.min(node.x, column - 1)));
920
+ node.w = ((column === 1 || prevColumn === 1) ? 1 : scale ? (Math.round(node.w * ratio) || 1) : (Math.min(node.w, column)));
921
+ newNodes.push(node);
922
+ });
923
+ nodes = [];
866
924
  }
867
- nodes.splice(j, 1);
868
- }
869
- });
870
- // ...and add any extra non-cached ones
871
- if (nodes.length) {
872
- if (typeof layout === 'function') {
873
- layout(column, prevColumn, newNodes, nodes);
874
- }
875
- else if (!domOrder) {
876
- let ratio = column / prevColumn;
877
- let move = (layout === 'move' || layout === 'moveScale');
878
- let scale = (layout === 'scale' || layout === 'moveScale');
879
- nodes.forEach(node => {
880
- // NOTE: x + w could be outside of the grid, but addNode() below will handle that
881
- node.x = (column === 1 ? 0 : (move ? Math.round(node.x * ratio) : Math.min(node.x, column - 1)));
882
- node.w = ((column === 1 || prevColumn === 1) ? 1 :
883
- scale ? (Math.round(node.w * ratio) || 1) : (Math.min(node.w, column)));
884
- newNodes.push(node);
885
- });
886
- nodes = [];
887
925
  }
926
+ // finally re-layout them in reverse order (to get correct placement)
927
+ if (!domOrder)
928
+ newNodes = Utils.sort(newNodes, -1, column);
929
+ this._inColumnResize = true; // prevent cache update
930
+ this.nodes = []; // pretend we have no nodes to start with (add() will use same structures) to simplify layout
931
+ newNodes.forEach(node => {
932
+ this.addNode(node, false); // 'false' for add event trigger
933
+ delete node._orig; // make sure the commit doesn't try to restore things back to original
934
+ });
888
935
  }
889
- // finally re-layout them in reverse order (to get correct placement)
890
- if (!domOrder)
891
- newNodes = Utils.sort(newNodes, -1, column);
892
- this._inColumnResize = true; // prevent cache update
893
- this.nodes = []; // pretend we have no nodes to start with (add() will use same structures) to simplify layout
894
- newNodes.forEach(node => {
895
- this.addNode(node, false); // 'false' for add event trigger
896
- delete node._orig; // make sure the commit doesn't try to restore things back to original
897
- });
898
- this.batchUpdate(false);
936
+ this.nodes.forEach(n => delete n._orig); // clear _orig before batch=false so it doesn't handle float=true restore
937
+ this.batchUpdate(false, !doCompact);
899
938
  delete this._inColumnResize;
900
939
  return this;
901
940
  }