Skip to content

Commit

Permalink
lib: inline predicate logic
Browse files Browse the repository at this point in the history
  • Loading branch information
zackschuster committed Sep 29, 2022
1 parent 14391c1 commit a1fba50
Showing 1 changed file with 69 additions and 64 deletions.
133 changes: 69 additions & 64 deletions lib/chessboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,6 @@ function throttle(f, interval) {
};
}

// function debounce (f, interval, scope) {
// const timeout = 0
// return function (_args) {
// window.clearTimeout(timeout)
// const args = arguments
// timeout = window.setTimeout(function () {
// f.apply(scope, args)
// }, interval)
// }
// }

function uuid() {
return 'xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx'.replace(/x/g, function () {
const r = (Math.random() * 16) | 0;
Expand Down Expand Up @@ -123,38 +112,24 @@ function interpolateTemplate(str, obj) {
// Predicates
// ---------------------------------------------------------------------------

function isString(s) {
return typeof s === 'string';
}

function isFunction(f) {
return typeof f === 'function';
}

function isInteger(n) {
return typeof n === 'number' &&
isFinite(n) &&
Math.floor(n) === n;
}

function isPlainObject(o) {
return Object.prototype.toString.call(o) === '[object Object]';
}

function validAnimationSpeed(speed) {
if (speed === 'fast' || speed === 'slow') return true;
if (!isInteger(speed)) return false;
if (!Number.isInteger(speed)) return false;
return speed >= 0;
}

function validThrottleRate(rate) {
return isInteger(rate) &&
return Number.isInteger(rate) &&
rate >= 1;
}

function validMove(move) {
// move should be a string
if (!isString(move)) return false;
if (typeof move !== 'string') return false;

// move should be in the form of "e2-e4", "f6-d5"
const squares = move.split('-');
Expand All @@ -164,15 +139,20 @@ function validMove(move) {
}

function validSquare(square) {
return isString(square) && square.search(/^[a-h][1-8]$/) !== -1;
return typeof square === 'string' && square.search(/^[a-h][1-8]$/) !== -1;
}

function validPieceCode(code) {
return isString(code) && code.search(/^[bw][KQRNBP]$/) !== -1;
return typeof code === 'string' && code.search(/^[bw][KQRNBP]$/) !== -1;
}

/**
*
* @param {string} [fen]
* @returns {boolean}
*/
function validFen(fen) {
if (!isString(fen)) return false;
if (typeof fen !== 'string') return false;

// cut off any move, castling, etc info from the end
// we're only interested in position information
Expand Down Expand Up @@ -242,17 +222,20 @@ function pieceCodeToFen(piece) {
return pieceCodeLetters[1].toLowerCase();
}

// convert FEN string to position object
// returns false if the FEN string is invalid
/**
* Convert FEN string to position object. Returns `false` if the FEN string is invalid
* @param {string} [fen]
* @returns {false | Record<string, string>}
*/
function fenToObj(fen) {
if (!validFen(fen)) return false;
if (!fen || !validFen(fen)) return false;

// cut off any move, castling, etc info from the end
// we're only interested in position information
fen = fen.replace(/ .+$/, '');

const rows = fen.split('/');
const position = {};
const position = /** @type {Record<string, string>} */({});

let currentRow = 8;
for (let i = 0; i < 8; i++) {
Expand All @@ -279,8 +262,13 @@ function fenToObj(fen) {
return position;
}

// position object to FEN string
// returns false if the obj is not a valid position object
//
//
/**
* Converts position object to FEN string. Returns false if the obj is not a valid position object
* @param {object} obj
* @returns {false | string}
*/
function objToFen(obj) {
if (!validPositionObject(obj)) return false;

Expand Down Expand Up @@ -313,6 +301,10 @@ function objToFen(obj) {
return fen;
}

/**
* @param {string} fen
* @returns {string}
*/
function squeezeFenEmptySquares(fen) {
return fen.replace(/11111111/g, '8')
.replace(/1111111/g, '7')
Expand All @@ -323,6 +315,10 @@ function squeezeFenEmptySquares(fen) {
.replace(/11/g, '2');
}

/**
* @param {string} fen
* @returns {string}
*/
function expandFenEmptySquares(fen) {
return fen.replace(/8/g, '11111111')
.replace(/7/g, '1111111')
Expand Down Expand Up @@ -483,7 +479,7 @@ function expandConfig(config) {

// default piece theme is wikipedia
if (!Object.prototype.hasOwnProperty.call(config, 'pieceTheme') ||
(!isString(config.pieceTheme) && !isFunction(config.pieceTheme))) {
(typeof config.pieceTheme !== 'string' && typeof config.pieceTheme !== 'function')) {
config.pieceTheme = 'img/chesspieces/wikipedia/{piece}.png';
}

Expand Down Expand Up @@ -516,14 +512,13 @@ function checkContainerArg(containerElOrString) {
}

// convert containerEl to query selector if it is a string
if (isString(containerElOrString) &&
containerElOrString.charAt(0) !== '#') {
if (typeof containerElOrString === 'string' && containerElOrString.startsWith('#') === false) {
containerElOrString = '#' + containerElOrString;
}

// containerEl must be something that becomes a NodeList of size 1
const $container = /** @type {NodeListOf<HTMLElement>} */(document.querySelectorAll(containerElOrString));
if ($container.length !== 1) {
const container = /** @type {NodeListOf<HTMLElement>} */(document.querySelectorAll(containerElOrString));
if (container.length !== 1) {
const errorMsg2 = 'Chessboard Error 1003: ' +
'The first argument to Chessboard() must be the ID of a DOM node, ' +
'an ID query selector, or a single DOM node.' +
Expand All @@ -533,7 +528,7 @@ function checkContainerArg(containerElOrString) {
return false;
}

return $container.item(0);
return container.item(0);
}

// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -586,6 +581,9 @@ class Chessboard {
#sparePiecesElsIds = {};
#squareElsIds = {};
#squareElsOffsets = {};
/**
* @type {number}
*/
#squareSize = 16;

constructor(containerElOrString, config) {
Expand Down Expand Up @@ -734,14 +732,21 @@ class Chessboard {
position(position, useAnimation) {
if (!position) {
return deepCopy(this.#currentPosition);
} else if (isString(position) && position.toLowerCase() === 'fen') {
// get position as FEN
return objToFen(this.#currentPosition);
}

if (isString(position) && position.toLowerCase() === 'start') {
// start position
position = deepCopy(START_POSITION);
const positionIsString = typeof position === 'string';

if (positionIsString) {
const positionLowerCase = position.toLowerCase();

if (positionLowerCase === 'fen') {
// get position as FEN
return objToFen(this.#currentPosition);
}
if (positionLowerCase === 'start') {
// start position
position = deepCopy(START_POSITION);
}
}

// convert FEN to position object
Expand Down Expand Up @@ -831,7 +836,7 @@ class Chessboard {
this.#draggedPiece.style.setProperty('display', 'none');

// execute their onSnapEnd function
if (isFunction(this.#config.onSnapEnd)) {
if (typeof this.#config.onSnapEnd === 'function') {
this.#config.onSnapEnd(this.#draggedPieceSource, square, this.#draggedPiece);
}
}
Expand Down Expand Up @@ -876,7 +881,7 @@ class Chessboard {
}

// custom function
if (isFunction(this.#config.showErrors)) {
if (typeof this.#config.showErrors === 'function') {
this.#config.showErrors(code, msg, obj);
}
}
Expand Down Expand Up @@ -961,11 +966,11 @@ class Chessboard {
}

#buildPieceImgSrc(piece) {
if (isFunction(this.#config.pieceTheme)) {
if (typeof this.#config.pieceTheme === 'function') {
return this.#config.pieceTheme(piece);
}

if (isString(this.#config.pieceTheme)) {
if (typeof this.#config.pieceTheme === 'string') {
return interpolateTemplate(this.#config.pieceTheme, { piece });
}

Expand All @@ -982,7 +987,7 @@ class Chessboard {

#buildPieceHTML(piece, hidden, id) {
let html = '<img src="' + this.#buildPieceImgSrc(piece) + '" ';
if (isString(id) && id !== '') {
if (typeof id === 'string' && id.length > 0) {
html += 'id="' + id + '" ';
}
html += 'alt="" ' +
Expand Down Expand Up @@ -1043,7 +1048,7 @@ class Chessboard {
$animatedPiece.remove();

// run complete function
if (isFunction(completeFn)) {
if (typeof completeFn === 'function') {
completeFn();
}
};
Expand Down Expand Up @@ -1075,7 +1080,7 @@ class Chessboard {
$animatedPiece.remove();

// run complete function
if (isFunction(completeFn)) {
if (typeof completeFn === 'function') {
completeFn();
}
};
Expand All @@ -1094,7 +1099,7 @@ class Chessboard {
this.#drawPositionInstant();

// run their onMoveEnd function
if (isFunction(this.#config.onMoveEnd)) {
if (typeof this.#config.onMoveEnd === 'function') {
this.#config.onMoveEnd(deepCopy(oldPos), deepCopy(newPos));
}
};
Expand Down Expand Up @@ -1246,7 +1251,7 @@ class Chessboard {
if (oldFen === newFen) return;

// run their onChange function
if (isFunction(this.#config.onChange)) {
if (typeof this.#config.onChange === 'function') {
this.#config.onChange(oldPos, newPos);
}

Expand Down Expand Up @@ -1314,7 +1319,7 @@ class Chessboard {
this.#draggedPiece.style.setProperty('display', 'none');

// run their onSnapbackEnd function
if (isFunction(this.#config.onSnapbackEnd)) {
if (typeof this.#config.onSnapbackEnd === 'function') {
this.#config.onSnapbackEnd(
this.#draggedPiece,
this.#draggedPieceSource,
Expand Down Expand Up @@ -1351,7 +1356,7 @@ class Chessboard {
#beginDraggingPiece(source, piece, x, y) {
// run their custom onDragStart function
// their custom onDragStart function can cancel drag start
if (isFunction(this.#config.onDragStart) &&
if (typeof this.#config.onDragStart === 'function' &&
this.#config.onDragStart(source, piece, deepCopy(this.#currentPosition), this.#currentOrientation) === false) {
return;
}
Expand Down Expand Up @@ -1411,7 +1416,7 @@ class Chessboard {
}

// run onDragMove
if (isFunction(this.#config.onDragMove)) {
if (typeof this.#config.onDragMove === 'function') {
this.#config.onDragMove(
location,
this.#draggedPieceLocation,
Expand All @@ -1437,7 +1442,7 @@ class Chessboard {
}

// run their onDrop function, which can potentially change the drop action
if (isFunction(this.#config.onDrop)) {
if (typeof this.#config.onDrop === 'function') {
const newPosition = deepCopy(this.#currentPosition);

// source piece is a spare piece and position is off the board
Expand Down Expand Up @@ -1598,7 +1603,7 @@ class Chessboard {
if (this.#isDragging) return;

// exit if they did not provide a onMouseoverSquare function
if (!isFunction(this.#config.onMouseoverSquare)) return;
if (typeof this.#config.onMouseoverSquare !== 'function') return;

// get the square
const square = /** @type {HTMLElement | null} */(evt.currentTarget)?.getAttribute('data-square');
Expand All @@ -1622,7 +1627,7 @@ class Chessboard {
if (this.#isDragging) return;

// exit if they did not provide an onMouseoutSquare function
if (!isFunction(this.#config.onMouseoutSquare)) return;
if (typeof this.#config.onMouseoutSquare !== 'function') return;

// get the square
const square = document.getElementById(evt.currentTarget)?.getAttribute('data-square');
Expand Down

0 comments on commit a1fba50

Please sign in to comment.