diff --git a/src/Sortable.js b/src/Sortable.js index 72f571c82..9ffc05052 100644 --- a/src/Sortable.js +++ b/src/Sortable.js @@ -161,8 +161,24 @@ let dragEl, })(), _detectDirection = function(el, options) { - let elCSS = css(el), - elWidth = parseInt(elCSS.width) + let layoutEl = el, + elCSS = css(layoutEl); + + // #1853: display:contents generates no box; use the layout-generating ancestor + while (elCSS && elCSS.display === 'contents') { + let parent = layoutEl.assignedSlot || layoutEl.parentElement; + if (!parent && layoutEl.getRootNode) { + const root = layoutEl.getRootNode(); + if (root && root.host) parent = root.host; + } + if (!parent || parent === layoutEl || parent.nodeType !== 1) break; + const parentCSS = css(parent); + if (!parentCSS) break; + layoutEl = parent; + elCSS = parentCSS; + } + + let elWidth = parseInt(elCSS.width) - parseInt(elCSS.paddingLeft) - parseInt(elCSS.paddingRight) - parseInt(elCSS.borderLeftWidth) @@ -174,12 +190,12 @@ let dragEl, firstChildWidth = firstChildCSS && parseInt(firstChildCSS.marginLeft) + parseInt(firstChildCSS.marginRight) + getRect(child1).width, secondChildWidth = secondChildCSS && parseInt(secondChildCSS.marginLeft) + parseInt(secondChildCSS.marginRight) + getRect(child2).width; - if (elCSS.display === 'flex') { + if (elCSS.display === 'flex' || elCSS.display === 'inline-flex') { return elCSS.flexDirection === 'column' || elCSS.flexDirection === 'column-reverse' ? 'vertical' : 'horizontal'; } - if (elCSS.display === 'grid') { + if (elCSS.display === 'grid' || elCSS.display === 'inline-grid') { return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal'; } diff --git a/tests/Sortable.test.js b/tests/Sortable.test.js index 59ce11f46..b0d08e151 100644 --- a/tests/Sortable.test.js +++ b/tests/Sortable.test.js @@ -384,3 +384,49 @@ test('Do not insert into empty list if outside emptyInsertThreshold', async brow }) .expect(dragStartPosition.innerText).eql(dragEl.innerText); }); + + +fixture `Display contents grid` + .page `./display-contents-grid.html`; + +const contentsList = Selector('#list-contents'); + +test('Detect horizontal direction for display:contents inside a multi-column grid', async browser => { + const directions = await browser.eval(() => { + const opts = { draggable: '>*' }; + return { + grid: Sortable.utils.detectDirection(document.getElementById('list-contents'), opts), + flexRow: Sortable.utils.detectDirection(document.getElementById('flex-row-inner'), opts), + flexCol: Sortable.utils.detectDirection(document.getElementById('flex-col-inner'), opts), + block: Sortable.utils.detectDirection(document.getElementById('block-inner'), opts), + nested: Sortable.utils.detectDirection(document.getElementById('nested-inner'), opts), + grid1Col: Sortable.utils.detectDirection(document.getElementById('grid-1col-inner'), opts), + inlineGrid: Sortable.utils.detectDirection(document.getElementById('inline-grid-inner'), opts) + }; + }); + + await browser.expect(directions.grid).eql('horizontal'); + await browser.expect(directions.flexRow).eql('horizontal'); + await browser.expect(directions.flexCol).eql('vertical'); + await browser.expect(directions.block).eql('vertical'); + await browser.expect(directions.nested).eql('horizontal'); + await browser.expect(directions.grid1Col).eql('vertical'); + await browser.expect(directions.inlineGrid).eql('horizontal'); +}); + +test('Sort across an incomplete display:contents grid row', async browser => { + const dragStartPosition = contentsList.child(0); + const dragEl = await dragStartPosition(); + const targetStartPosition = contentsList.child(2); + const target = await targetStartPosition(); + + await browser + .expect(dragStartPosition.innerText).eql(dragEl.innerText) + .expect(targetStartPosition.innerText).eql(target.innerText) + .dragToElement(dragEl, target) + .expect(contentsList.child(0).innerText).eql('Item 2') + .expect(contentsList.child(1).innerText).eql('Item 3') + .expect(contentsList.child(2).innerText).eql('Item 1') + .expect(contentsList.child(3).innerText).eql('Item 4') + .expect(contentsList.child(4).innerText).eql('Item 5'); +}); diff --git a/tests/display-contents-grid.html b/tests/display-contents-grid.html new file mode 100644 index 000000000..a558b9521 --- /dev/null +++ b/tests/display-contents-grid.html @@ -0,0 +1,137 @@ + + +
+