Skip to content

Commit

Permalink
добавлен TypeScript
Browse files Browse the repository at this point in the history
  • Loading branch information
Geksanit committed Jan 11, 2018
1 parent 0f9f2c0 commit 3902508
Show file tree
Hide file tree
Showing 15 changed files with 447 additions and 341 deletions.
565 changes: 300 additions & 265 deletions build/index.js

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions frontend/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import './index.styl';
import './favicons/favicons';
import './components/slider/slider';
import './components/standart-button/standart-button';
import Controller from './mvc/controller/Controller.ts';

const controller = new Controller();
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* global assert sinon */
import Controller from './Controller';
/* global assert */
import Controller from './Controller.ts';

describe('контроллер', () => {
let div;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import Model from '../model/Model';
import View from '../view/View';

class Controller {
model: Model;
view: View;
running: boolean;
fps: number;
constructor() {
this.model = new Model(10, 10);
this.view = new View();
Expand All @@ -11,7 +15,7 @@ class Controller {
this.view.initTable(this.model.matrix);// начальная отрисовка
this.setRunning(false);
}
setSubscription() {
setSubscription():void {
this.model.matrixChanged.attach((sender, obj) => {
if (obj.resized) this.view.initTable(obj.matrix);
else this.view.changeTable(obj.matrix);
Expand All @@ -26,19 +30,19 @@ class Controller {
this.handlerSliders(event);
});
}
setRunning(value) {
setRunning(value: boolean): void {
this.running = value;
this.view.setButtons(this.running);
this.view.setStatus(this.running);
}
anim(callback) {
anim(callback?): void {
// останавливается и вызывет аргумент callback(для тестов), когда матрица перестает меняться
const self = this;
const loop = function loop() {
setTimeout(() => {
if (self.running) {
requestAnimationFrame(loop);
const flag = self.model.calculateMatrix();
const flag: boolean = self.model.calculateMatrix();
if (flag) { // повторилась ли матрица ?
self.setRunning(false);
}
Expand All @@ -49,12 +53,12 @@ class Controller {
};
loop();
}
handleCell({ target }) {
const cell = target.cellIndex;
const row = target.parentElement.sectionRowIndex;
handleCell({ target }): void {
const cell: number = target.cellIndex;
const row: number = target.parentElement.sectionRowIndex;
this.model.toggleCell(row, cell);
}
handlerButtons({ target }) {
handlerButtons({ target }): void {
switch (target.innerHTML) {
case 'start':
this.setRunning(true);
Expand All @@ -68,8 +72,8 @@ class Controller {
this.setRunning(false);
}
}
handlerSliders({ target }) {
const value = target.valueAsNumber;
handlerSliders({ target }): void {
const value: number = target.valueAsNumber;
switch (target.parentElement.previousElementSibling.innerText) {
case 'speed':
this.fps = value;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* global assert */
import Model from './Model';
import Model from './Model.ts';

describe('модель', () => {
const modelRows = 5;
Expand Down
38 changes: 22 additions & 16 deletions frontend/mvc/model/Model.js → frontend/mvc/model/Model.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import Event from '../utils/Event';

class Model {
constructor(rows = 10, columns = 10) {
matrix: Array<object>;
rows: number;
columns: number;
listOldMatrix: Array<object>;
matrixChanged: Event;
constructor(rows: number = 10, columns: number = 10) {
this.initMatrix(rows, columns);
this.rows = rows;
this.columns = columns;
this.listOldMatrix = [];
this.matrixChanged = new Event(this);
}
initMatrix(rows, columns) {
initMatrix(rows: number, columns: number): void {
this.matrix = [];
for (let i = 0; i < rows; i += 1) {
let row = [];
Expand All @@ -18,39 +23,40 @@ class Model {
this.matrix.push(row);
}
}
resizeMatrix(rows, columns) {
resizeMatrix(rows: number, columns: number): void {
this.initMatrix(rows, columns);
this.rows = rows;
this.columns = columns;
this.listOldMatrix = [];
this.matrixChanged.notify({ matrix: this.matrix, resized: true });
}
clearMatrix() {
clearMatrix(): void {
this.initMatrix(this.rows, this.columns);
this.listOldMatrix = [];
this.matrixChanged.notify({ matrix: this.matrix });
}
calculateMatrix() {
calculateMatrix(): boolean {
// обход всех ячеек с записью нового состояния
const newMatrix = this.matrix.map((row, i) => row.map((cell, j) => this.calculateCell(i, j)));
const flag = this.isRepeatMatrix(newMatrix); // повторилась ли матрица?
const newMatrix: Array<object> = this.matrix.map((row: Array<object>, i: number) =>
row.map((cell: Array<boolean>, j: number) => this.calculateCell(i, j)));
const flag: boolean = this.isRepeatMatrix(newMatrix);
this.matrix = newMatrix;
this.matrixChanged.notify({ matrix: this.matrix });
return flag;
return flag;// повторилась матрица?
}
isRepeatMatrix(newMatrix) {
const flag = this.listOldMatrix.some(matrix =>
matrix.every((row, i) =>
row.every((cell, j) =>
isRepeatMatrix(newMatrix): boolean {
const flag: boolean = this.listOldMatrix.some((matrix: Array<object>) =>
matrix.every((row: Array<object>, i: number) =>
row.every((cell: Array<boolean>, j: number) =>
(cell === newMatrix[i][j]))));
if (flag) this.listOldMatrix = [];
else this.listOldMatrix.push(newMatrix);
return flag;
}
calculateCell(row, column) {
calculateCell(row: number, column: number): boolean {
// соседи за пределами поля считаются мертвыми
let count = 0;// живые соседи
let newCell = this.matrix[row][column];
let count: number = 0;// живые соседи
let newCell: boolean = this.matrix[row][column];

if (this.matrix[row - 1]) {
if (this.matrix[row - 1][column - 1]) count += 1;
Expand All @@ -71,7 +77,7 @@ class Model {
else if (count === 3) newCell = true;
return newCell;
}
toggleCell(row, column) {
toggleCell(row: number, column: number): void {
this.matrix[row][column] = !this.matrix[row][column];
this.matrixChanged.notify({ matrix: this.matrix });
}
Expand Down
8 changes: 5 additions & 3 deletions frontend/mvc/utils/Event.js → frontend/mvc/utils/Event.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
class Event {
constructor(sender) {
sender: object;
listeners: Array<(a, b) => void>;
constructor(sender: any) {
this.sender = sender;
this.listeners = [];
}
attach(listener) {
attach(listener: (a, b) => void): void {
this.listeners.push(listener);
}
notify(args) {
notify(args: any): void {
this.listeners.forEach((listener) => {
listener(this.sender, args);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* global assert */
import Model from '../model/Model';
import View from './View';
import Model from '../model/Model.ts';
import View from './View.ts';

describe('Представление', () => {
let div;
Expand Down
43 changes: 25 additions & 18 deletions frontend/mvc/view/View.js → frontend/mvc/view/View.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,49 @@
import Event from '../utils/Event';

class View {
table: any;
controls: any;
buttons: any;
status: any;
tableClicked: Event;
buttonClicked: Event;
sliderChanged: Event;
constructor() {
this.initDOMElements();
this.initEvents();
this.initHandlers();
}
initDOMElements() {
initDOMElements(): void {
this.table = document.getElementById('board');
this.controls = document.getElementById('controls');
this.buttons = this.controls.getElementsByTagName('button');
this.status = this.controls.querySelector('.status');
}
initEvents() {
initEvents(): void {
this.tableClicked = new Event(this);
this.buttonClicked = new Event(this);
this.sliderChanged = new Event(this);
}
initHandlers() {
this.table.onclick = (event) => {
initHandlers(): void {
this.table.onclick = (event): void => {
if (event.target.tagName === 'TD') {
this.tableClicked.notify(event);
}
};
this.controls.onclick = (event) => {
this.controls.onclick = (event): void => {
if (event.target.tagName === 'BUTTON') {
this.buttonClicked.notify(event);
}
};
this.controls.onchange = (event) => {
this.controls.onchange = (event): void => {
if (event.target.tagName === 'INPUT') {
this.sliderChanged.notify(event);
}
};
}
setButtons(running) {
setButtons(running: boolean): void {
if (!this.buttons) return;
// forEach в браузере работает, а в тестах нет. по докам его быть не должно
// forEach для коллекции в браузере работает, а в тестах нет. по докам его быть не должно
Array.prototype.forEach.call(this.buttons, (button) => {
if (button.innerHTML === 'start') {
button.disabled = running;
Expand All @@ -46,20 +53,20 @@ class View {
}
});
}
setStatus(running) {
setStatus(running: boolean): void {
if (!this.status) return;
if (running) this.status.classList.remove('status_stopped');
else this.status.classList.add('status_stopped');
}
getNewTbody(matrix, tableWidth) {
getNewTbody(matrix: any, tableWidth: number) {
// заполнение тела таблицы
const columns = matrix[0].length;
const size = tableWidth / columns;
let tbody = document.createElement('tbody');
let tbody: any = document.createElement('tbody');
matrix.forEach((row) => {
let tr = document.createElement('tr');
let tr: any = document.createElement('tr');
row.forEach((cell) => {
let td = document.createElement('td');
let td: any = document.createElement('td');
this.setTdClass(td, cell);
td.style.width = `${size}px`;
td.style.height = `${size}px`;
Expand All @@ -69,24 +76,24 @@ class View {
});
return tbody;
}
initTable(matrix) {
initTable(matrix: Array<object>): void {
// для создания и ресайза таблицы
const { table } = this;
const tbody = this.getNewTbody(matrix, table.clientWidth);
if (table.children.length) table.replaceChild(tbody, table.children[0]);
else table.appendChild(tbody);
}
changeTable(matrix) {
changeTable(matrix: Array<object>): void {
// изменение класса у ячеек таблицы
const { table } = this;
const tbody = table.children[0];
matrix.forEach((row, i) => {
row.forEach((cell, j) => {
matrix.forEach((row: Array<boolean>, i: number) => {
row.forEach((cell: boolean, j: number) => {
this.setTdClass(tbody.children[i].children[j], cell);
});
});
}
setTdClass(td, flag) {
setTdClass(td: any, flag: boolean): void {
if (flag) td.className = 'live';
else td.className = '';
}
Expand Down
25 changes: 8 additions & 17 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/**
* Created by DNS on 07.11.2017.
*/
module.exports = function (config) {
const webpackConfig = require('./webpack.karma.config');

module.exports = (config) => {
config.set({
browsers: ['Chrome'],
hostname: 'localhost',
Expand All @@ -20,24 +19,16 @@ module.exports = function (config) {
istanbul: { noCompact: true },
},
},
files: ['frontend/**/*.spec.js'],
files: ['frontend/**/*.spec.ts'],
frameworks: ['chai', 'jasmine', 'sinon'],
// репортеры необходимы для наглядного отображения результатов
reporters: ['mocha', 'coverage'],
preprocessors: {
'frontend/**/*.spec.js': ['webpack', 'babel', 'sourcemap', 'coverage'],
'frontend/**/*.spec.ts': ['webpack', 'sourcemap', 'coverage'],
},
babelPreprocessor: {
options: {
presets: ['env'],
sourceMap: 'inline',
},
filename: function (file) {
return file.originalPath.replace(/\.js$/, '.es5.js');
},
sourceFileName: function (file) {
return file.originalPath;
},
webpack: {
module: webpackConfig.module,
resolve: webpackConfig.resolve,
},
plugins: [
'karma-jasmine', 'karma-mocha',
Expand Down
Loading

0 comments on commit 3902508

Please sign in to comment.