From aab6a124ed83e153e568a0ba4d90bd80f130efde Mon Sep 17 00:00:00 2001
From: Boris Sekachev <40690378+bsekachev@users.noreply.github.com>
Date: Wed, 7 Aug 2019 15:43:17 +0300
Subject: [PATCH] Integration of tslint static analyser for cvat-canvas (#624)
---
cvat-canvas/.eslintrc.js | 52 ------------------------
cvat-canvas/README.md | 18 ++++-----
cvat-canvas/dist/canvas.css | 20 ++++-----
cvat-canvas/dist/index.html | 16 --------
cvat-canvas/dist/index.js | 28 -------------
cvat-canvas/package.json | 3 +-
cvat-canvas/src/canvas.ts | 5 ++-
cvat-canvas/src/canvasController.ts | 3 +-
cvat-canvas/src/canvasModel.ts | 49 ++++++++++------------
cvat-canvas/src/canvasView.ts | 63 +++++++++++++++--------------
cvat-canvas/tslint.config.js | 34 ++++++++++++++++
11 files changed, 114 insertions(+), 177 deletions(-)
delete mode 100644 cvat-canvas/.eslintrc.js
delete mode 100644 cvat-canvas/dist/index.html
delete mode 100644 cvat-canvas/dist/index.js
create mode 100644 cvat-canvas/tslint.config.js
diff --git a/cvat-canvas/.eslintrc.js b/cvat-canvas/.eslintrc.js
deleted file mode 100644
index 9d123380..00000000
--- a/cvat-canvas/.eslintrc.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2018 Intel Corporation
- *
- * SPDX-License-Identifier: MIT
- */
-
- module.exports = {
- 'env': {
- 'node': true,
- 'browser': true,
- 'es6': true,
- },
- 'parserOptions': {
- 'parser': '@typescript-eslint/parser',
- 'sourceType': 'module',
- 'ecmaVersion': 6,
- },
- 'plugins': [
- 'security',
- 'no-unsanitized',
- 'no-unsafe-innerhtml',
- '@typescript-eslint',
- ],
- 'extends': [
- 'eslint:recommended',
- 'plugin:security/recommended',
- 'plugin:no-unsanitized/DOM',
- 'plugin:@typescript-eslint/recommended',
- 'airbnb',
- ],
- 'rules': {
- 'no-new': [0],
- 'class-methods-use-this': [0],
- 'no-plusplus': [0],
- 'no-restricted-syntax': [0, {'selector': 'ForOfStatement'}],
- 'no-continue': [0],
- 'security/detect-object-injection': 0,
- 'indent': ['warn', 4],
- 'no-useless-constructor': 0,
- 'func-names': [0],
- 'no-console': [0], // this rule deprecates console.log, console.warn etc. because 'it is not good in production code'
- '@typescript-eslint/no-explicit-any': [0],
- 'lines-between-class-members': [0],
- },
- 'settings': {
- 'import/resolver': {
- 'node': {
- 'extensions': ['.ts', '.js', '.json'],
- },
- },
- },
-};
diff --git a/cvat-canvas/README.md b/cvat-canvas/README.md
index 911aaaff..369effa2 100644
--- a/cvat-canvas/README.md
+++ b/cvat-canvas/README.md
@@ -68,15 +68,15 @@ All methods are sync.
### CSS Classes/IDs
-- Each drawn object (tag, shape, track) has id ```canvas_object_{objectState.id}```
-- Drawn shapes and tracks have classes ```canvas_shape```,
- ```canvas_shape_activated```,
- ```canvas_shape_grouping```,
- ```canvas_shape_merging```,
- ```canvas_shape_drawing```
-- Tags has a class ```canvas_tag```
-- Canvas image has ID ```canvas_image```
-- Grid on the canvas has ID ```canvas_grid_pattern```
+- Each drawn object (tag, shape, track) has id ```cvat_canvas_object_{objectState.id}```
+- Drawn shapes and tracks have classes ```cvat_canvas_shape```,
+ ```cvat_canvas_shape_activated```,
+ ```cvat_canvas_shape_grouping```,
+ ```cvat_canvas_shape_merging```,
+ ```cvat_canvas_shape_drawing```
+- Tags has a class ```cvat_canvas_tag```
+- Canvas image has ID ```cvat_canvas_image```
+- Grid on the canvas has ID ```cvat_canvas_grid_pattern```
### Events
diff --git a/cvat-canvas/dist/canvas.css b/cvat-canvas/dist/canvas.css
index db6093c4..cdb35074 100644
--- a/cvat-canvas/dist/canvas.css
+++ b/cvat-canvas/dist/canvas.css
@@ -1,8 +1,8 @@
-.canvas_hidden {
+.cvat_canvas_hidden {
display: none;
}
-#canvas_wrapper {
+#cvat_canvas_wrapper {
width: 100%;
height: 80%;
border: 1px black solid;
@@ -12,13 +12,13 @@
position: relative;
}
-#canvas_rotation_wrapper {
+#cvat_canvas_rotation_wrapper {
width: 100%;
height: 100%;
position: relative;
}
-#canvas_loading_animation {
+#cvat_canvas_loading_animation {
z-index: 1;
position: absolute;
width: 100%;
@@ -26,7 +26,7 @@
transform-origin: top left;
}
-#canvas_loading_circle {
+#cvat_canvas_loading_circle {
fill-opacity: 0;
stroke: #09c;
stroke-width: 3px;
@@ -34,7 +34,7 @@
animation: loadingAnimation 1s linear infinite;
}
-#canvas_text_content {
+#cvat_canvas_text_content {
position: absolute;
z-index: 3;
transform-origin: center center;
@@ -43,7 +43,7 @@
height: 100%;
}
-#canvas_background {
+#cvat_canvas_background {
position: absolute;
z-index: 0;
background-repeat: no-repeat;
@@ -52,7 +52,7 @@
height: 100%;
}
-#canvas_grid {
+#cvat_canvas_grid {
position: absolute;
z-index: 2;
transform-origin: top left;
@@ -61,12 +61,12 @@
height: 100%;
}
-#canvas_grid_pattern {
+#cvat_canvas_grid_pattern {
opacity: 1;
stroke: white;
}
-#canvas_content {
+#cvat_canvas_content {
position: absolute;
z-index: 2;
outline: 10px solid black;
diff --git a/cvat-canvas/dist/index.html b/cvat-canvas/dist/index.html
deleted file mode 100644
index ac996e9d..00000000
--- a/cvat-canvas/dist/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- CVAT-CANVAS Dev Server
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/cvat-canvas/dist/index.js b/cvat-canvas/dist/index.js
deleted file mode 100644
index b13d7c6d..00000000
--- a/cvat-canvas/dist/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-window.addEventListener('DOMContentLoaded', async () => {
- await window.cvat.server.login('admin', 'nimda760');
- const [job] = (await window.cvat.jobs.get({ jobID: 21 }));
- const canvas = new window.canvas.Canvas();
- const htmlContainer = window.document.getElementById('htmlContainer');
-
-
- htmlContainer.appendChild(canvas.html());
-
- let frame = 0;
- const callback = async () => {
- canvas.fit();
- const frameData = await job.frames.get(frame);
- canvas.setup(frameData, []);
- frame += 1;
-
- if (frame > 50) {
- frame = 0;
- }
- };
-
- canvas.html().addEventListener('canvas.setup', async () => {
- setTimeout(callback, 30);
- });
-
- const frameData = await job.frames.get(frame);
- canvas.setup(frameData, []);
-});
diff --git a/cvat-canvas/package.json b/cvat-canvas/package.json
index e6b980f3..99838df5 100644
--- a/cvat-canvas/package.json
+++ b/cvat-canvas/package.json
@@ -21,8 +21,9 @@
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"babel-loader": "^8.0.6",
- "eslint": "^6.1.0",
"nodemon": "^1.19.1",
+ "tslint": "^5.18.0",
+ "tslint-config-airbnb": "^5.11.1",
"typescript": "^3.5.3",
"webpack": "^4.36.1",
"webpack-cli": "^3.3.6",
diff --git a/cvat-canvas/src/canvas.ts b/cvat-canvas/src/canvas.ts
index f2d47abe..f48f0155 100644
--- a/cvat-canvas/src/canvas.ts
+++ b/cvat-canvas/src/canvas.ts
@@ -3,8 +3,8 @@
* SPDX-License-Identifier: MIT
*/
-import { CanvasModel, CanvasModelImpl, Rotation } from './canvasModel';
import { CanvasController, CanvasControllerImpl } from './canvasController';
+import { CanvasModel, CanvasModelImpl, Rotation } from './canvasModel';
import { CanvasView, CanvasViewImpl } from './canvasView';
interface Canvas {
@@ -63,7 +63,8 @@ class CanvasImpl implements Canvas {
this.model.grid(stepX, stepY);
}
- public draw(enabled: boolean = false, shapeType: string = '', numberOfPoints: number = 0, initialState: any = null): any {
+ public draw(enabled: boolean = false, shapeType: string = '',
+ numberOfPoints: number = 0, initialState: any = null): any {
return this.model.draw(enabled, shapeType, numberOfPoints, initialState);
}
diff --git a/cvat-canvas/src/canvasController.ts b/cvat-canvas/src/canvasController.ts
index 4e2d9892..3c4db0a5 100644
--- a/cvat-canvas/src/canvasController.ts
+++ b/cvat-canvas/src/canvasController.ts
@@ -6,11 +6,10 @@
import {
CanvasModel,
Geometry,
- Size,
Position,
+ Size,
} from './canvasModel';
-
export interface CanvasController {
readonly geometry: Geometry;
canvasSize: Size;
diff --git a/cvat-canvas/src/canvasModel.ts b/cvat-canvas/src/canvasModel.ts
index 05eda925..cf24e06e 100644
--- a/cvat-canvas/src/canvasModel.ts
+++ b/cvat-canvas/src/canvasModel.ts
@@ -80,19 +80,19 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
super();
this.data = {
+ canvasSize: {
+ height: 0,
+ width: 0,
+ },
image: '',
+ imageOffset: 0,
imageSize: {
- width: 0,
height: 0,
- },
- canvasSize: {
width: 0,
- height: 0,
},
- imageOffset: 0,
+ left: 0,
scale: 1,
top: 0,
- left: 0,
};
}
@@ -112,7 +112,6 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
this.notify(UpdateReasons.MOVE);
}
-
public setup(frameData: any, objectStates: any[]): void {
frameData.data(
(): void => {
@@ -121,8 +120,8 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
},
).then((data: string): void => {
this.data.imageSize = {
- width: (frameData.width as number),
height: (frameData.height as number),
+ width: (frameData.width as number),
};
this.data.image = data;
@@ -170,12 +169,12 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
}
public draw(enabled: boolean, shapeType: string,
- numberOfPoints: number, initialState: any): any {
+ numberOfPoints: number, initialState: any): any {
return {
enabled,
- shapeType,
- numberOfPoints,
initialState,
+ numberOfPoints,
+ shapeType,
};
}
@@ -192,23 +191,23 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
}
public cancel(): void {
-
+ console.log('hello');
}
public get geometry(): Geometry {
return {
- image: {
- width: this.data.imageSize.width,
- height: this.data.imageSize.height,
- },
canvas: {
- width: this.data.canvasSize.width,
height: this.data.canvasSize.height,
+ width: this.data.canvasSize.width,
+ },
+ image: {
+ height: this.data.imageSize.height,
+ width: this.data.imageSize.width,
},
- top: this.data.top,
left: this.data.left,
- scale: this.data.scale,
offset: this.data.imageOffset,
+ scale: this.data.scale,
+ top: this.data.top,
};
}
@@ -218,22 +217,22 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
public set imageSize(value: Size) {
this.data.imageSize = {
- width: value.width,
height: value.height,
+ width: value.width,
};
}
public get imageSize(): Size {
return {
- width: this.data.imageSize.width,
height: this.data.imageSize.height,
+ width: this.data.imageSize.width,
};
}
public set canvasSize(value: Size) {
this.data.canvasSize = {
- width: value.width,
height: value.height,
+ width: value.width,
};
this.data.imageOffset = Math.floor(Math.max(
@@ -244,12 +243,8 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
public get canvasSize(): Size {
return {
- width: this.data.canvasSize.width,
height: this.data.canvasSize.height,
+ width: this.data.canvasSize.width,
};
}
}
-
-// TODO List:
-// 2) Rotate image
-// 3) Draw objects
diff --git a/cvat-canvas/src/canvasView.ts b/cvat-canvas/src/canvasView.ts
index dc7d3c80..2dd82b30 100644
--- a/cvat-canvas/src/canvasView.ts
+++ b/cvat-canvas/src/canvasView.ts
@@ -3,9 +3,9 @@
* SPDX-License-Identifier: MIT
*/
-import { CanvasModel, UpdateReasons, Geometry } from './canvasModel';
-import { Listener, Master } from './master';
import { CanvasController } from './canvasController';
+import { CanvasModel, Geometry, UpdateReasons } from './canvasModel';
+import { Listener, Master } from './master';
export interface CanvasView {
html(): HTMLDivElement;
@@ -15,7 +15,6 @@ interface HTMLAttribute {
[index: string]: string;
}
-
function translateToSVG(svg: SVGSVGElement, points: number[]): number[] {
const output = [];
const transformationMatrix = svg.getScreenCTM().inverse();
@@ -59,7 +58,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.controller = controller;
// Create HTML elements
- this.loadingAnimation = window.document.createElementNS('http://www.w3.org/2000/svg', 'svg');
+ this.loadingAnimation = window.document
+ .createElementNS('http://www.w3.org/2000/svg', 'svg');
this.text = window.document.createElementNS('http://www.w3.org/2000/svg', 'svg');
this.background = window.document.createElementNS('http://www.w3.org/2000/svg', 'svg');
@@ -70,41 +70,44 @@ export class CanvasViewImpl implements CanvasView, Listener {
this.rotationWrapper = window.document.createElement('div');
this.canvas = window.document.createElement('div');
- const loadingCircle: SVGCircleElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'circle');
- const gridDefs: SVGDefsElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'defs');
- const gridPattern: SVGPatternElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'pattern');
- const gridRect: SVGRectElement = window.document.createElementNS('http://www.w3.org/2000/svg', 'rect');
+ const loadingCircle: SVGCircleElement = window.document
+ .createElementNS('http://www.w3.org/2000/svg', 'circle');
+ const gridDefs: SVGDefsElement = window.document
+ .createElementNS('http://www.w3.org/2000/svg', 'defs');
+ const gridPattern: SVGPatternElement = window.document
+ .createElementNS('http://www.w3.org/2000/svg', 'pattern');
+ const gridRect: SVGRectElement = window.document
+ .createElementNS('http://www.w3.org/2000/svg', 'rect');
// Setup loading animation
- this.loadingAnimation.setAttribute('id', 'canvas_loading_animation');
- loadingCircle.setAttribute('id', 'canvas_loading_circle');
+ this.loadingAnimation.setAttribute('id', 'cvat_canvas_loading_animation');
+ loadingCircle.setAttribute('id', 'cvat_canvas_loading_circle');
loadingCircle.setAttribute('r', '30');
loadingCircle.setAttribute('cx', '50%');
loadingCircle.setAttribute('cy', '50%');
// Setup grid
- this.grid.setAttribute('id', 'canvas_grid');
+ this.grid.setAttribute('id', 'cvat_canvas_grid');
this.grid.setAttribute('version', '2');
this.gridPath.setAttribute('d', 'M 1000 0 L 0 0 0 1000');
this.gridPath.setAttribute('fill', 'none');
this.gridPath.setAttribute('stroke-width', '1.5');
- gridPattern.setAttribute('id', 'canvas_grid_pattern');
+ gridPattern.setAttribute('id', 'cvat_canvas_grid_pattern');
gridPattern.setAttribute('width', '100');
gridPattern.setAttribute('height', '100');
gridPattern.setAttribute('patternUnits', 'userSpaceOnUse');
gridRect.setAttribute('width', '100%');
gridRect.setAttribute('height', '100%');
- gridRect.setAttribute('fill', 'url(#canvas_grid_pattern)');
-
+ gridRect.setAttribute('fill', 'url(#cvat_canvas_grid_pattern)');
// Setup content
- this.text.setAttribute('id', 'canvas_text_content');
- this.background.setAttribute('id', 'canvas_background');
- this.content.setAttribute('id', 'canvas_content');
+ this.text.setAttribute('id', 'cvat_canvas_text_content');
+ this.background.setAttribute('id', 'cvat_canvas_background');
+ this.content.setAttribute('id', 'cvat_canvas_content');
// Setup wrappers
- this.rotationWrapper.setAttribute('id', 'canvas_rotation_wrapper');
- this.canvas.setAttribute('id', 'canvas_wrapper');
+ this.rotationWrapper.setAttribute('id', 'cvat_canvas_rotation_wrapper');
+ this.canvas.setAttribute('id', 'cvat_canvas_wrapper');
// Unite created HTML elements together
this.loadingAnimation.appendChild(loadingCircle);
@@ -128,8 +131,8 @@ export class CanvasViewImpl implements CanvasView, Listener {
const canvasFirstMounted = (event: AnimationEvent): void => {
if (event.animationName === 'loadingAnimation') {
self.controller.canvasSize = {
- width: self.rotationWrapper.clientWidth,
height: self.rotationWrapper.clientHeight,
+ width: self.rotationWrapper.clientWidth,
};
self.rotationWrapper.removeEventListener('animationstart', canvasFirstMounted);
@@ -171,25 +174,25 @@ export class CanvasViewImpl implements CanvasView, Listener {
function resize(geometry: Geometry): void {
for (const obj of [this.background, this.grid, this.loadingAnimation]) {
- obj.style.width = `${geometry.image.width}`;
- obj.style.height = `${geometry.image.height}`;
+ obj.style.width = `${geometry.image.width}px`;
+ obj.style.height = `${geometry.image.height}px`;
}
for (const obj of [this.content, this.text]) {
- obj.style.width = `${geometry.image.width + geometry.offset * 2}`;
- obj.style.height = `${geometry.image.height + geometry.offset * 2}`;
+ obj.style.width = `${geometry.image.width + geometry.offset * 2}px`;
+ obj.style.height = `${geometry.image.height + geometry.offset * 2}px`;
}
}
function move(geometry: Geometry): void {
for (const obj of [this.background, this.grid, this.loadingAnimation]) {
- obj.style.top = `${geometry.top}`;
- obj.style.left = `${geometry.left}`;
+ obj.style.top = `${geometry.top}px`;
+ obj.style.left = `${geometry.left}px`;
}
for (const obj of [this.content, this.text]) {
- obj.style.top = `${geometry.top - geometry.offset * geometry.scale}`;
- obj.style.left = `${geometry.left - geometry.offset * geometry.scale}`;
+ obj.style.top = `${geometry.top - geometry.offset * geometry.scale}px`;
+ obj.style.left = `${geometry.left - geometry.offset * geometry.scale}px`;
}
this.content.style.transform = `scale(${geometry.scale})`;
@@ -198,9 +201,9 @@ export class CanvasViewImpl implements CanvasView, Listener {
const { geometry } = this.controller;
if (reason === UpdateReasons.IMAGE) {
if (!model.image.length) {
- this.loadingAnimation.classList.remove('canvas_hidden');
+ this.loadingAnimation.classList.remove('cvat_canvas_hidden');
} else {
- this.loadingAnimation.classList.add('canvas_hidden');
+ this.loadingAnimation.classList.add('cvat_canvas_hidden');
this.background.style.backgroundImage = `url("${model.image}")`;
move.call(this, geometry);
resize.call(this, geometry);
diff --git a/cvat-canvas/tslint.config.js b/cvat-canvas/tslint.config.js
new file mode 100644
index 00000000..c237ed26
--- /dev/null
+++ b/cvat-canvas/tslint.config.js
@@ -0,0 +1,34 @@
+/*
+* Copyright (C) 2018 Intel Corporation
+* SPDX-License-Identifier: MIT
+*/
+
+/* eslint-disable */
+
+module.exports = {
+ defaultSeverity: 'error',
+ extends: [
+ 'tslint:recommended',
+ 'tslint-config-airbnb'
+ ],
+ jsRules: {},
+ rulesDirectory: [],
+ rules: {
+ 'ter-indent': ['warn', 4],
+ // TypeScript guildline prevents interfaces names started with I
+ // https://github.com/Microsoft/TypeScript/wiki/Coding-guidelines#names
+ 'interface-name': false,
+ 'no-console': false,
+ // Arrow functions doesn't use closure context, but sometimes we need it
+ // At the same time typescript non-arrow functions are forbidden in TS
+ // So, we forced to disable this rule
+ 'no-this-assignment': false,
+ // Just a strange rule
+ 'no-shadowed-variable': false,
+ // Don't prevent ++ and -- operations (the same like in eslint)
+ 'no-increment-decrement': false,
+ },
+ linterOptions: {
+ include: ['src/*.ts']
+ }
+}