|
1 | 1 | import { GridItemHTMLElement, GridStack, GridStackWidget } from '../src/gridstack'; |
| 2 | +import type { GridStackNode } from '../src/types'; |
| 3 | +import { Utils } from '../src/utils'; |
2 | 4 |
|
3 | 5 | describe('regression >', () => { |
4 | 6 | 'use strict'; |
@@ -108,4 +110,62 @@ describe('regression >', () => { |
108 | 110 | expect(parseInt(el3.getAttribute('gs-y'))).toBe(1); |
109 | 111 | }); |
110 | 112 | }); |
| 113 | + |
| 114 | + describe('3175 hovering to nest must not lose the underlying widget >', () => { |
| 115 | + beforeEach(() => { |
| 116 | + document.body.insertAdjacentHTML('afterbegin', gridstackEmptyHTML); |
| 117 | + }); |
| 118 | + afterEach(() => { |
| 119 | + delete GridStack.addRemoveCB; |
| 120 | + document.body.removeChild(document.getElementById('gs-cont')); |
| 121 | + }); |
| 122 | + |
| 123 | + // NOTE: the report is a video on the nested_advanced demo with no code reference, and the |
| 124 | + // dynamic-nesting trigger needs real 80%-coverage drag geometry, so this could NOT be |
| 125 | + // reproduced at the API level. These lock in the create -> revert round trip either way. |
| 126 | + const makeGrid = () => GridStack.init({column: 12, cellHeight: 50, subGridDynamic: true, |
| 127 | + children: [{id: 'under', x: 0, y: 0, w: 4, h: 2, content: 'IMPORTANT'}]}); |
| 128 | + |
| 129 | + it('keeps the hovered widget when a sub-grid is created over it', () => { |
| 130 | + grid = makeGrid(); |
| 131 | + const under = grid.engine.nodes.find(n => n.id === 'under')!; |
| 132 | + grid.makeSubGrid(under.el!, undefined, {id: 'dropped', w: 2, h: 2, content: 'new'} as GridStackNode); |
| 133 | + |
| 134 | + const sg = under.subGrid!; |
| 135 | + expect(sg).toBeTruthy(); |
| 136 | + expect(sg.engine.nodes.length).toBeGreaterThan(0); |
| 137 | + expect(sg.el.textContent).toContain('IMPORTANT'); // the underlying widget is still there |
| 138 | + }); |
| 139 | + |
| 140 | + it('keeps it through the addRemoveCB path too (framework wrappers)', () => { |
| 141 | + GridStack.addRemoveCB = (parent, w, add, isGrid) => { |
| 142 | + if (!add) return undefined; |
| 143 | + if (isGrid) { |
| 144 | + const e = Utils.createDiv(['grid-stack']); |
| 145 | + parent.appendChild(e); |
| 146 | + return e; |
| 147 | + } |
| 148 | + const e = Utils.createDiv(['grid-stack-item']); |
| 149 | + const c = Utils.createDiv(['grid-stack-item-content'], e); |
| 150 | + if (w.content) c.textContent = w.content; |
| 151 | + return e; |
| 152 | + }; |
| 153 | + grid = makeGrid(); |
| 154 | + const under = grid.engine.nodes.find(n => n.id === 'under')!; |
| 155 | + grid.makeSubGrid(under.el!, undefined, {id: 'dropped', w: 2, h: 2, content: 'new'} as GridStackNode); |
| 156 | + expect(under.subGrid!.el.textContent).toContain('IMPORTANT'); |
| 157 | + }); |
| 158 | + |
| 159 | + it('gives the widget back when the temporary sub-grid is reverted', () => { |
| 160 | + grid = makeGrid(); |
| 161 | + const under = grid.engine.nodes.find(n => n.id === 'under')!; |
| 162 | + grid.makeSubGrid(under.el!, undefined, {id: 'dropped', w: 2, h: 2, content: 'new'} as GridStackNode); |
| 163 | + const sg = under.subGrid!; |
| 164 | + |
| 165 | + sg.removeAsSubGrid(); // what leaving the hover does for a temp sub-grid |
| 166 | + |
| 167 | + expect(grid.engine.nodes.length).toBeGreaterThan(0); |
| 168 | + expect(grid.el.textContent).toContain('IMPORTANT'); // not swallowed by the revert |
| 169 | + }); |
| 170 | + }); |
111 | 171 | }); |
0 commit comments