未验证 提交 9a9abcfd 编写于 作者: O owen-m1 提交者: GitHub

Add tests

上级 1279457e
version: 2.0
jobs:
build:
docker:
- image: circleci/node:10.16-browsers
steps:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
- v1-dependencies-
- run: npm install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
- run: npm run build:umd
- run: npm run test:compat
- run: npm run test
- store_test_results:
path: /tmp/test-results
......@@ -10,3 +10,6 @@ insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[*.yml]
indent_style = space
{
"speed": 0.4,
"reporter": {
"name": "xunit",
"output": "/tmp/test-results/res.xml"
}
}
# Sortable   [![DeepScan grade](https://deepscan.io/api/teams/3901/projects/5666/branches/43977/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=3901&pid=5666&bid=43977) [![](https://data.jsdelivr.com/v1/package/npm/sortablejs/badge)](https://www.jsdelivr.com/package/npm/sortablejs) [![npm](https://img.shields.io/npm/v/sortablejs.svg)](https://www.npmjs.com/package/sortablejs)
# Sortable   [![CircleCI](https://circleci.com/gh/SortableJS/Sortable.svg?style=svg)](https://circleci.com/gh/SortableJS/Sortable) [![DeepScan grade](https://deepscan.io/api/teams/3901/projects/5666/branches/43977/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=3901&pid=5666&bid=43977) [![](https://data.jsdelivr.com/v1/package/npm/sortablejs/badge)](https://www.jsdelivr.com/package/npm/sortablejs) [![npm](https://img.shields.io/npm/v/sortablejs.svg)](https://www.npmjs.com/package/sortablejs)
Sortable is a JavaScript library for reorderable drag-and-drop lists.
......@@ -284,7 +284,7 @@ Whether or not the delay should be applied only if the user is using touch (eg.
#### `swapThreshold` option
Percentage of the target that the swap zone will take up, as a float between `0` and `1`. This option has nothing to do with the `swap` option.
Percentage of the target that the swap zone will take up, as a float between `0` and `1`.
[Read more](https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#swap-threshold)
......@@ -295,7 +295,7 @@ Demo: http://sortablejs.github.io/Sortable#thresholds
#### `invertSwap` option
Set to `true` to set the swap zone to the sides of the target, for the effect of sorting "in between" items. This option has nothing to do with the `swap` option.
Set to `true` to set the swap zone to the sides of the target, for the effect of sorting "in between" items.
[Read more](https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#forcing-inverted-swap-zone)
......@@ -306,7 +306,7 @@ Demo: http://sortablejs.github.io/Sortable#thresholds
#### `invertedSwapThreshold` option
Percentage of the target that the inverted swap zone will take up, as a float between `0` and `1`. If not given, will default to `swapThreshold`. This option has nothing to do with the `swap` option.
Percentage of the target that the inverted swap zone will take up, as a float between `0` and `1`. If not given, will default to `swapThreshold`.
[Read more](https://github.com/SortableJS/Sortable/wiki/Swap-Thresholds-and-Direction#dealing-with-swap-glitching)
......@@ -694,7 +694,14 @@ The clone element.
---
##### Sortable.mount(plugin:`...SortablePlugin|...SortablePlugin[]`)
##### Sortable.get(element:`HTMLElement`):`Sortable`
Get the Sortable instance on an element.
---
##### Sortable.mount(plugin:`...SortablePlugin|SortablePlugin[]`)
Mounts a plugin to Sortable.
......
此差异已折叠。
......@@ -10,18 +10,23 @@
"rollup-plugin-babel": "^4.3.2",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.0.0",
"testcafe": "^1.3.1",
"testcafe-browser-provider-saucelabs": "^1.7.0",
"testcafe-reporter-xunit": "^2.1.0",
"uglify-js": "^3.5.12"
},
"description": "JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. No jQuery required. Supports Meteor, AngularJS, React, Polymer, Vue, Knockout and any CSS library, e.g. Bootstrap.",
"main": "./Sortable.js",
"module": "modular/sortable.esm.js",
"scripts": {
"build:umd": "set NODE_ENV=umd&& rollup -c build/umd-build.js",
"build:umd:watch": "set NODE_ENV=umd&& rollup -w -c build/umd-build.js",
"build:es": "set NODE_ENV=es&& rollup -c build/esm-build.js",
"build:es:watch": "set NODE_ENV=es&& rollup -w -c build/esm-build.js",
"minify": "node build/minify.js",
"build": "npm run build:es && npm run build:umd && npm run minify"
"build:umd": "NODE_ENV=umd rollup -c ./scripts/umd-build.js",
"build:umd:watch": "set NODE_ENV=umd&& rollup -w -c ./scripts/umd-build.js",
"build:es": "set NODE_ENV=es&& rollup -c ./scripts/esm-build.js",
"build:es:watch": "set NODE_ENV=es&& rollup -w -c ./scripts/esm-build.js",
"minify": "node ./scripts/minify.js",
"build": "npm run build:es && npm run build:umd && npm run minify",
"test:compat": "node ./scripts/test-compat.js",
"test": "node ./scripts/test.js"
},
"maintainers": [
"Konstantin Lebedev <ibnRubaXa@gmail.com>",
......
......@@ -95,8 +95,8 @@ function AutoScrollPlugin() {
},
_handleAutoScroll(evt, fallback) {
const x = evt.clientX,
y = evt.clientY,
const x = (evt.touches ? evt.touches[0] : evt).clientX,
y = (evt.touches ? evt.touches[0] : evt).clientY,
elem = document.elementFromPoint(x, y);
......@@ -164,7 +164,9 @@ function clearPointerElemChangedInterval() {
const autoScroll = throttle(function(evt, options, rootEl, isFallback) {
// Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
if (!options.scroll) return;
const sens = options.scrollSensitivity,
const x = (evt.touches ? evt.touches[0] : evt).clientX,
y = (evt.touches ? evt.touches[0] : evt).clientY,
sens = options.scrollSensitivity,
speed = options.scrollSpeed,
winScroller = getWindowScrollingElement();
......@@ -220,8 +222,8 @@ const autoScroll = throttle(function(evt, options, rootEl, isFallback) {
canScrollY = height < scrollHeight && (elCSS.overflowY === 'auto' || elCSS.overflowY === 'scroll');
}
let vx = canScrollX && (Math.abs(right - evt.clientX) <= sens && (scrollPosX + width) < scrollWidth) - (Math.abs(left - evt.clientX) <= sens && !!scrollPosX);
let vy = canScrollY && (Math.abs(bottom - evt.clientY) <= sens && (scrollPosY + height) < scrollHeight) - (Math.abs(top - evt.clientY) <= sens && !!scrollPosY);
let vx = canScrollX && (Math.abs(right - x) <= sens && (scrollPosX + width) < scrollWidth) - (Math.abs(left - x) <= sens && !!scrollPosX);
let vy = canScrollY && (Math.abs(bottom - y) <= sens && (scrollPosY + height) < scrollHeight) - (Math.abs(top - y) <= sens && !!scrollPosY);
if (!autoScrolls[layersOut]) {
......
const createTestCafe = require('testcafe');
// Testcafe cannot test on IE < 11
// Testcafe testing on Chrome Android is currently broken (https://github.com/DevExpress/testcafe/issues/3948)
const browsers = [
'saucelabs:Internet Explorer@11.285:Windows 10',
'saucelabs:MicrosoftEdge@16.16299:Windows 10',
'saucelabs:iPhone XS Simulator@12.2',
'saucelabs:Safari@12.0:macOS 10.14',
'chrome:headless',
'firefox:headless'
];
let testcafe;
let runner;
let failedCount;
createTestCafe(null, 8000, 8001).then((tc) => {
testcafe = tc;
runner = tc.createRunner();
return runner
.src('./tests/Sortable.compat.test.js')
.browsers(browsers)
.run();
}).then((actualFailedCount) => {
// https://testcafe-discuss.devexpress.com/t/why-circleci-marked-build-as-green-even-if-this-build-contain-failed-test/726/2
failedCount = actualFailedCount;
return testcafe.close();
}).then(() => process.exit(failedCount));
const createTestCafe = require('testcafe');
let testcafe;
let runner;
let failedCount;
createTestCafe().then((tc) => {
testcafe = tc;
runner = tc.createRunner();
return runner
.src('./tests/Sortable.test.js')
.browsers('chrome')
.concurrency(3)
.run();
}).then((actualFailedCount) => {
failedCount = actualFailedCount;
console.log('FAILED COUNT', actualFailedCount)
return testcafe.close();
}).then(() => process.exit(failedCount));
......@@ -178,7 +178,7 @@ let dragEl,
return elCSS.gridTemplateColumns.split(' ').length <= 1 ? 'vertical' : 'horizontal';
}
if (child1 && firstChildCSS.float !== 'none') {
if (child1 && firstChildCSS.float && firstChildCSS.float !== 'none') {
let touchingSideChild2 = firstChildCSS.float === 'left' ? 'left' : 'right';
return child2 && (secondChildCSS.clear === 'both' || secondChildCSS.clear === touchingSideChild2) ?
......@@ -1879,6 +1879,15 @@ Sortable.utils = {
};
/**
* Get the Sortable instance of an element
* @param {HTMLElement} element The element
* @return {Sortable|undefined} The instance of Sortable
*/
Sortable.get = function(element) {
return element[expando];
};
/**
* Mount a plugin to Sortable
* @param {...SortablePlugin|SortablePlugin[]} plugins Plugins being mounted
......
import { Selector } from 'testcafe';
fixture `Simple Sorting`
.page `./single-list.html`;
let list1 = Selector('#list1');
test('Sort down list', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list1.child(2);
const targetStartPosition = list1.child(2);
const target = await targetStartPosition();
const targetEndPosition = list1.child(1);
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target)
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
test('Sort up list', async browser => {
const dragStartPosition = list1.child(2);
const dragEl = await dragStartPosition();
const dragEndPosition = list1.child(0);
const targetStartPosition = list1.child(0);
const target = await targetStartPosition();
const targetEndPosition = list1.child(1);
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target)
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
import { Selector } from 'testcafe';
const itemHeight = 54; // px
const leeway = 1;
fixture `Simple Sorting`
.page `./single-list.html`;
let list1 = Selector('#list1');
test('Sort down list', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list1.child(2);
const targetStartPosition = list1.child(2);
const target = await targetStartPosition();
const targetEndPosition = list1.child(1);
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target)
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
test('Sort up list', async browser => {
const dragStartPosition = list1.child(2);
const dragEl = await dragStartPosition();
const dragEndPosition = list1.child(0);
const targetStartPosition = list1.child(0);
const target = await targetStartPosition();
const targetEndPosition = list1.child(1);
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target)
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
test('Swap threshold', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list1.child(1);
const targetStartPosition = list1.child(1);
const target = await targetStartPosition();
const targetEndPosition = list1.child(0);
await browser.eval(() => {
Sortable.get(document.getElementById('list1')).option('swapThreshold', 0.6);
});
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, {
destinationOffsetY: Math.round(itemHeight / 2 * 0.4 - leeway)
})
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, {
destinationOffsetY: Math.round(itemHeight / 2 * 0.4 + leeway)
})
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
test('Invert swap', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list1.child(1);
const targetStartPosition = list1.child(1);
const target = await targetStartPosition();
const targetEndPosition = list1.child(0);
await browser.eval(() => {
Sortable.get(document.getElementById('list1')).option('invertSwap', true);
});
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, {
destinationOffsetY: Math.round(itemHeight / 2 - leeway)
})
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, {
destinationOffsetY: Math.round(itemHeight / 2 + leeway)
})
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
test('Inverted swap threshold', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list1.child(1);
const targetStartPosition = list1.child(1);
const target = await targetStartPosition();
const targetEndPosition = list1.child(0);
await browser.eval(() => {
Sortable.get(document.getElementById('list1')).option('invertSwap', true);
Sortable.get(document.getElementById('list1')).option('invertedSwapThreshold', 0.5);
});
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, {
destinationOffsetY: Math.round(itemHeight - (itemHeight / 2 * 0.5) - leeway)
})
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, {
destinationOffsetY: Math.round(itemHeight - (itemHeight / 2 * 0.5) + leeway)
})
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
fixture `Grouping`
.page `./dual-list.html`;
let list2 = Selector('#list2');
test('Move to list of the same group', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list2.child(0);
const targetStartPosition = list2.child(0);
const target = await targetStartPosition();
const targetEndPosition = list2.child(1);
await browser.eval(() => {
Sortable.get(document.getElementById('list2')).option('group', 'shared');
});
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, { offsetY: 0, destinationOffsetY: 0 })
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
test('Do not move to list of different group', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const targetStartPosition = list2.child(0);
const target = await targetStartPosition();
await browser.eval(() => {
Sortable.get(document.getElementById('list2')).option('group', null);
});
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, { offsetY: 0, destinationOffsetY: 0 })
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText);
});
test('Move to list with put:true', async browser => {
// Should allow insert, since pull defaults to `true`
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list2.child(0);
const targetStartPosition = list2.child(0);
const target = await targetStartPosition();
const targetEndPosition = list2.child(1);
await browser.eval(() => {
Sortable.get(document.getElementById('list2')).option('group', { put: true });
});
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, { offsetY: 0, destinationOffsetY: 0 })
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
test('Do not move from list with pull:false', async browser => {
// Should not allow insert, since put defaults to `false`
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const targetStartPosition = list2.child(0);
const target = await targetStartPosition();
await browser.eval(() => {
Sortable.get(document.getElementById('list1')).option('group', { pull: false });
});
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, { offsetY: 0, destinationOffsetY: 0 })
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText);
});
test('Clone element if pull:"clone"', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list2.child(0);
const targetStartPosition = list2.child(0);
const target = await targetStartPosition();
const targetEndPosition = list2.child(1);
await browser.eval(() => {
Sortable.get(document.getElementById('list1')).option('group', { pull: 'clone' });
Sortable.get(document.getElementById('list2')).option('group', { put: true });
});
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, { offsetY: 0, destinationOffsetY: 0 })
.expect(dragStartPosition.innerText).eql(dragEl.innerText) // clone check
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
fixture `Handles`
.page `./handles.html`;
test('Do not allow dragging not using handle', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const targetStartPosition = list1.child(1);
const target = await targetStartPosition();
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target)
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText);
});
test('Allow dragging using handle', async browser => {
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list1.child(1);
const targetStartPosition = list1.child(1);
const target = await targetStartPosition();
const targetEndPosition = list1.child(0);
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(await dragStartPosition.child('.handle'), target)
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
fixture `Filter`
.page `./filter.html`;
test('Do not allow dragging of filtered element', async browser => {
const dragStartPosition = list1.child('.filtered');
const dragEl = await dragStartPosition();
const targetStartPosition = dragStartPosition.nextSibling(1);
const target = await targetStartPosition();
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target)
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText);
});
test('Allow dragging of non-filtered element', async browser => {
const dragStartPosition = list1.child(':not(.filtered)');
const dragEl = await dragStartPosition();
const dragEndPosition = dragStartPosition.nextSibling(1);
const targetStartPosition = dragStartPosition.nextSibling(1);
const target = await targetStartPosition();
const targetEndPosition = dragStartPosition.nextSibling(0);
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target)
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
fixture `Nested`
.page `./nested.html`;
let list1n1 = Selector('.n1');
let list1n2 = Selector('.n2');
let list2n1 = Selector('.n1:nth-of-type(2)');
test('Dragging from level 1 to level 0', async browser => {
const dragStartPosition = list1n1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list1.child(2);
const targetStartPosition = list1.child(2);
const target = await targetStartPosition();
const targetEndPosition = list1.child(3);
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, { destinationOffsetY: 0 })
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
test('Dragging from level 0 to level 2', async browser => {
const dragStartPosition = list1.child(1);
const dragEl = await dragStartPosition();
const dragEndPosition = list1n2.child(2);
const targetStartPosition = list1n2.child(2);
const target = await targetStartPosition();
const targetEndPosition = list1n2.child(3);
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.expect(targetStartPosition.innerText).eql(target.innerText)
.dragToElement(dragEl, target, { destinationOffsetY: 0 })
.expect(dragEndPosition.innerText).eql(dragEl.innerText)
.expect(targetEndPosition.innerText).eql(target.innerText);
});
fixture `Empty Insert`
.page `./empty-list.html`;
test('Insert into empty list if within emptyInsertThreshold', async browser => {
const threshold = await browser.eval(() => Sortable.get(document.getElementById('list2')).option('emptyInsertThreshold'));
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragEndPosition = list2.child(0);
// Must use rects since testcafe won't drag to element that is "not visible"
const dragRect = dragEl.boundingClientRect;
const list2Rect = await list2.boundingClientRect;
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.drag(dragEl, Math.round(list2Rect.left - dragRect.left) - (threshold - 1), -(threshold - 1), {
offsetY: 0,
offsetX: 0
})
.expect(dragEndPosition.innerText).eql(dragEl.innerText);
});
test('Do not insert into empty list if outside emptyInsertThreshold', async browser => {
const threshold = await browser.eval(() => Sortable.get(document.getElementById('list2')).option('emptyInsertThreshold'));
const dragStartPosition = list1.child(0);
const dragEl = await dragStartPosition();
const dragRect = dragEl.boundingClientRect;
const list2Rect = await list2.boundingClientRect;
await browser
.expect(dragStartPosition.innerText).eql(dragEl.innerText)
.drag(dragEl, Math.round(list2Rect.left - dragRect.left) - (threshold + 1), -(threshold + 1), {
offsetY: 0,
offsetX: 0
})
.expect(dragStartPosition.innerText).eql(dragEl.innerText);
});
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<div class="list half" id="list1">
<div>Item 1.1</div>
<div>Item 1.2</div>
<div>Item 1.3</div>
<div>Item 1.4</div>
<div>Item 1.5</div>
</div>
<div class="list half" id="list2">
<div>Item 2.1</div>
<div>Item 2.2</div>
<div>Item 2.3</div>
<div>Item 2.4</div>
<div>Item 2.5</div>
</div>
<script src="../Sortable.js"></script>
<script type="text/javascript">
new Sortable(document.getElementById('list1'), { group: 'shared' });
new Sortable(document.getElementById('list2'), { });
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<div class="list half" id="list1">
<div>Item 1.1</div>
<div>Item 1.2</div>
<div>Item 1.3</div>
<div>Item 1.4</div>
<div>Item 1.5</div>
</div>
<div class="list half" id="list2">
</div>
<script src="../Sortable.js"></script>
<script type="text/javascript">
new Sortable(document.getElementById('list1'), { group: 'shared' });
new Sortable(document.getElementById('list2'), { group: 'shared' });
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<div class="list" id="list1">
<div>Item 1.1</div>
<div>Item 1.2</div>
<div class="filtered">Item 1.3</div>
<div>Item 1.4</div>
<div>Item 1.5</div>
</div>
<script src="../Sortable.js"></script>
<script type="text/javascript">
new Sortable(document.getElementById('list1'), { filter: '.filtered' });
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<div class="list" id="list1">
<div><span class="handle">::</span>Item 1.1</div>
<div><span class="handle">::</span>Item 1.2</div>
<div><span class="handle">::</span>Item 1.3</div>
<div><span class="handle">::</span>Item 1.4</div>
<div><span class="handle">::</span>Item 1.5</div>
</div>
<script src="../Sortable.js"></script>
<script type="text/javascript">
new Sortable(document.getElementById('list1'), { handle: '.handle' });
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<div id="list1" class="list">
<div>Item 1.1
<div class="list n1">
<div>Item 2.1</div>
<div>Item 2.2
<div class="list n2">
<div>Item 3.1</div>
<div>Item 3.2</div>
<div>Item 3.3</div>
<div>Item 3.4</div>
</div>
</div>
<div>Item 2.3</div>
<div>Item 2.4</div>
</div>
</div>
<div>Item 1.2</div>
<div>Item 1.3</div>
<div>Item 1.4
<div class="list n1">
<div>Item 2.1</div>
<div>Item 2.2</div>
<div>Item 2.3</div>
<div>Item 2.4</div>
</div>
</div>
<div>Item 1.5</div>
</div>
<style>
.n1 > div {
background-color: lightblue;
}
.n2 > div {
background-color: lightgreen
}
.list {
padding: 50px;
}
</style>
<script src="../Sortable.js"></script>
<script type="text/javascript">
var elements = document.getElementsByClassName('list');
for (var i = 0; i < elements.length; i++) {
new Sortable(elements[i], {
group: 'shared',
invertSwap: true
});
}
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<div class="list" id="list1">
<div>Item 1.1</div>
<div>Item 1.2</div>
<div>Item 1.3</div>
<div>Item 1.4</div>
<div>Item 1.5</div>
</div>
<script src="../Sortable.js"></script>
<script type="text/javascript">
new Sortable(document.getElementById('list1'));
</script>
</body>
</html>
.list > div {
min-height: 50px;
border-style: solid;
border-width: 2px;
text-align: center;
line-height: 50px;
font-size: 20px;
font-family: Helvetica;
}
.half {
display: inline-block;
width: 49%;
padding: 0;
margin: 0;
vertical-align: top;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册