@internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found. * return true if we moved.
(node: GridStackNode, nn = node, collide?: GridStackNode, opt: GridStackMoveOpts = {})
| 107 | /** @internal fix collision on given 'node', going to given new location 'nn', with optional 'collide' node already found. |
| 108 | * return true if we moved. */ |
| 109 | protected _fixCollisions(node: GridStackNode, nn = node, collide?: GridStackNode, opt: GridStackMoveOpts = {}): boolean { |
| 110 | this.sortNodes(-1); // from last to first, so recursive collision move items in the right order |
| 111 | |
| 112 | collide = collide || this.collide(node, nn); // REAL area collide for swap and skip if none... |
| 113 | if (!collide) return false; |
| 114 | |
| 115 | // swap check: if we're actively moving in gravity mode, see if we collide with an object the same size |
| 116 | if (node._moving && !opt.nested && !this.float) { |
| 117 | if (this.swap(node, collide)) return true; |
| 118 | } |
| 119 | |
| 120 | // during while() collisions MAKE SURE to check entire row so larger items don't leap frog small ones (push them all down starting last in grid) |
| 121 | let area = nn; |
| 122 | if (!this._loading && this._useEntireRowArea(node, nn)) { |
| 123 | area = {x: 0, w: this.column, y: nn.y, h: nn.h}; |
| 124 | collide = this.collide(node, area, opt.skip); // force new hit |
| 125 | } |
| 126 | |
| 127 | let didMove = false; |
| 128 | const newOpt: GridStackMoveOpts = {nested: true, pack: false}; |
| 129 | let counter = 0; |
| 130 | while (collide = collide || this.collide(node, area, opt.skip)) { // could collide with more than 1 item... so repeat for each |
| 131 | if (counter++ > this.nodes.length * 2) { |
| 132 | throw new Error("Infinite collide check"); |
| 133 | } |
| 134 | let moved: boolean; |
| 135 | // if colliding with a locked item OR loading (move after) OR moving down with top gravity (and collide could move up) -> skip past the collide, |
| 136 | // but remember that skip down so we only do this once (and push others otherwise). |
| 137 | if (collide.locked || this._loading || node._moving && !node._skipDown && nn.y > node.y && !this.float && |
| 138 | // can take space we had, or before where we're going |
| 139 | (!this.collide(collide, {...collide, y: node.y}, node) || !this.collide(collide, {...collide, y: nn.y - collide.h}, node))) { |
| 140 | |
| 141 | node._skipDown = (node._skipDown || nn.y > node.y); |
| 142 | const newNN = {...nn, y: collide.y + collide.h, ...newOpt}; |
| 143 | // pretent we moved to where we are now so we can continue any collision checks #2492 |
| 144 | moved = this._loading && Utils.samePos(node, newNN) ? true : this.moveNode(node, newNN); |
| 145 | |
| 146 | if ((collide.locked || this._loading) && moved) { |
| 147 | Utils.copyPos(nn, node); // moving after lock become our new desired location |
| 148 | } else if (!collide.locked && moved && opt.pack) { |
| 149 | // we moved after and will pack: do it now and keep the original drop location, but past the old collide to see what else we might push way |
| 150 | this._packNodes(); |
| 151 | nn.y = collide.y + collide.h; |
| 152 | Utils.copyPos(node, nn); |
| 153 | } |
| 154 | didMove = didMove || moved; |
| 155 | } else { |
| 156 | // move collide down *after* where we will be, ignoring where we are now (don't collide with us) |
| 157 | moved = this.moveNode(collide, {...collide, y: nn.y + nn.h, skip: node, ...newOpt}); |
| 158 | } |
| 159 | |
| 160 | if (!moved) return didMove; // break inf loop if we couldn't move after all (ex: maxRow, fixed) |
| 161 | |
| 162 | collide = undefined; |
| 163 | } |
| 164 | return didMove; |
| 165 | } |
| 166 |
no test coverage detected