Skip to content

Commit e923d88

Browse files
fix(core): Prevent removal of elements during drag and drop
This addresses a reported issue where elements were being fully removed from the DOM during drag and drop operations. fixes: #67257 (cherry picked from commit 0b59cba)
1 parent 150f0b3 commit e923d88

34 files changed

Lines changed: 7276 additions & 6 deletions
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Editor configuration, see https://editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
indent_style = space
7+
indent_size = 2
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
max_line_length = off
13+
trim_trailing_whitespace = false

integration/animations/.gitignore

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# See https://help.github.com/ignore-files/ for more about ignoring files.
2+
3+
# compiled output
4+
/dist
5+
/tmp
6+
/out-tsc
7+
# Only exists if Bazel was run
8+
/bazel-out
9+
10+
# dependencies
11+
/node_modules
12+
13+
# profiling files
14+
chrome-profiler-events*.json
15+
speed-measure-plugin*.json
16+
17+
# IDEs and editors
18+
/.idea
19+
.project
20+
.classpath
21+
.c9/
22+
*.launch
23+
.settings/
24+
*.sublime-workspace
25+
26+
# IDE - VSCode
27+
.vscode/*
28+
!.vscode/settings.json
29+
!.vscode/tasks.json
30+
!.vscode/launch.json
31+
!.vscode/extensions.json
32+
.history/*
33+
34+
# misc
35+
/.sass-cache
36+
/connect.lock
37+
/coverage
38+
/libpeerconnection.log
39+
npm-debug.log
40+
yarn-error.log
41+
testem.log
42+
/typings
43+
44+
# System Files
45+
.DS_Store
46+
Thumbs.db

integration/animations/BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
load("//integration:index.bzl", "ng_integration_test")
2+
3+
ng_integration_test(
4+
name = "test",
5+
setup_chromium = True,
6+
)

integration/animations/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# CoreAnimationsE2E
2+
3+
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.0.0-next.9.
4+
5+
## Development server
6+
7+
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
8+
9+
## Code scaffolding
10+
11+
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12+
13+
## Build
14+
15+
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
16+
17+
## Running unit tests
18+
19+
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20+
21+
## Running end-to-end tests
22+
23+
Run `ng e2e` to execute the end-to-end tests via [Protractor](https://www.protractortest.org/).
24+
25+
## Further help
26+
27+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/main/README.md).
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
{
2+
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3+
"version": 1,
4+
"newProjectRoot": "projects",
5+
"projects": {
6+
"core-animations-e2e": {
7+
"projectType": "application",
8+
"schematics": {},
9+
"root": "",
10+
"sourceRoot": "src",
11+
"prefix": "app",
12+
"architect": {
13+
"build": {
14+
"builder": "@angular/build:application",
15+
"options": {
16+
"outputHashing": "none",
17+
"outputPath": {
18+
"base": "dist",
19+
"browser": ""
20+
},
21+
"index": "src/index.html",
22+
"polyfills": ["zone.js"],
23+
"tsConfig": "tsconfig.app.json",
24+
"aot": true,
25+
"assets": ["src/favicon.ico", "src/assets"],
26+
"styles": ["src/styles.css"],
27+
"scripts": [],
28+
"optimization": false,
29+
"progress": false,
30+
"browser": "src/main.ts"
31+
},
32+
"configurations": {
33+
"production": {
34+
"optimization": true,
35+
"outputHashing": "none",
36+
"sourceMap": false,
37+
"namedChunks": false,
38+
"extractLicenses": true,
39+
"budgets": [
40+
{
41+
"type": "initial",
42+
"maximumWarning": "2mb",
43+
"maximumError": "5mb"
44+
},
45+
{
46+
"type": "anyComponentStyle",
47+
"maximumWarning": "6kb",
48+
"maximumError": "10kb"
49+
}
50+
]
51+
}
52+
}
53+
},
54+
"serve": {
55+
"builder": "@angular/build:dev-server",
56+
"options": {
57+
"buildTarget": "core-animations-e2e:build"
58+
},
59+
"configurations": {
60+
"dev": {
61+
"buildTarget": "core-animations-e2e:build:dev"
62+
},
63+
"production": {
64+
"buildTarget": "core-animations-e2e:build:production"
65+
},
66+
"ci": {},
67+
"ci-production": {
68+
"buildTarget": "core-animations-e2e:build:production"
69+
}
70+
}
71+
},
72+
"extract-i18n": {
73+
"builder": "@angular/build:extract-i18n",
74+
"options": {
75+
"buildTarget": "core-animations-e2e:build"
76+
}
77+
},
78+
"test": {
79+
"builder": "@angular-devkit/build-angular:karma",
80+
"options": {
81+
"polyfills": ["zone.js", "zone.js/testing"],
82+
"tsConfig": "tsconfig.spec.json",
83+
"karmaConfig": "karma.conf.js",
84+
"assets": ["src/favicon.ico", "src/assets"],
85+
"styles": ["src/styles.css"],
86+
"scripts": [],
87+
"progress": false,
88+
"watch": false
89+
}
90+
},
91+
"lint": {
92+
"builder": "@angular/build:tslint",
93+
"options": {
94+
"tsConfig": ["tsconfig.app.json", "tsconfig.spec.json", "e2e/tsconfig.json"],
95+
"exclude": ["**/node_modules/**"]
96+
}
97+
}
98+
}
99+
}
100+
},
101+
"cli": {
102+
"cache": {
103+
"enabled": false
104+
},
105+
"analytics": false
106+
}
107+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"spec_dir": "e2e",
3+
"spec_files": ["src/**/*spec.ts"],
4+
"helpers": ["setup.js"],
5+
"stopSpecOnExpectationFailure": false,
6+
"random": false
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const path = require('path');
2+
const tsNode = require('ts-node');
3+
4+
tsNode.register({
5+
project: path.join(__dirname, 'tsconfig.json'),
6+
});
7+
8+
jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import puppeteer, {Browser, Page} from 'puppeteer';
2+
3+
describe('Animations Integration', () => {
4+
let browser: Browser;
5+
let page: Page;
6+
7+
beforeAll(async () => {
8+
browser = await puppeteer.launch({
9+
headless: false, // watch it run in the browser
10+
executablePath: process.env.CHROME_BIN,
11+
args: ['--no-sandbox', '--disable-gpu'],
12+
});
13+
});
14+
15+
afterAll(async () => {
16+
if (browser) {
17+
await browser.close();
18+
}
19+
});
20+
21+
beforeEach(async () => {
22+
page = await browser.newPage();
23+
// Use a retry loop to wait for ng serve to be fully ready
24+
for (let i = 0; i < 10; i++) {
25+
try {
26+
await page.goto('http://localhost:4208/');
27+
break;
28+
} catch (e) {
29+
if (i === 9) throw e;
30+
await new Promise((res) => setTimeout(res, 2000));
31+
}
32+
}
33+
});
34+
35+
afterEach(async () => {
36+
if (page) {
37+
await page.close();
38+
}
39+
});
40+
41+
it('should not disappear items when rearranged', async () => {
42+
// Wait for the elements to be rendered
43+
await page.waitForSelector('.example-box');
44+
45+
const boxes = await page.$$('.example-box');
46+
expect(boxes.length).toBe(3);
47+
48+
// Get the bounding boxes of the first and last elements
49+
const firstBox = await boxes[0]!.boundingBox();
50+
const lastBox = await boxes[2]!.boundingBox();
51+
52+
if (!firstBox || !lastBox) {
53+
throw new Error('Could not find bounding boxes for elements.');
54+
}
55+
56+
// Perform drag and drop
57+
await page.mouse.move(firstBox.x + firstBox.width / 2, firstBox.y + firstBox.height / 2);
58+
await page.mouse.down();
59+
60+
// Smoothly drag it down to the last position
61+
await page.mouse.move(lastBox.x + lastBox.width / 2, lastBox.y + lastBox.height / 2 + 20, {
62+
steps: 50,
63+
});
64+
65+
// Drop
66+
await page.mouse.up();
67+
68+
// Wait for animations to finish (2000ms + some buffer)
69+
await new Promise((res) => setTimeout(res, 3000));
70+
71+
// Check that we still have 3 items
72+
const finalBoxes = await page.$$('.example-box');
73+
expect(finalBoxes.length).toBe(3);
74+
});
75+
});
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* To learn more about this file see: https://angular.io/guide/typescript-configuration. */
2+
{
3+
"extends": "../tsconfig.json",
4+
"compilerOptions": {
5+
"outDir": "../out-tsc/e2e",
6+
"module": "commonjs",
7+
"moduleResolution": "node",
8+
"target": "ES2022",
9+
"types": ["jasmine", "node"]
10+
}
11+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Karma configuration file, see link for more information
2+
// https://karma-runner.github.io/1.0/config/configuration-file.html
3+
4+
module.exports = function (config) {
5+
config.set({
6+
basePath: '',
7+
frameworks: ['jasmine', '@angular-devkit/build-angular'],
8+
plugins: [
9+
require('karma-jasmine'),
10+
require('karma-chrome-launcher'),
11+
require('karma-jasmine-html-reporter'),
12+
require('@angular-devkit/build-angular/plugins/karma'),
13+
],
14+
client: {
15+
clearContext: false, // leave Jasmine Spec Runner output visible in browser
16+
},
17+
reporters: ['progress', 'kjhtml'],
18+
port: 9876,
19+
colors: true,
20+
logLevel: config.LOG_INFO,
21+
autoWatch: true,
22+
customLaunchers: {
23+
ChromeHeadlessNoSandbox: {
24+
base: 'ChromeHeadless',
25+
// See /integration/README.md#browser-tests for more info on these args
26+
flags: [
27+
'--no-sandbox',
28+
'--headless',
29+
'--disable-gpu',
30+
'--disable-dev-shm-usage',
31+
'--hide-scrollbars',
32+
'--mute-audio',
33+
],
34+
},
35+
},
36+
browsers: ['ChromeHeadlessNoSandbox'],
37+
singleRun: false,
38+
restartOnFileChange: true,
39+
});
40+
};

0 commit comments

Comments
 (0)