build editor with default tsconfig

This commit is contained in:
Niklas Fiekas 2019-11-18 00:56:44 +01:00
parent 7a89bef927
commit afe74702e4
7 changed files with 71 additions and 73 deletions

View file

@ -14,7 +14,7 @@ export default function(ctrl: EditorCtrl): VNode {
ctrl.chessground = Chessground(el, makeConfig(ctrl));
bindEvents(el, ctrl);
},
destroy: _ => ctrl.chessground.destroy()
destroy: _ => ctrl.chessground!.destroy()
}
});
}
@ -26,15 +26,15 @@ function bindEvents(el: HTMLElement, ctrl: EditorCtrl): void {
});
}
function isLeftButton(e): boolean {
function isLeftButton(e: MouchEvent): boolean {
return e.buttons === 1 || e.button === 1;
}
function isLeftClick(e): boolean {
function isLeftClick(e: MouchEvent): boolean {
return isLeftButton(e) && !e.ctrlKey;
}
function isRightClick(e): boolean {
function isRightClick(e: MouchEvent): boolean {
return util.isRightButton(e) || (e.ctrlKey && isLeftButton(e));
}
@ -52,12 +52,14 @@ function onMouseEvent(ctrl: EditorCtrl): (e: MouchEvent) => void {
if (isLeftClick(e) || e.type === 'touchstart' || e.type === 'touchmove') {
if (sel === 'pointer' || (ctrl.chessground && ctrl.chessground.state.draggable.current && ctrl.chessground.state.draggable.current.newPiece)) return;
const key = ctrl.chessground.getKeyAtDomPos(util.eventPosition(e));
const pos = util.eventPosition(e);
if (!pos) return;
const key = ctrl.chessground!.getKeyAtDomPos(pos);
if (!key) return;
if (e.type === 'mousedown' || e.type === 'touchstart') downKey = key;
if (sel === 'trash') deleteOrHidePiece(ctrl, key, e);
else {
const existingPiece = ctrl.chessground.state.pieces[key];
const existingPiece = ctrl.chessground!.state.pieces[key];
const piece = {
color: sel[0],
role: sel[1]
@ -70,21 +72,21 @@ function onMouseEvent(ctrl: EditorCtrl): (e: MouchEvent) => void {
const endEvents = { mousedown: 'mouseup', touchstart: 'touchend' };
document.addEventListener(endEvents[e.type], () => placeDelete = false, { once: true });
} else if (!placeDelete && (e.type === 'mousedown' || e.type === 'touchstart' || key !== lastKey)) {
ctrl.chessground.setPieces({
ctrl.chessground!.setPieces({
[key]: piece
});
ctrl.onChange();
ctrl.chessground.cancelMove();
ctrl.chessground!.cancelMove();
}
}
lastKey = key;
} else if (isRightClick(e)) {
if (sel !== 'pointer') {
ctrl.chessground.state.drawable.current = undefined;
ctrl.chessground.state.drawable.shapes = [];
ctrl.chessground!.state.drawable.current = undefined;
ctrl.chessground!.state.drawable.shapes = [];
if (e.type === 'contextmenu' && sel != 'trash') {
ctrl.chessground.cancelMove();
ctrl.chessground!.cancelMove();
sel[0] = util.opposite(sel[0]);
ctrl.redraw();
}
@ -95,9 +97,9 @@ function onMouseEvent(ctrl: EditorCtrl): (e: MouchEvent) => void {
function deleteOrHidePiece(ctrl: EditorCtrl, key: Key, e: Event): void {
if (e.type === 'touchstart') {
if (ctrl.chessground.state.pieces[key]) {
(ctrl.chessground.state.draggable.current.element as HTMLElement).style.display = 'none';
ctrl.chessground.cancelMove();
if (ctrl.chessground!.state.pieces[key]) {
(ctrl.chessground!.state.draggable.current!.element as HTMLElement).style.display = 'none';
ctrl.chessground!.cancelMove();
}
document.addEventListener('touchend', () => deletePiece(ctrl, key), { once: true });
} else if (e.type === 'mousedown' || key !== downKey) {
@ -106,7 +108,7 @@ function deleteOrHidePiece(ctrl: EditorCtrl, key: Key, e: Event): void {
}
function deletePiece(ctrl: EditorCtrl, key: Key): void {
ctrl.chessground.setPieces({
ctrl.chessground!.setPieces({
[key]: undefined
});
ctrl.onChange();

View file

@ -11,7 +11,7 @@ export default class EditorCtrl {
embed: boolean;
trans: Trans;
selected: Prop<Selection>;
extraPositions?: OpeningPosition[];
extraPositions: OpeningPosition[];
chessground: CgApi | undefined;
positionIndex: { [boardFen: string]: number };
redraw: Redraw;
@ -42,7 +42,7 @@ export default class EditorCtrl {
this.positionIndex[p.fen.split(' ')[0]] = i;
});
window.Mousetrap.bind('f', (e) => {
window.Mousetrap.bind('f', (e: Event) => {
e.preventDefault();
if (this.chessground) this.chessground.toggleOrientation();
redraw();
@ -73,13 +73,13 @@ export default class EditorCtrl {
this.onChange();
}
setCastle(id, value): void {
setCastle(id: 'K' | 'Q' | 'k' | 'q', value: boolean): void {
this.data.castles[id](value);
this.onChange();
}
startPosition(): void {
this.chessground.set({
this.chessground!.set({
fen: 'start'
});
this.data.castles = editor.castlesAt(true);
@ -88,7 +88,7 @@ export default class EditorCtrl {
}
clearBoard(): void {
this.chessground.set({
this.chessground!.set({
fen: '8/8/8/8/8/8/8/8'
});
this.data.castles = editor.castlesAt(false);
@ -97,7 +97,7 @@ export default class EditorCtrl {
loadNewFen(fen: string | 'prompt'): void {
if (fen === 'prompt') {
fen = prompt('Paste FEN position').trim();
fen = (prompt('Paste FEN position') || '').trim();
if (!fen) return;
}
this.changeFen(fen);
@ -121,15 +121,16 @@ export default class EditorCtrl {
black: 0
};
for (const pos in pieces) {
if (pieces[pos] && pieces[pos].role === 'king') kings[pieces[pos].color]++;
const piece = pieces[pos];
if (piece && piece.role === 'king') kings[piece.color]++;
}
return kings.white === (variant !== "horde" ? 1 : 0) && kings.black === 1;
}
setOrientation = function(o: Color): void {
setOrientation(o: Color): void {
this.options.orientation = o;
if (this.chessground.state.orientation !== o)
this.chessground.toggleOrientation();
if (this.chessground!.state.orientation !== o)
this.chessground!.toggleOrientation();
this.redraw();
}
}

View file

@ -1,5 +1,5 @@
import { prop, Prop } from 'common';
import { EditorConfig, EditorData, Castles } from './interfaces';
import { EditorConfig, EditorData, Castles, CASTLING_SIDES } from './interfaces';
export function init(cfg: EditorConfig): EditorData {
return {
@ -28,9 +28,9 @@ export function castlesAt(v: boolean): Castles<Prop<boolean>> {
function fenMetadatas(data: EditorData): string {
let castles = '';
Object.keys(data.castles).forEach(piece => {
if (data.castles[piece]()) castles += piece;
});
for (const side of CASTLING_SIDES) {
if (data.castles[side]()) castles += side;
}
return `${data.color()} ${castles.length ? castles : '-'} -`;
}

View file

@ -1,5 +1,9 @@
import { Prop } from 'common';
export type CastlingSide = 'K' | 'Q' | 'k' | 'q';
export const CASTLING_SIDES: CastlingSide[] = ['K', 'Q', 'k', 'q'];
export interface Castles<T> {
K: T;
Q: T;
@ -41,7 +45,7 @@ export interface EditorData {
castles: Castles<Prop<boolean>>;
variant: VariantKey;
i18n: any;
positions: OpeningPosition[];
positions?: OpeningPosition[];
}
export type Redraw = () => void;

View file

@ -15,7 +15,7 @@ menuHover();
const patch = init([klass, attributes, eventlisteners]);
export default function(element, config: EditorConfig) {
export default function(element: HTMLElement, config: EditorConfig) {
let vnode: VNode, ctrl: EditorCtrl;
const redraw = () => {

View file

@ -1,12 +1,12 @@
import { h } from 'snabbdom';
import { VNode } from 'snabbdom/vnode';
import { MouchEvent } from 'chessground/types';
import { MouchEvent, NumberPair } from 'chessground/types';
import { dragNewPiece } from 'chessground/drag';
import { eventPosition, opposite } from 'chessground/util';
import EditorCtrl from './ctrl';
import chessground from './chessground';
import * as editor from './editor';
import { OpeningPosition } from './interfaces';
import { OpeningPosition, Selection } from './interfaces';
function castleCheckBox(ctrl: EditorCtrl, id: 'K' | 'Q' | 'k' | 'q', label: string, reversed: boolean): VNode {
const input = h('input', {
@ -80,7 +80,7 @@ function controls(ctrl: EditorCtrl, fen: string): VNode {
return h('option', {
attrs: {
value: pos.fen,
selected: currentPosition && currentPosition.fen === pos.fen
selected: !!currentPosition && currentPosition.fen === pos.fen
}
}, pos.eco ? `${pos.eco} ${pos.name}` : pos.name);
};
@ -125,11 +125,11 @@ function controls(ctrl: EditorCtrl, fen: string): VNode {
h('div.castling', [
h('strong', ctrl.trans.noarg('castling')),
h('div', [
castleCheckBox(ctrl, 'K', ctrl.trans.noarg('whiteCastlingKingside'), ctrl.options.inlineCastling),
castleCheckBox(ctrl, 'K', ctrl.trans.noarg('whiteCastlingKingside'), !!ctrl.options.inlineCastling),
castleCheckBox(ctrl, 'Q', 'O-O-O', true)
]),
h('div', [
castleCheckBox(ctrl, 'k', ctrl.trans.noarg('blackCastlingKingside'), ctrl.options.inlineCastling),
castleCheckBox(ctrl, 'k', ctrl.trans.noarg('blackCastlingKingside'), !!ctrl.options.inlineCastling),
castleCheckBox(ctrl, 'q', 'O-O-O', true)
])
])
@ -165,7 +165,7 @@ function controls(ctrl: EditorCtrl, fen: string): VNode {
attrs: { 'data-icon': 'B' },
on: {
click() {
ctrl.chessground.toggleOrientation();
ctrl.chessground!.toggleOrientation();
}
}
}, ctrl.trans.noarg('flipBoard')),
@ -246,13 +246,13 @@ function inputs(ctrl: EditorCtrl, fen: string): VNode | undefined {
}
// can be 'pointer', 'trash', or [color, role]
function selectedToClass(s): string {
function selectedToClass(s: Selection): string {
return (s === 'pointer' || s === 'trash') ? s : s.join(' ');
}
let lastTouchMovePos;
let lastTouchMovePos: NumberPair | undefined;
function sparePieces(ctrl: EditorCtrl, color: Color, orientation: Color, position: 'top' | 'bottom'): VNode {
function sparePieces(ctrl: EditorCtrl, color: Color, _orientation: Color, position: 'top' | 'bottom'): VNode {
const selectedClass = selectedToClass(ctrl.selected());
const pieces = ['king', 'queen', 'rook', 'bishop', 'knight', 'pawn'].map(function(role) {
@ -263,37 +263,25 @@ function sparePieces(ctrl: EditorCtrl, color: Color, orientation: Color, positio
attrs: {
class: ['spare', 'spare-' + position, 'spare-' + color].join(' ')
}
}, ['pointer', ...pieces, 'trash'].map(function(s) {
}, ['pointer', ...pieces, 'trash'].map((s: Selection) => {
const className = selectedToClass(s);
const attrs = {
class: className
class: className,
...((s !== 'pointer' && s !== 'trash') ? {
'data-color': s[0],
'data-role': s[1]
} : {})
};
let containerClass = 'no-square' +
(
(
selectedClass === className &&
(
!ctrl.chessground ||
!ctrl.chessground.state.draggable.current ||
!ctrl.chessground.state.draggable.current.newPiece
)
) ?
' selected-square' : ''
);
if (s === 'pointer') {
containerClass += ' pointer';
} else if (s === 'trash') {
containerClass += ' trash';
} else {
attrs['data-color'] = s[0];
attrs['data-role'] = s[1];
}
const selectedSquare = selectedClass === className && (
!ctrl.chessground ||
!ctrl.chessground.state.draggable.current ||
!ctrl.chessground.state.draggable.current.newPiece);
return h('div', {
attrs: {
class: containerClass,
class: {
'no-square': true,
pointer: s === 'pointer',
trash: s === 'trash',
'selected-square': selectedSquare
},
on: {
mousedown: onSelectSparePiece(ctrl, s, 'mouseup'),
@ -306,22 +294,21 @@ function sparePieces(ctrl: EditorCtrl, color: Color, orientation: Color, positio
}));
}
function onSelectSparePiece(ctrl: EditorCtrl, s, upEvent: string): (e: MouchEvent) => void {
function onSelectSparePiece(ctrl: EditorCtrl, s: Selection, upEvent: string): (e: MouchEvent) => void {
return function(e: MouchEvent): void {
e.preventDefault();
if (['pointer', 'trash'].includes(s)) ctrl.selected(s);
if (s === 'pointer' || s === 'trash') ctrl.selected(s);
else {
ctrl.selected('pointer');
dragNewPiece(ctrl.chessground.state, {
dragNewPiece(ctrl.chessground!.state, {
color: s[0],
role: s[1]
}, e, true);
document.addEventListener(upEvent, (e: MouchEvent) => {
const eventPos = eventPosition(e) || lastTouchMovePos;
if (eventPos && ctrl.chessground.getKeyAtDomPos(eventPos)) ctrl.selected('pointer');
if (eventPos && ctrl.chessground!.getKeyAtDomPos(eventPos)) ctrl.selected('pointer');
else ctrl.selected(s);
ctrl.redraw();
}, { once: true });
@ -329,7 +316,7 @@ function onSelectSparePiece(ctrl: EditorCtrl, s, upEvent: string): (e: MouchEven
};
}
function makeCursor(selected): string {
function makeCursor(selected: Selection): string {
if (selected === 'pointer') return 'pointer';
const name = selected === 'trash' ? 'trash' : selected.join('-');

4
ui/editor/tsconfig.json Normal file
View file

@ -0,0 +1,4 @@
{
"extends": "../tsconfig.base.json",
"include": ["src/*.ts"]
}