@alepot55/chessboardjs 2.3.5 → 2.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chessboard.cjs.js +317 -772
- package/dist/chessboard.esm.js +317 -772
- package/dist/chessboard.iife.js +317 -772
- package/dist/chessboard.umd.js +317 -772
- package/package.json +1 -1
- package/src/components/Piece.js +13 -1
- package/src/core/Chessboard.js +265 -686
- package/src/core/ChessboardConfig.js +17 -18
- package/src/core/index.js +15 -34
- package/src/index.js +13 -13
- package/src/services/PieceService.js +9 -3
- package/tests/unit/chessboard-config-animations.test.js +0 -9
package/dist/chessboard.cjs.js
CHANGED
|
@@ -1096,7 +1096,7 @@ const DEFAULT_CONFIG$1 = Object.freeze({
|
|
|
1096
1096
|
ratio: 0.9,
|
|
1097
1097
|
piecesPath: '../assets/themes/default',
|
|
1098
1098
|
animationStyle: 'simultaneous',
|
|
1099
|
-
simultaneousAnimationDelay:
|
|
1099
|
+
simultaneousAnimationDelay: 0,
|
|
1100
1100
|
onMove: () => true,
|
|
1101
1101
|
onMoveEnd: () => true,
|
|
1102
1102
|
onChange: () => true,
|
|
@@ -1130,19 +1130,19 @@ class ChessboardConfig {
|
|
|
1130
1130
|
constructor(settings = {}) {
|
|
1131
1131
|
// Initialize validation service
|
|
1132
1132
|
this._validationService = new ValidationService();
|
|
1133
|
-
|
|
1133
|
+
|
|
1134
1134
|
// Validate input
|
|
1135
1135
|
this._validateInput(settings);
|
|
1136
|
-
|
|
1136
|
+
|
|
1137
1137
|
// Merge with defaults
|
|
1138
1138
|
const config = this._mergeWithDefaults(settings);
|
|
1139
|
-
|
|
1139
|
+
|
|
1140
1140
|
// Process and validate configuration
|
|
1141
1141
|
this._processConfiguration(config);
|
|
1142
|
-
|
|
1142
|
+
|
|
1143
1143
|
// Set CSS properties
|
|
1144
1144
|
this._setCSSProperties(config);
|
|
1145
|
-
|
|
1145
|
+
|
|
1146
1146
|
// Configure mode-specific settings
|
|
1147
1147
|
this._configureModeSettings();
|
|
1148
1148
|
}
|
|
@@ -1157,7 +1157,7 @@ class ChessboardConfig {
|
|
|
1157
1157
|
if (settings !== null && typeof settings !== 'object') {
|
|
1158
1158
|
throw new ConfigurationError('Settings must be an object', 'settings', settings);
|
|
1159
1159
|
}
|
|
1160
|
-
|
|
1160
|
+
|
|
1161
1161
|
// Validate using validation service
|
|
1162
1162
|
try {
|
|
1163
1163
|
this._validationService.validateConfig(settings);
|
|
@@ -1191,7 +1191,7 @@ class ChessboardConfig {
|
|
|
1191
1191
|
this.size = config.size;
|
|
1192
1192
|
this.movableColors = config.movableColors;
|
|
1193
1193
|
this.piecesPath = config.piecesPath;
|
|
1194
|
-
|
|
1194
|
+
|
|
1195
1195
|
// Event handlers
|
|
1196
1196
|
this.onMove = this._validateCallback(config.onMove);
|
|
1197
1197
|
this.onMoveEnd = this._validateCallback(config.onMoveEnd);
|
|
@@ -1219,7 +1219,7 @@ class ChessboardConfig {
|
|
|
1219
1219
|
this.snapbackTime = this._setTime(config.snapbackTime);
|
|
1220
1220
|
this.dropCenterTime = this._setTime(config.dropCenterTime);
|
|
1221
1221
|
this.fadeTime = this._setTime(config.fadeTime);
|
|
1222
|
-
|
|
1222
|
+
|
|
1223
1223
|
// Animation style properties
|
|
1224
1224
|
this.animationStyle = this._validateAnimationStyle(config.animationStyle);
|
|
1225
1225
|
this.simultaneousAnimationDelay = this._validateDelay(config.simultaneousAnimationDelay);
|
|
@@ -1352,11 +1352,11 @@ class ChessboardConfig {
|
|
|
1352
1352
|
}
|
|
1353
1353
|
return value;
|
|
1354
1354
|
}
|
|
1355
|
-
|
|
1355
|
+
|
|
1356
1356
|
if (typeof value === 'string' && value in ANIMATION_TIMES) {
|
|
1357
1357
|
return ANIMATION_TIMES[value];
|
|
1358
1358
|
}
|
|
1359
|
-
|
|
1359
|
+
|
|
1360
1360
|
throw new ConfigurationError('Invalid time value', 'time', value);
|
|
1361
1361
|
}
|
|
1362
1362
|
|
|
@@ -1371,11 +1371,11 @@ class ChessboardConfig {
|
|
|
1371
1371
|
if (typeof value === 'boolean') {
|
|
1372
1372
|
return value;
|
|
1373
1373
|
}
|
|
1374
|
-
|
|
1374
|
+
|
|
1375
1375
|
if (value in BOOLEAN_VALUES) {
|
|
1376
1376
|
return BOOLEAN_VALUES[value];
|
|
1377
1377
|
}
|
|
1378
|
-
|
|
1378
|
+
|
|
1379
1379
|
throw new ConfigurationError('Invalid boolean value', 'boolean', value);
|
|
1380
1380
|
}
|
|
1381
1381
|
|
|
@@ -1391,17 +1391,17 @@ class ChessboardConfig {
|
|
|
1391
1391
|
if (typeof value === 'boolean') {
|
|
1392
1392
|
return value ? TRANSITION_FUNCTIONS.ease : null;
|
|
1393
1393
|
}
|
|
1394
|
-
|
|
1394
|
+
|
|
1395
1395
|
// Handle string values
|
|
1396
1396
|
if (typeof value === 'string' && value in TRANSITION_FUNCTIONS) {
|
|
1397
1397
|
return TRANSITION_FUNCTIONS[value];
|
|
1398
1398
|
}
|
|
1399
|
-
|
|
1399
|
+
|
|
1400
1400
|
// Handle null/undefined
|
|
1401
1401
|
if (value === null || value === undefined) {
|
|
1402
1402
|
return null;
|
|
1403
1403
|
}
|
|
1404
|
-
|
|
1404
|
+
|
|
1405
1405
|
throw new ConfigurationError('Invalid transition function', 'transitionFunction', value);
|
|
1406
1406
|
}
|
|
1407
1407
|
|
|
@@ -1454,7 +1454,7 @@ class ChessboardConfig {
|
|
|
1454
1454
|
|
|
1455
1455
|
// Apply updates
|
|
1456
1456
|
const newConfig = Object.assign({}, this.toObject(), updates);
|
|
1457
|
-
|
|
1457
|
+
|
|
1458
1458
|
// Re-process configuration
|
|
1459
1459
|
this._processConfiguration(newConfig);
|
|
1460
1460
|
this._setCSSProperties(newConfig);
|
|
@@ -1677,10 +1677,22 @@ class Piece {
|
|
|
1677
1677
|
|
|
1678
1678
|
setDrag(f) {
|
|
1679
1679
|
if (!this.element) { console.debug(`[Piece] setDrag: ${this.id} - element is null`); return; }
|
|
1680
|
+
// Remove previous handlers
|
|
1681
|
+
this.element.onmousedown = null;
|
|
1682
|
+
this.element.ontouchstart = null;
|
|
1683
|
+
this.element.ondragstart = null;
|
|
1684
|
+
if (window.PointerEvent) {
|
|
1685
|
+
this.element.onpointerdown = null;
|
|
1686
|
+
}
|
|
1687
|
+
// Set new handlers
|
|
1680
1688
|
this.element.ondragstart = (e) => { e.preventDefault(); };
|
|
1681
1689
|
this.element.onmousedown = f;
|
|
1682
1690
|
this.element.ontouchstart = f; // Drag touch
|
|
1683
|
-
|
|
1691
|
+
if (window.PointerEvent) {
|
|
1692
|
+
this.element.onpointerdown = f;
|
|
1693
|
+
console.debug(`[Piece] setDrag: pointerdown set for ${this.id}`);
|
|
1694
|
+
}
|
|
1695
|
+
console.debug(`[Piece] setDrag: mousedown/ontouchstart set for ${this.id}`);
|
|
1684
1696
|
}
|
|
1685
1697
|
|
|
1686
1698
|
destroy() {
|
|
@@ -4655,9 +4667,15 @@ class PieceService {
|
|
|
4655
4667
|
console.debug(`[PieceService] addPieceOnSquare: ${piece.id} to ${square.id}`);
|
|
4656
4668
|
square.putPiece(piece);
|
|
4657
4669
|
|
|
4670
|
+
// Imposta sempre il drag (touch e mouse)
|
|
4658
4671
|
if (dragFunction) {
|
|
4659
4672
|
piece.setDrag(dragFunction(square, piece));
|
|
4660
4673
|
}
|
|
4674
|
+
// Forza il drag touch se manca (debug/robustezza)
|
|
4675
|
+
if (!piece.element.ontouchstart) {
|
|
4676
|
+
piece.element.ontouchstart = dragFunction ? dragFunction(square, piece) : () => { };
|
|
4677
|
+
console.debug(`[PieceService] Forzato ontouchstart su ${piece.id}`);
|
|
4678
|
+
}
|
|
4661
4679
|
|
|
4662
4680
|
if (fade && this.config.fadeTime > 0) {
|
|
4663
4681
|
piece.fadeIn(
|
|
@@ -4715,8 +4733,8 @@ class PieceService {
|
|
|
4715
4733
|
*/
|
|
4716
4734
|
movePiece(piece, targetSquare, duration, callback) {
|
|
4717
4735
|
console.debug(`[PieceService] movePiece: ${piece.id} to ${targetSquare.id}`);
|
|
4718
|
-
if (!piece) {
|
|
4719
|
-
console.warn(
|
|
4736
|
+
if (!piece || !piece.element) {
|
|
4737
|
+
console.warn(`[PieceService] movePiece: piece or element is null, skipping animation`);
|
|
4720
4738
|
if (callback) callback();
|
|
4721
4739
|
return;
|
|
4722
4740
|
}
|
|
@@ -4772,7 +4790,7 @@ class PieceService {
|
|
|
4772
4790
|
};
|
|
4773
4791
|
|
|
4774
4792
|
// Check if piece is currently being dragged
|
|
4775
|
-
const isDragging = move.piece.element.classList.contains('dragging');
|
|
4793
|
+
const isDragging = move.piece.element && move.piece.element.classList.contains('dragging');
|
|
4776
4794
|
|
|
4777
4795
|
if (isDragging) {
|
|
4778
4796
|
// If piece is being dragged, don't animate - just move it immediately
|
|
@@ -7097,7 +7115,7 @@ class PositionService {
|
|
|
7097
7115
|
* Implements the Facade pattern to provide a unified interface
|
|
7098
7116
|
* @class
|
|
7099
7117
|
*/
|
|
7100
|
-
|
|
7118
|
+
class Chessboard {
|
|
7101
7119
|
/**
|
|
7102
7120
|
* Creates a new Chessboard instance
|
|
7103
7121
|
* @param {Object} config - Configuration object
|
|
@@ -7122,8 +7140,6 @@ let Chessboard$1 = class Chessboard {
|
|
|
7122
7140
|
} catch (error) {
|
|
7123
7141
|
this._handleConstructorError(error);
|
|
7124
7142
|
}
|
|
7125
|
-
this._undoneMoves = [];
|
|
7126
|
-
this._updateBoardPieces(true, true); // Forza popolamento DOM subito
|
|
7127
7143
|
}
|
|
7128
7144
|
|
|
7129
7145
|
/**
|
|
@@ -7167,31 +7183,6 @@ let Chessboard$1 = class Chessboard {
|
|
|
7167
7183
|
}
|
|
7168
7184
|
}
|
|
7169
7185
|
|
|
7170
|
-
/**
|
|
7171
|
-
* Cleans up any partially initialized resources (safe to call multiple times)
|
|
7172
|
-
* @private
|
|
7173
|
-
*/
|
|
7174
|
-
_cleanup() {
|
|
7175
|
-
// Remove event listeners if present
|
|
7176
|
-
if (this.eventService && typeof this.eventService.removeListeners === 'function') {
|
|
7177
|
-
this.eventService.removeListeners();
|
|
7178
|
-
}
|
|
7179
|
-
// Clear timeouts
|
|
7180
|
-
if (this._updateTimeout) {
|
|
7181
|
-
clearTimeout(this._updateTimeout);
|
|
7182
|
-
this._updateTimeout = null;
|
|
7183
|
-
}
|
|
7184
|
-
// Null all services
|
|
7185
|
-
this.validationService = null;
|
|
7186
|
-
this.coordinateService = null;
|
|
7187
|
-
this.positionService = null;
|
|
7188
|
-
this.boardService = null;
|
|
7189
|
-
this.pieceService = null;
|
|
7190
|
-
this.animationService = null;
|
|
7191
|
-
this.moveService = null;
|
|
7192
|
-
this.eventService = null;
|
|
7193
|
-
}
|
|
7194
|
-
|
|
7195
7186
|
/**
|
|
7196
7187
|
* Initializes all services
|
|
7197
7188
|
* @private
|
|
@@ -7260,23 +7251,8 @@ let Chessboard$1 = class Chessboard {
|
|
|
7260
7251
|
/**
|
|
7261
7252
|
* Builds the board DOM structure
|
|
7262
7253
|
* @private
|
|
7263
|
-
* Best practice: always remove squares (destroy JS/DOM) before clearing the board container.
|
|
7264
7254
|
*/
|
|
7265
7255
|
_buildBoard() {
|
|
7266
|
-
console.log('CHIAMATO: _buildBoard');
|
|
7267
|
-
if (this._isUndoRedo) {
|
|
7268
|
-
console.log('SKIP _buildBoard per undo/redo');
|
|
7269
|
-
return;
|
|
7270
|
-
}
|
|
7271
|
-
// Forza la pulizia completa del contenitore board (DOM)
|
|
7272
|
-
const boardContainer = document.getElementById(this.config.id_div);
|
|
7273
|
-
if (boardContainer) boardContainer.innerHTML = '';
|
|
7274
|
-
// Force remove all pieces from all squares (no animation, best practice)
|
|
7275
|
-
if (this.boardService && this.boardService.squares) {
|
|
7276
|
-
Object.values(this.boardService.squares).forEach(sq => sq && sq.forceRemoveAllPieces && sq.forceRemoveAllPieces());
|
|
7277
|
-
}
|
|
7278
|
-
if (this.boardService && this.boardService.removeSquares) this.boardService.removeSquares();
|
|
7279
|
-
if (this.boardService && this.boardService.removeBoard) this.boardService.removeBoard();
|
|
7280
7256
|
this.boardService.buildBoard();
|
|
7281
7257
|
}
|
|
7282
7258
|
|
|
@@ -7285,14 +7261,6 @@ let Chessboard$1 = class Chessboard {
|
|
|
7285
7261
|
* @private
|
|
7286
7262
|
*/
|
|
7287
7263
|
_buildSquares() {
|
|
7288
|
-
console.log('CHIAMATO: _buildSquares');
|
|
7289
|
-
if (this._isUndoRedo) {
|
|
7290
|
-
console.log('SKIP _buildSquares per undo/redo');
|
|
7291
|
-
return;
|
|
7292
|
-
}
|
|
7293
|
-
if (this.boardService && this.boardService.removeSquares) {
|
|
7294
|
-
this.boardService.removeSquares();
|
|
7295
|
-
}
|
|
7296
7264
|
this.boardService.buildSquares((row, col) => {
|
|
7297
7265
|
return this.coordinateService.realCoord(row, col);
|
|
7298
7266
|
});
|
|
@@ -7662,7 +7630,6 @@ let Chessboard$1 = class Chessboard {
|
|
|
7662
7630
|
* @param {boolean} [isPositionLoad=false] - Whether this is a position load
|
|
7663
7631
|
*/
|
|
7664
7632
|
_updateBoardPieces(animation = false, isPositionLoad = false) {
|
|
7665
|
-
console.log('CHIAMATO: _updateBoardPieces', { animation, isPositionLoad, isUndoRedo: this._isUndoRedo });
|
|
7666
7633
|
// Check if services are available
|
|
7667
7634
|
if (!this.positionService || !this.moveService || !this.eventService) {
|
|
7668
7635
|
console.log('Cannot update board pieces - services not available');
|
|
@@ -7728,48 +7695,35 @@ let Chessboard$1 = class Chessboard {
|
|
|
7728
7695
|
* @param {boolean} [isPositionLoad=false] - Whether this is a position load (affects delay)
|
|
7729
7696
|
*/
|
|
7730
7697
|
_doUpdateBoardPieces(animation = false, isPositionLoad = false) {
|
|
7731
|
-
// Blocca update se un drag è in corso
|
|
7732
|
-
if (this._isDragging) return;
|
|
7733
7698
|
// Skip update if we're in the middle of a promotion
|
|
7734
7699
|
if (this._isPromoting) {
|
|
7700
|
+
console.log('Skipping board update during promotion');
|
|
7735
7701
|
return;
|
|
7736
7702
|
}
|
|
7703
|
+
|
|
7704
|
+
// Check if services are available
|
|
7737
7705
|
if (!this.positionService || !this.positionService.getGame()) {
|
|
7706
|
+
console.log('Cannot update board pieces - position service not available');
|
|
7738
7707
|
return;
|
|
7739
7708
|
}
|
|
7709
|
+
|
|
7740
7710
|
const squares = this.boardService.getAllSquares();
|
|
7741
7711
|
const gameStateBefore = this.positionService.getGame().fen();
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
element.remove();
|
|
7748
|
-
});
|
|
7749
|
-
}
|
|
7750
|
-
Object.values(squares).forEach(sq => {
|
|
7751
|
-
if (sq && sq.piece) {
|
|
7752
|
-
sq.piece = null;
|
|
7753
|
-
}
|
|
7754
|
-
});
|
|
7755
|
-
this._clearVisualState();
|
|
7756
|
-
this._addListeners();
|
|
7757
|
-
if (this.config.onChange) this.config.onChange(gameStateBefore);
|
|
7758
|
-
return;
|
|
7759
|
-
}
|
|
7712
|
+
|
|
7713
|
+
console.log('_doUpdateBoardPieces - current FEN:', gameStateBefore);
|
|
7714
|
+
console.log('_doUpdateBoardPieces - animation:', animation, 'style:', this.config.animationStyle, 'isPositionLoad:', isPositionLoad);
|
|
7715
|
+
|
|
7716
|
+
// Determine which animation style to use
|
|
7760
7717
|
const useSimultaneous = this.config.animationStyle === 'simultaneous';
|
|
7718
|
+
console.log('_doUpdateBoardPieces - useSimultaneous:', useSimultaneous);
|
|
7719
|
+
|
|
7761
7720
|
if (useSimultaneous) {
|
|
7721
|
+
console.log('Using simultaneous animation');
|
|
7762
7722
|
this._doSimultaneousUpdate(squares, gameStateBefore, isPositionLoad);
|
|
7763
7723
|
} else {
|
|
7724
|
+
console.log('Using sequential animation');
|
|
7764
7725
|
this._doSequentialUpdate(squares, gameStateBefore, animation);
|
|
7765
7726
|
}
|
|
7766
|
-
// Pulizia finale robusta: rimuovi tutti i pezzi orfani dal DOM e dal riferimento JS
|
|
7767
|
-
Object.values(this.boardService.getAllSquares()).forEach(square => {
|
|
7768
|
-
const expectedPieceId = this.positionService.getGamePieceId(square.id);
|
|
7769
|
-
if (!expectedPieceId && typeof square.forceRemoveAllPieces === 'function') {
|
|
7770
|
-
square.forceRemoveAllPieces();
|
|
7771
|
-
}
|
|
7772
|
-
});
|
|
7773
7727
|
}
|
|
7774
7728
|
|
|
7775
7729
|
/**
|
|
@@ -7780,45 +7734,43 @@ let Chessboard$1 = class Chessboard {
|
|
|
7780
7734
|
* @param {boolean} animation - Whether to animate
|
|
7781
7735
|
*/
|
|
7782
7736
|
_doSequentialUpdate(squares, gameStateBefore, animation) {
|
|
7783
|
-
//
|
|
7784
|
-
const expectedMap = {};
|
|
7785
|
-
Object.values(squares).forEach(square => {
|
|
7786
|
-
expectedMap[square.id] = this.positionService.getGamePieceId(square.id);
|
|
7787
|
-
});
|
|
7788
|
-
|
|
7737
|
+
// Update each square sequentially
|
|
7789
7738
|
Object.values(squares).forEach(square => {
|
|
7790
|
-
const expectedPieceId =
|
|
7739
|
+
const expectedPieceId = this.positionService.getGamePieceId(square.id);
|
|
7791
7740
|
const currentPiece = square.piece;
|
|
7792
7741
|
const currentPieceId = currentPiece ? currentPiece.getId() : null;
|
|
7793
7742
|
|
|
7794
|
-
//
|
|
7795
|
-
if (currentPieceId
|
|
7796
|
-
|
|
7797
|
-
}
|
|
7743
|
+
// Log only for squares that are changing
|
|
7744
|
+
if (currentPieceId !== expectedPieceId) {
|
|
7745
|
+
console.log(`_doSequentialUpdate - ${square.id}: ${currentPieceId} -> ${expectedPieceId}`);
|
|
7798
7746
|
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
if (typeof square.forceRemoveAllPieces === 'function') {
|
|
7803
|
-
square.forceRemoveAllPieces();
|
|
7747
|
+
// Check if we already have the correct piece (from promotion)
|
|
7748
|
+
if (currentPiece && currentPiece.getId() === expectedPieceId) {
|
|
7749
|
+
console.log(`Piece ${expectedPieceId} already correctly placed on ${square.id}`);
|
|
7804
7750
|
} else {
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
|
|
7751
|
+
// Remove current piece if exists
|
|
7752
|
+
if (currentPiece) {
|
|
7753
|
+
this.pieceService.removePieceFromSquare(square, animation);
|
|
7754
|
+
}
|
|
7808
7755
|
|
|
7809
|
-
|
|
7810
|
-
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7817
|
-
|
|
7756
|
+
// Add new piece if needed
|
|
7757
|
+
if (expectedPieceId) {
|
|
7758
|
+
const newPiece = this.pieceService.convertPiece(expectedPieceId);
|
|
7759
|
+
this.pieceService.addPieceOnSquare(
|
|
7760
|
+
square,
|
|
7761
|
+
newPiece,
|
|
7762
|
+
animation,
|
|
7763
|
+
this._createDragFunction.bind(this)
|
|
7764
|
+
);
|
|
7765
|
+
}
|
|
7766
|
+
}
|
|
7818
7767
|
}
|
|
7819
7768
|
});
|
|
7820
7769
|
|
|
7770
|
+
// Re-add listeners after updating pieces to ensure hover events work correctly
|
|
7821
7771
|
this._addListeners();
|
|
7772
|
+
|
|
7773
|
+
// Trigger change event if position changed
|
|
7822
7774
|
const gameStateAfter = this.positionService.getGame().fen();
|
|
7823
7775
|
if (gameStateBefore !== gameStateAfter) {
|
|
7824
7776
|
this.config.onChange(gameStateAfter);
|
|
@@ -7833,38 +7785,16 @@ let Chessboard$1 = class Chessboard {
|
|
|
7833
7785
|
* @param {boolean} [isPositionLoad=false] - Whether this is a position load
|
|
7834
7786
|
*/
|
|
7835
7787
|
_doSimultaneousUpdate(squares, gameStateBefore, isPositionLoad = false) {
|
|
7836
|
-
|
|
7837
|
-
const currentMap = {};
|
|
7838
|
-
const expectedMap = {};
|
|
7839
|
-
|
|
7840
|
-
Object.values(squares).forEach(square => {
|
|
7841
|
-
const currentPiece = square.piece;
|
|
7842
|
-
const expectedPieceId = this.positionService.getGamePieceId(square.id);
|
|
7843
|
-
if (currentPiece) {
|
|
7844
|
-
// Normalizza la chiave come 'color+type' lowercase
|
|
7845
|
-
const key = (currentPiece.color + currentPiece.type).toLowerCase();
|
|
7846
|
-
if (!currentMap[key]) currentMap[key] = [];
|
|
7847
|
-
currentMap[key].push({ square, id: square.id });
|
|
7848
|
-
}
|
|
7849
|
-
if (expectedPieceId) {
|
|
7850
|
-
// Normalizza la chiave come 'color+type' lowercase
|
|
7851
|
-
const key = expectedPieceId.toLowerCase();
|
|
7852
|
-
if (!expectedMap[key]) expectedMap[key] = [];
|
|
7853
|
-
expectedMap[key].push({ square, id: square.id });
|
|
7854
|
-
}
|
|
7855
|
-
});
|
|
7788
|
+
console.log('_doSimultaneousUpdate - Starting simultaneous update');
|
|
7856
7789
|
|
|
7857
|
-
|
|
7858
|
-
|
|
7859
|
-
const animationDelay = isPositionLoad ? 0 : this.config.simultaneousAnimationDelay;
|
|
7860
|
-
let animationIndex = 0;
|
|
7790
|
+
// Analyze what changes need to be made
|
|
7791
|
+
const changeAnalysis = this._analyzePositionChanges(squares);
|
|
7861
7792
|
|
|
7862
|
-
|
|
7863
|
-
|
|
7864
|
-
});
|
|
7865
|
-
|
|
7866
|
-
if (totalAnimations === 0) {
|
|
7793
|
+
if (changeAnalysis.totalChanges === 0) {
|
|
7794
|
+
console.log('_doSimultaneousUpdate - No changes needed, returning');
|
|
7867
7795
|
this._addListeners();
|
|
7796
|
+
|
|
7797
|
+
// Trigger change event if position changed
|
|
7868
7798
|
const gameStateAfter = this.positionService.getGame().fen();
|
|
7869
7799
|
if (gameStateBefore !== gameStateAfter) {
|
|
7870
7800
|
this.config.onChange(gameStateAfter);
|
|
@@ -7872,109 +7802,10 @@ let Chessboard$1 = class Chessboard {
|
|
|
7872
7802
|
return;
|
|
7873
7803
|
}
|
|
7874
7804
|
|
|
7875
|
-
|
|
7876
|
-
animationsCompleted++;
|
|
7877
|
-
if (animationsCompleted === totalAnimations) {
|
|
7878
|
-
this._addListeners();
|
|
7879
|
-
const gameStateAfter = this.positionService.getGame().fen();
|
|
7880
|
-
if (gameStateBefore !== gameStateAfter) {
|
|
7881
|
-
this.config.onChange(gameStateAfter);
|
|
7882
|
-
}
|
|
7883
|
-
}
|
|
7884
|
-
};
|
|
7885
|
-
|
|
7886
|
-
Object.keys(expectedMap).forEach(key => {
|
|
7887
|
-
const fromList = (currentMap[key] || []).slice();
|
|
7888
|
-
const toList = expectedMap[key].slice();
|
|
7889
|
-
|
|
7890
|
-
// 1. Costruisci matrice delle distanze
|
|
7891
|
-
const distances = [];
|
|
7892
|
-
for (let i = 0; i < fromList.length; i++) {
|
|
7893
|
-
distances[i] = [];
|
|
7894
|
-
for (let j = 0; j < toList.length; j++) {
|
|
7895
|
-
distances[i][j] = Math.abs(fromList[i].square.row - toList[j].square.row) +
|
|
7896
|
-
Math.abs(fromList[i].square.col - toList[j].square.col);
|
|
7897
|
-
}
|
|
7898
|
-
}
|
|
7899
|
-
|
|
7900
|
-
// 2. Matching greedy: abbina i più vicini
|
|
7901
|
-
const fromMatched = new Array(fromList.length).fill(false);
|
|
7902
|
-
const toMatched = new Array(toList.length).fill(false);
|
|
7903
|
-
const moves = [];
|
|
7904
|
-
|
|
7905
|
-
while (true) {
|
|
7906
|
-
let minDist = Infinity, minI = -1, minJ = -1;
|
|
7907
|
-
for (let i = 0; i < fromList.length; i++) {
|
|
7908
|
-
if (fromMatched[i]) continue;
|
|
7909
|
-
for (let j = 0; j < toList.length; j++) {
|
|
7910
|
-
if (toMatched[j]) continue;
|
|
7911
|
-
if (distances[i][j] < minDist) {
|
|
7912
|
-
minDist = distances[i][j];
|
|
7913
|
-
minI = i;
|
|
7914
|
-
minJ = j;
|
|
7915
|
-
}
|
|
7916
|
-
}
|
|
7917
|
-
}
|
|
7918
|
-
if (minI === -1 || minJ === -1) break;
|
|
7919
|
-
// Se la posizione è la stessa, non fare nulla (pezzo unchanged)
|
|
7920
|
-
if (fromList[minI].square === toList[minJ].square) {
|
|
7921
|
-
fromMatched[minI] = true;
|
|
7922
|
-
toMatched[minJ] = true;
|
|
7923
|
-
continue;
|
|
7924
|
-
}
|
|
7925
|
-
// Altrimenti, sposta il pezzo
|
|
7926
|
-
moves.push({ from: fromList[minI].square, to: toList[minJ].square, piece: fromList[minI].square.piece });
|
|
7927
|
-
fromMatched[minI] = true;
|
|
7928
|
-
toMatched[minJ] = true;
|
|
7929
|
-
}
|
|
7930
|
-
|
|
7931
|
-
// 3. Rimuovi i pezzi non abbinati (presenti solo in fromList)
|
|
7932
|
-
for (let i = 0; i < fromList.length; i++) {
|
|
7933
|
-
if (!fromMatched[i]) {
|
|
7934
|
-
setTimeout(() => {
|
|
7935
|
-
// Rimozione robusta: elimina tutti i pezzi orfani dal DOM e dal riferimento JS
|
|
7936
|
-
if (typeof fromList[i].square.forceRemoveAllPieces === 'function') {
|
|
7937
|
-
fromList[i].square.forceRemoveAllPieces();
|
|
7938
|
-
} else {
|
|
7939
|
-
this.pieceService.removePieceFromSquare(fromList[i].square, true, onAnimationComplete);
|
|
7940
|
-
}
|
|
7941
|
-
onAnimationComplete();
|
|
7942
|
-
}, animationIndex * animationDelay);
|
|
7943
|
-
animationIndex++;
|
|
7944
|
-
}
|
|
7945
|
-
}
|
|
7946
|
-
|
|
7947
|
-
// 4. Aggiungi i pezzi non abbinati (presenti solo in toList)
|
|
7948
|
-
for (let j = 0; j < toList.length; j++) {
|
|
7949
|
-
if (!toMatched[j]) {
|
|
7950
|
-
setTimeout(() => {
|
|
7951
|
-
const newPiece = this.pieceService.convertPiece(key);
|
|
7952
|
-
this.pieceService.addPieceOnSquare(
|
|
7953
|
-
toList[j].square,
|
|
7954
|
-
newPiece,
|
|
7955
|
-
true,
|
|
7956
|
-
this._createDragFunction.bind(this),
|
|
7957
|
-
onAnimationComplete
|
|
7958
|
-
);
|
|
7959
|
-
}, animationIndex * animationDelay);
|
|
7960
|
-
animationIndex++;
|
|
7961
|
-
}
|
|
7962
|
-
}
|
|
7805
|
+
console.log('_doSimultaneousUpdate - Change analysis:', changeAnalysis);
|
|
7963
7806
|
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
setTimeout(() => {
|
|
7967
|
-
this.pieceService.translatePiece(
|
|
7968
|
-
move,
|
|
7969
|
-
false,
|
|
7970
|
-
true,
|
|
7971
|
-
this._createDragFunction.bind(this),
|
|
7972
|
-
onAnimationComplete
|
|
7973
|
-
);
|
|
7974
|
-
}, animationIndex * animationDelay);
|
|
7975
|
-
animationIndex++;
|
|
7976
|
-
});
|
|
7977
|
-
});
|
|
7807
|
+
// Execute all changes simultaneously
|
|
7808
|
+
this._executeSimultaneousChanges(changeAnalysis, gameStateBefore, isPositionLoad);
|
|
7978
7809
|
}
|
|
7979
7810
|
|
|
7980
7811
|
/**
|
|
@@ -8300,380 +8131,99 @@ let Chessboard$1 = class Chessboard {
|
|
|
8300
8131
|
}
|
|
8301
8132
|
|
|
8302
8133
|
// -------------------
|
|
8303
|
-
// Public API Methods
|
|
8134
|
+
// Public API Methods
|
|
8304
8135
|
// -------------------
|
|
8305
8136
|
|
|
8306
|
-
// --- POSITION & STATE ---
|
|
8307
8137
|
/**
|
|
8308
|
-
*
|
|
8309
|
-
* @returns {string}
|
|
8310
|
-
*/
|
|
8311
|
-
getPosition() { return this.fen(); }
|
|
8312
|
-
/**
|
|
8313
|
-
* Set the board position (FEN or object)
|
|
8314
|
-
* @param {string|Object} position
|
|
8315
|
-
* @param {Object} [opts]
|
|
8316
|
-
* @param {boolean} [opts.animate=true]
|
|
8317
|
-
* @returns {boolean}
|
|
8318
|
-
*/
|
|
8319
|
-
setPosition(position, opts = {}) {
|
|
8320
|
-
const animate = opts.animate !== undefined ? opts.animate : true;
|
|
8321
|
-
// Remove highlights and selections
|
|
8322
|
-
if (this.boardService && this.boardService.applyToAllSquares) {
|
|
8323
|
-
this.boardService.applyToAllSquares('removeHint');
|
|
8324
|
-
this.boardService.applyToAllSquares('deselect');
|
|
8325
|
-
this.boardService.applyToAllSquares('unmoved');
|
|
8326
|
-
}
|
|
8327
|
-
if (this.positionService && this.positionService.setGame) {
|
|
8328
|
-
this.positionService.setGame(position);
|
|
8329
|
-
}
|
|
8330
|
-
if (this._updateBoardPieces) {
|
|
8331
|
-
this._updateBoardPieces(animate, true);
|
|
8332
|
-
}
|
|
8333
|
-
// Forza la sincronizzazione dopo setPosition
|
|
8334
|
-
this._updateBoardPieces(true, false);
|
|
8335
|
-
return true;
|
|
8336
|
-
}
|
|
8337
|
-
/**
|
|
8338
|
-
* Reset the board to the starting position
|
|
8339
|
-
* @param {Object} [opts]
|
|
8340
|
-
* @param {boolean} [opts.animate=true]
|
|
8341
|
-
* @returns {boolean}
|
|
8342
|
-
*/
|
|
8343
|
-
reset(opts = {}) {
|
|
8344
|
-
const animate = opts.animate !== undefined ? opts.animate : true;
|
|
8345
|
-
// Use the default starting position from config or fallback
|
|
8346
|
-
const startPosition = this.config && this.config.position ? this.config.position : 'start';
|
|
8347
|
-
this._updateBoardPieces(animate);
|
|
8348
|
-
const result = this.setPosition(startPosition, { animate });
|
|
8349
|
-
// Forza la sincronizzazione dopo reset
|
|
8350
|
-
this._updateBoardPieces(true, false);
|
|
8351
|
-
return result;
|
|
8352
|
-
}
|
|
8353
|
-
/**
|
|
8354
|
-
* Clear the board
|
|
8355
|
-
* @param {Object} [opts]
|
|
8356
|
-
* @param {boolean} [opts.animate=true]
|
|
8357
|
-
* @returns {boolean}
|
|
8138
|
+
* Gets the current position as FEN
|
|
8139
|
+
* @returns {string} FEN string
|
|
8358
8140
|
*/
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
if (!this.positionService || !this.positionService.getGame()) {
|
|
8362
|
-
return false;
|
|
8363
|
-
}
|
|
8364
|
-
if (this._clearVisualState) this._clearVisualState();
|
|
8365
|
-
this.positionService.getGame().clear();
|
|
8366
|
-
// Forza la rimozione di tutti i pezzi dal DOM
|
|
8367
|
-
if (this.boardService && this.boardService.squares) {
|
|
8368
|
-
Object.values(this.boardService.squares).forEach(sq => {
|
|
8369
|
-
if (sq && sq.piece) sq.piece = null;
|
|
8370
|
-
});
|
|
8371
|
-
}
|
|
8372
|
-
if (this._updateBoardPieces) {
|
|
8373
|
-
this._updateBoardPieces(animate, true);
|
|
8374
|
-
}
|
|
8375
|
-
// Forza la sincronizzazione dopo clear
|
|
8376
|
-
this._updateBoardPieces(true, false);
|
|
8377
|
-
return true;
|
|
8141
|
+
fen() {
|
|
8142
|
+
return this.positionService.getGame().fen();
|
|
8378
8143
|
}
|
|
8379
8144
|
|
|
8380
|
-
// --- MOVE MANAGEMENT ---
|
|
8381
8145
|
/**
|
|
8382
|
-
*
|
|
8383
|
-
* @
|
|
8384
|
-
* @param {boolean} [opts.animate=true]
|
|
8385
|
-
* @returns {boolean}
|
|
8146
|
+
* Gets current turn
|
|
8147
|
+
* @returns {string} 'w' or 'b'
|
|
8386
8148
|
*/
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
if (undone) {
|
|
8390
|
-
this._undoneMoves.push(undone);
|
|
8391
|
-
// Forza refresh completo di tutti i pezzi dopo undo
|
|
8392
|
-
this._updateBoardPieces(true, true);
|
|
8393
|
-
return undone;
|
|
8394
|
-
}
|
|
8395
|
-
return null;
|
|
8396
|
-
}
|
|
8397
|
-
/**
|
|
8398
|
-
* Redo last undone move
|
|
8399
|
-
* @param {Object} [opts]
|
|
8400
|
-
* @param {boolean} [opts.animate=true]
|
|
8401
|
-
* @returns {boolean}
|
|
8402
|
-
*/
|
|
8403
|
-
redoMove(opts = {}) {
|
|
8404
|
-
if (this._undoneMoves && this._undoneMoves.length > 0) {
|
|
8405
|
-
const move = this._undoneMoves.pop();
|
|
8406
|
-
const moveObj = { from: move.from, to: move.to };
|
|
8407
|
-
if (move.promotion) moveObj.promotion = move.promotion;
|
|
8408
|
-
const result = this.positionService.getGame().move(moveObj);
|
|
8409
|
-
// Forza refresh completo di tutti i pezzi dopo redo
|
|
8410
|
-
this._updateBoardPieces(true, true);
|
|
8411
|
-
return result;
|
|
8412
|
-
}
|
|
8413
|
-
return false;
|
|
8149
|
+
turn() {
|
|
8150
|
+
return this.positionService.getGame().turn();
|
|
8414
8151
|
}
|
|
8415
|
-
/**
|
|
8416
|
-
* Get legal moves for a square
|
|
8417
|
-
* @param {string} square
|
|
8418
|
-
* @returns {Array}
|
|
8419
|
-
*/
|
|
8420
|
-
getLegalMoves(square) { return this.legalMoves(square); }
|
|
8421
8152
|
|
|
8422
|
-
// --- PIECE MANAGEMENT ---
|
|
8423
8153
|
/**
|
|
8424
|
-
*
|
|
8425
|
-
* @param {string}
|
|
8426
|
-
* @
|
|
8427
|
-
|
|
8428
|
-
getPiece(square) {
|
|
8429
|
-
// Sempre leggi lo stato aggiornato dal boardService
|
|
8430
|
-
const squareObj = typeof square === 'string' ? this.boardService.getSquare(square) : square;
|
|
8431
|
-
if (!squareObj || typeof squareObj !== 'object' || !('id' in squareObj)) throw new Error('[getPiece] Parametro square non valido');
|
|
8432
|
-
// Forza sync prima di leggere
|
|
8433
|
-
this._updateBoardPieces(false, false);
|
|
8434
|
-
const piece = squareObj.piece;
|
|
8435
|
-
if (!piece) return null;
|
|
8436
|
-
return (piece.color + piece.type).toLowerCase();
|
|
8437
|
-
}
|
|
8438
|
-
/**
|
|
8439
|
-
* Put a piece on a square
|
|
8440
|
-
* @param {string|Piece} piece
|
|
8441
|
-
* @param {string|Square} square
|
|
8442
|
-
* @param {Object} [opts]
|
|
8443
|
-
* @param {boolean} [opts.animate=true]
|
|
8444
|
-
* @returns {boolean}
|
|
8154
|
+
* Loads a new position
|
|
8155
|
+
* @param {string|Object} position - Position to load
|
|
8156
|
+
* @param {Object} [options={}] - Loading options
|
|
8157
|
+
* @param {boolean} [animation=true] - Whether to animate
|
|
8445
8158
|
*/
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
pieceStr = (piece.color + piece.type).toLowerCase();
|
|
8451
|
-
} else if (typeof piece === 'string' && piece.length === 2) {
|
|
8452
|
-
const a = piece[0].toLowerCase();
|
|
8453
|
-
const b = piece[1].toLowerCase();
|
|
8454
|
-
const types = 'kqrbnp';
|
|
8455
|
-
const colors = 'wb';
|
|
8456
|
-
if (types.includes(a) && colors.includes(b)) {
|
|
8457
|
-
pieceStr = b + a;
|
|
8458
|
-
} else if (colors.includes(a) && types.includes(b)) {
|
|
8459
|
-
pieceStr = a + b;
|
|
8460
|
-
} else {
|
|
8461
|
-
throw new Error(`[putPiece] Invalid piece: ${piece}`);
|
|
8462
|
-
}
|
|
8463
|
-
}
|
|
8464
|
-
const squareObj = typeof square === 'string' ? this.boardService.getSquare(square) : square;
|
|
8465
|
-
if (!squareObj || typeof squareObj !== 'object' || !('id' in squareObj)) throw new Error('[putPiece] Parametro square non valido');
|
|
8466
|
-
const pieceObj = this.pieceService.convertPiece(pieceStr);
|
|
8467
|
-
if (!pieceObj || typeof pieceObj !== 'object' || !('type' in pieceObj)) throw new Error('[putPiece] Parametro piece non valido');
|
|
8468
|
-
// Aggiorna solo il motore chess.js
|
|
8469
|
-
const chessJsPiece = { type: pieceObj.type, color: pieceObj.color };
|
|
8470
|
-
const game = this.positionService.getGame();
|
|
8471
|
-
const result = game.put(chessJsPiece, squareObj.id);
|
|
8472
|
-
if (!result) throw new Error(`[putPiece] Game.put failed for ${pieceStr} on ${squareObj.id}`);
|
|
8473
|
-
// Non aggiornare direttamente square.piece!
|
|
8474
|
-
// Riallinea la board JS allo stato del motore
|
|
8475
|
-
this._updateBoardPieces(animate);
|
|
8476
|
-
return true;
|
|
8477
|
-
}
|
|
8478
|
-
/**
|
|
8479
|
-
* Remove a piece from a square
|
|
8480
|
-
* @param {string|Square} square
|
|
8481
|
-
* @param {Object} [opts]
|
|
8482
|
-
* @param {boolean} [opts.animate=true]
|
|
8483
|
-
* @returns {string|null}
|
|
8484
|
-
*/
|
|
8485
|
-
removePiece(square, opts = {}) {
|
|
8486
|
-
const animate = opts.animate !== undefined ? opts.animate : true;
|
|
8487
|
-
const squareObj = typeof square === 'string' ? this.boardService.getSquare(square) : square;
|
|
8488
|
-
if (!squareObj || typeof squareObj !== 'object' || !('id' in squareObj)) throw new Error('[removePiece] Parametro square non valido');
|
|
8489
|
-
// Aggiorna solo il motore chess.js
|
|
8490
|
-
const game = this.positionService.getGame();
|
|
8491
|
-
game.remove(squareObj.id);
|
|
8492
|
-
// Non aggiornare direttamente square.piece!
|
|
8493
|
-
// Riallinea la board JS allo stato del motore
|
|
8494
|
-
this._updateBoardPieces(animate);
|
|
8495
|
-
return true;
|
|
8496
|
-
}
|
|
8159
|
+
load(position, options = {}, animation = true) {
|
|
8160
|
+
this.boardService.applyToAllSquares('removeHint');
|
|
8161
|
+
this.boardService.applyToAllSquares('deselect');
|
|
8162
|
+
this.boardService.applyToAllSquares('unmoved');
|
|
8497
8163
|
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
* Flip the board orientation
|
|
8501
|
-
* @param {Object} [opts]
|
|
8502
|
-
* @param {boolean} [opts.animate=true]
|
|
8503
|
-
*/
|
|
8504
|
-
flipBoard(opts = {}) {
|
|
8505
|
-
if (this.coordinateService && this.coordinateService.flipOrientation) {
|
|
8506
|
-
this.coordinateService.flipOrientation();
|
|
8507
|
-
}
|
|
8508
|
-
if (this._buildBoard) this._buildBoard();
|
|
8509
|
-
if (this._buildSquares) this._buildSquares();
|
|
8510
|
-
if (this._addListeners) this._addListeners();
|
|
8511
|
-
if (this._updateBoardPieces) this._updateBoardPieces(opts.animate !== false);
|
|
8512
|
-
console.log('FEN dopo flip:', this.fen(), 'Orientamento:', this.coordinateService.getOrientation());
|
|
8513
|
-
}
|
|
8514
|
-
/**
|
|
8515
|
-
* Set the board orientation
|
|
8516
|
-
* @param {'w'|'b'} color
|
|
8517
|
-
* @param {Object} [opts]
|
|
8518
|
-
* @param {boolean} [opts.animate=true]
|
|
8519
|
-
*/
|
|
8520
|
-
setOrientation(color, opts = {}) {
|
|
8521
|
-
if (this.validationService.isValidOrientation(color)) {
|
|
8522
|
-
this.coordinateService.setOrientation(color);
|
|
8523
|
-
if (this._buildBoard) this._buildBoard();
|
|
8524
|
-
if (this._buildSquares) this._buildSquares();
|
|
8525
|
-
if (this._addListeners) this._addListeners();
|
|
8526
|
-
if (this._updateBoardPieces) this._updateBoardPieces(opts.animate !== false);
|
|
8527
|
-
}
|
|
8528
|
-
return this.coordinateService.getOrientation();
|
|
8529
|
-
}
|
|
8530
|
-
/**
|
|
8531
|
-
* Get the current orientation
|
|
8532
|
-
* @returns {'w'|'b'}
|
|
8533
|
-
*/
|
|
8534
|
-
getOrientation() { return this.orientation(); }
|
|
8535
|
-
/**
|
|
8536
|
-
* Resize the board
|
|
8537
|
-
* @param {number|string} size
|
|
8538
|
-
*/
|
|
8539
|
-
resizeBoard(size) {
|
|
8540
|
-
if (size === 'auto') {
|
|
8541
|
-
this.config.size = 'auto';
|
|
8542
|
-
document.documentElement.style.setProperty('--dimBoard', 'auto');
|
|
8543
|
-
this._updateBoardPieces(false);
|
|
8544
|
-
return true;
|
|
8545
|
-
}
|
|
8546
|
-
if (typeof size !== 'number' || size < 50 || size > 3000) {
|
|
8547
|
-
throw new Error(`[resizeBoard] Invalid size: ${size}`);
|
|
8548
|
-
}
|
|
8549
|
-
this.config.size = size;
|
|
8550
|
-
document.documentElement.style.setProperty('--dimBoard', `${size}px`);
|
|
8551
|
-
this._updateBoardPieces(false);
|
|
8552
|
-
return true;
|
|
8164
|
+
this.positionService.setGame(position, options);
|
|
8165
|
+
this._updateBoardPieces(animation, true); // Position load
|
|
8553
8166
|
}
|
|
8554
8167
|
|
|
8555
|
-
// --- HIGHLIGHTING & UI ---
|
|
8556
8168
|
/**
|
|
8557
|
-
*
|
|
8558
|
-
* @param {string|Square} square
|
|
8559
|
-
* @param {Object} [opts]
|
|
8169
|
+
* Destroys the board and cleans up resources
|
|
8560
8170
|
*/
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
|
|
8566
|
-
|
|
8567
|
-
|
|
8568
|
-
|
|
8569
|
-
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
|
|
8573
|
-
* @param {string|Square} square
|
|
8574
|
-
* @param {Object} [opts]
|
|
8575
|
-
*/
|
|
8576
|
-
dehighlight(square, opts = {}) {
|
|
8577
|
-
// API: accetta id, converte subito in oggetto
|
|
8578
|
-
const squareObj = typeof square === 'string' ? this.boardService.getSquare(square) : square;
|
|
8579
|
-
if (!squareObj || typeof squareObj !== 'object' || !('id' in squareObj)) throw new Error('[dehighlight] Parametro square non valido');
|
|
8580
|
-
if (this.boardService && this.boardService.dehighlightSquare) {
|
|
8581
|
-
this.boardService.dehighlightSquare(squareObj, opts);
|
|
8582
|
-
} else if (this.eventService && this.eventService.dehighlightSquare) {
|
|
8583
|
-
this.eventService.dehighlightSquare(squareObj, opts);
|
|
8171
|
+
destroy() {
|
|
8172
|
+
this.eventService.destroy();
|
|
8173
|
+
this.boardService.destroy();
|
|
8174
|
+
this.positionService.destroy();
|
|
8175
|
+
this.pieceService.destroy();
|
|
8176
|
+
this.moveService.destroy();
|
|
8177
|
+
this.animationService.destroy();
|
|
8178
|
+
this.validationService.destroy();
|
|
8179
|
+
|
|
8180
|
+
if (this._updateTimeout) {
|
|
8181
|
+
clearTimeout(this._updateTimeout);
|
|
8182
|
+
this._updateTimeout = null;
|
|
8584
8183
|
}
|
|
8585
8184
|
}
|
|
8586
8185
|
|
|
8587
|
-
// --- GAME INFO ---
|
|
8588
|
-
/**
|
|
8589
|
-
* Get FEN string
|
|
8590
|
-
* @returns {string}
|
|
8591
|
-
*/
|
|
8592
|
-
fen() {
|
|
8593
|
-
// Avoid recursion: call the underlying game object's fen()
|
|
8594
|
-
const game = this.positionService.getGame();
|
|
8595
|
-
if (!game || typeof game.fen !== 'function') return '';
|
|
8596
|
-
return game.fen();
|
|
8597
|
-
}
|
|
8598
8186
|
/**
|
|
8599
|
-
*
|
|
8600
|
-
* @
|
|
8187
|
+
* Resizes the board
|
|
8188
|
+
* @param {number|string} size - New size
|
|
8601
8189
|
*/
|
|
8602
|
-
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
* @returns {boolean}
|
|
8606
|
-
*/
|
|
8607
|
-
isGameOver() {
|
|
8608
|
-
// Forza sync prima di interrogare il motore
|
|
8609
|
-
this._updateBoardPieces(false, false);
|
|
8610
|
-
const game = this.positionService.getGame();
|
|
8611
|
-
if (!game) return false;
|
|
8612
|
-
if (game.isGameOver) return game.isGameOver();
|
|
8613
|
-
// Fallback: checkmate or draw
|
|
8614
|
-
if (game.isCheckmate && game.isCheckmate()) return true;
|
|
8615
|
-
if (game.isDraw && game.isDraw()) return true;
|
|
8616
|
-
return false;
|
|
8617
|
-
}
|
|
8618
|
-
/**
|
|
8619
|
-
* Is it checkmate?
|
|
8620
|
-
* @returns {boolean}
|
|
8621
|
-
*/
|
|
8622
|
-
isCheckmate() {
|
|
8623
|
-
const game = this.positionService.getGame();
|
|
8624
|
-
if (!game) return false;
|
|
8625
|
-
return game.isCheckmate ? game.isCheckmate() : false;
|
|
8626
|
-
}
|
|
8627
|
-
/**
|
|
8628
|
-
* Is it draw?
|
|
8629
|
-
* @returns {boolean}
|
|
8630
|
-
*/
|
|
8631
|
-
isDraw() {
|
|
8632
|
-
const game = this.positionService.getGame();
|
|
8633
|
-
if (!game) return false;
|
|
8634
|
-
return game.isDraw ? game.isDraw() : false;
|
|
8635
|
-
}
|
|
8636
|
-
/**
|
|
8637
|
-
* Get move history
|
|
8638
|
-
* @returns {Array}
|
|
8639
|
-
*/
|
|
8640
|
-
getHistory() {
|
|
8641
|
-
const game = this.positionService.getGame();
|
|
8642
|
-
if (!game) return [];
|
|
8643
|
-
return game.history ? game.history() : [];
|
|
8190
|
+
resize(size) {
|
|
8191
|
+
this.boardService.resize(size);
|
|
8192
|
+
this._updateBoardPieces();
|
|
8644
8193
|
}
|
|
8645
8194
|
|
|
8646
|
-
// --- LIFECYCLE ---
|
|
8647
8195
|
/**
|
|
8648
|
-
*
|
|
8649
|
-
*/
|
|
8650
|
-
destroy() { /* TODO: robust destroy logic */ }
|
|
8651
|
-
/**
|
|
8652
|
-
* Rebuild the board
|
|
8196
|
+
* Flips the board orientation
|
|
8653
8197
|
*/
|
|
8654
|
-
|
|
8198
|
+
flip() {
|
|
8199
|
+
this.coordinateService.flipOrientation();
|
|
8655
8200
|
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
|
|
8659
|
-
|
|
8660
|
-
|
|
8661
|
-
|
|
8662
|
-
/**
|
|
8663
|
-
* Set new config
|
|
8664
|
-
* @param {Object} newConfig
|
|
8665
|
-
*/
|
|
8666
|
-
setConfig(newConfig) { this.setConfig(newConfig); }
|
|
8201
|
+
// Save current position before destroying
|
|
8202
|
+
let currentPosition = null;
|
|
8203
|
+
try {
|
|
8204
|
+
// Check if there are any pieces on the board
|
|
8205
|
+
const position = this.positionService.getPosition();
|
|
8206
|
+
const hasPieces = Object.keys(position).length > 0;
|
|
8667
8207
|
|
|
8668
|
-
|
|
8669
|
-
|
|
8208
|
+
if (hasPieces) {
|
|
8209
|
+
currentPosition = this.positionService.getGame().fen();
|
|
8210
|
+
}
|
|
8211
|
+
} catch (error) {
|
|
8212
|
+
console.log('No valid position to save during flip');
|
|
8213
|
+
}
|
|
8670
8214
|
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8674
|
-
|
|
8675
|
-
|
|
8676
|
-
|
|
8215
|
+
this.destroy();
|
|
8216
|
+
this._initializeServices(); // Recreate all services
|
|
8217
|
+
this._initParams();
|
|
8218
|
+
|
|
8219
|
+
// Restore position after rebuilding if we had one
|
|
8220
|
+
if (currentPosition) {
|
|
8221
|
+
this._setGame(currentPosition);
|
|
8222
|
+
}
|
|
8223
|
+
this._buildBoard();
|
|
8224
|
+
this._buildSquares();
|
|
8225
|
+
this._addListeners();
|
|
8226
|
+
this._updateBoardPieces(true, true);
|
|
8677
8227
|
}
|
|
8678
8228
|
|
|
8679
8229
|
/**
|
|
@@ -8696,19 +8246,51 @@ let Chessboard$1 = class Chessboard {
|
|
|
8696
8246
|
this.load(position, {}, animate); // load() already handles isPositionLoad=true
|
|
8697
8247
|
}
|
|
8698
8248
|
|
|
8249
|
+
/**
|
|
8250
|
+
* Makes a move on the board
|
|
8251
|
+
* @param {string|Object} move - Move to make
|
|
8252
|
+
* @param {boolean} [animate=true] - Whether to animate
|
|
8253
|
+
* @returns {boolean} True if move was successful
|
|
8254
|
+
*/
|
|
8255
|
+
move(move, animate = true) {
|
|
8256
|
+
if (typeof move === 'string') {
|
|
8257
|
+
// Parse move string (e.g., 'e2e4')
|
|
8258
|
+
const moveObj = this.moveService.parseMove(move);
|
|
8259
|
+
if (!moveObj) return false;
|
|
8260
|
+
|
|
8261
|
+
const fromSquare = this.boardService.getSquare(moveObj.from);
|
|
8262
|
+
const toSquare = this.boardService.getSquare(moveObj.to);
|
|
8263
|
+
|
|
8264
|
+
if (!fromSquare || !toSquare) return false;
|
|
8265
|
+
|
|
8266
|
+
return this._onMove(fromSquare, toSquare, moveObj.promotion, animate);
|
|
8267
|
+
} else if (move && move.from && move.to) {
|
|
8268
|
+
// Handle move object
|
|
8269
|
+
const fromSquare = this.boardService.getSquare(move.from);
|
|
8270
|
+
const toSquare = this.boardService.getSquare(move.to);
|
|
8271
|
+
|
|
8272
|
+
if (!fromSquare || !toSquare) return false;
|
|
8273
|
+
|
|
8274
|
+
return this._onMove(fromSquare, toSquare, move.promotion, animate);
|
|
8275
|
+
}
|
|
8276
|
+
|
|
8277
|
+
return false;
|
|
8278
|
+
}
|
|
8279
|
+
|
|
8699
8280
|
/**
|
|
8700
8281
|
* Undoes the last move
|
|
8701
8282
|
* @param {boolean} [animate=true] - Whether to animate
|
|
8702
8283
|
* @returns {boolean} True if undo was successful
|
|
8703
8284
|
*/
|
|
8704
8285
|
undo(animate = true) {
|
|
8705
|
-
|
|
8706
|
-
|
|
8707
|
-
|
|
8708
|
-
|
|
8709
|
-
|
|
8286
|
+
if (this.positionService.getGame().undo) {
|
|
8287
|
+
const undoResult = this.positionService.getGame().undo();
|
|
8288
|
+
if (undoResult) {
|
|
8289
|
+
this._updateBoardPieces(animate, true); // Position change
|
|
8290
|
+
return true;
|
|
8291
|
+
}
|
|
8710
8292
|
}
|
|
8711
|
-
return
|
|
8293
|
+
return false;
|
|
8712
8294
|
}
|
|
8713
8295
|
|
|
8714
8296
|
/**
|
|
@@ -8717,13 +8299,12 @@ let Chessboard$1 = class Chessboard {
|
|
|
8717
8299
|
* @returns {boolean} True if redo was successful
|
|
8718
8300
|
*/
|
|
8719
8301
|
redo(animate = true) {
|
|
8720
|
-
if (this.
|
|
8721
|
-
const
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
return result;
|
|
8302
|
+
if (this.positionService.getGame().redo) {
|
|
8303
|
+
const redoResult = this.positionService.getGame().redo();
|
|
8304
|
+
if (redoResult) {
|
|
8305
|
+
this._updateBoardPieces(animate, true); // Position change
|
|
8306
|
+
return true;
|
|
8307
|
+
}
|
|
8727
8308
|
}
|
|
8728
8309
|
return false;
|
|
8729
8310
|
}
|
|
@@ -8885,6 +8466,112 @@ let Chessboard$1 = class Chessboard {
|
|
|
8885
8466
|
}
|
|
8886
8467
|
}
|
|
8887
8468
|
|
|
8469
|
+
/**
|
|
8470
|
+
* Clears the board
|
|
8471
|
+
* @param {boolean} [animate=true] - Whether to animate
|
|
8472
|
+
*/
|
|
8473
|
+
clear(animate = true) {
|
|
8474
|
+
// Check if services are available
|
|
8475
|
+
if (!this.positionService || !this.positionService.getGame()) {
|
|
8476
|
+
console.log('Cannot clear - position service not available');
|
|
8477
|
+
return;
|
|
8478
|
+
}
|
|
8479
|
+
|
|
8480
|
+
// Clear visual state first
|
|
8481
|
+
this._clearVisualState();
|
|
8482
|
+
|
|
8483
|
+
// Clear game state
|
|
8484
|
+
this.positionService.getGame().clear();
|
|
8485
|
+
|
|
8486
|
+
// Update board visually
|
|
8487
|
+
this._updateBoardPieces(animate, true); // Position change
|
|
8488
|
+
}
|
|
8489
|
+
|
|
8490
|
+
/**
|
|
8491
|
+
* Resets the board to starting position
|
|
8492
|
+
* @param {boolean} [animate=true] - Whether to animate
|
|
8493
|
+
*/
|
|
8494
|
+
reset(animate = true) {
|
|
8495
|
+
// Check if services are available
|
|
8496
|
+
if (!this.positionService || !this.positionService.getGame()) {
|
|
8497
|
+
console.log('Cannot reset - position service not available');
|
|
8498
|
+
return;
|
|
8499
|
+
}
|
|
8500
|
+
|
|
8501
|
+
this.positionService.getGame().reset();
|
|
8502
|
+
this._updateBoardPieces(animate, true); // Position change
|
|
8503
|
+
}
|
|
8504
|
+
|
|
8505
|
+
/**
|
|
8506
|
+
* Puts a piece on a square
|
|
8507
|
+
* @param {string} square - Square to put piece on
|
|
8508
|
+
* @param {string} piece - Piece to put
|
|
8509
|
+
* @param {boolean} [animate=true] - Whether to animate
|
|
8510
|
+
* @returns {boolean} True if successful
|
|
8511
|
+
*/
|
|
8512
|
+
put(square, piece, animate = true) {
|
|
8513
|
+
console.log(`put() called with square: ${square}, piece: ${piece}`);
|
|
8514
|
+
|
|
8515
|
+
if (!this.validationService.isValidSquare(square) || !this.validationService.isValidPiece(piece)) {
|
|
8516
|
+
console.log('Validation failed');
|
|
8517
|
+
return false;
|
|
8518
|
+
}
|
|
8519
|
+
|
|
8520
|
+
// Check if services are available
|
|
8521
|
+
if (!this.positionService || !this.positionService.getGame()) {
|
|
8522
|
+
console.log('Cannot put piece - position service not available');
|
|
8523
|
+
return false;
|
|
8524
|
+
}
|
|
8525
|
+
|
|
8526
|
+
const pieceObj = this.pieceService.convertPiece(piece);
|
|
8527
|
+
console.log(`Converted piece:`, pieceObj);
|
|
8528
|
+
console.log(`Piece type: ${pieceObj.type}, color: ${pieceObj.color}`);
|
|
8529
|
+
|
|
8530
|
+
const squareObj = this.boardService.getSquare(square);
|
|
8531
|
+
|
|
8532
|
+
if (!squareObj) {
|
|
8533
|
+
console.log('Square not found');
|
|
8534
|
+
return false;
|
|
8535
|
+
}
|
|
8536
|
+
|
|
8537
|
+
// Update game state - note: chess.js expects (piece, square) order
|
|
8538
|
+
const chessJsPiece = { type: pieceObj.type.toLowerCase(), color: pieceObj.color.toLowerCase() };
|
|
8539
|
+
console.log(`Chess.js piece:`, chessJsPiece);
|
|
8540
|
+
|
|
8541
|
+
const result = this.positionService.getGame().put(chessJsPiece, square);
|
|
8542
|
+
console.log(`Chess.js put result:`, result);
|
|
8543
|
+
|
|
8544
|
+
if (result) {
|
|
8545
|
+
// Update visual representation
|
|
8546
|
+
this._updateBoardPieces(animate, true); // Position change
|
|
8547
|
+
}
|
|
8548
|
+
|
|
8549
|
+
return result;
|
|
8550
|
+
}
|
|
8551
|
+
|
|
8552
|
+
/**
|
|
8553
|
+
* Removes a piece from a square
|
|
8554
|
+
* @param {string} square - Square to remove piece from
|
|
8555
|
+
* @param {boolean} [animate=true] - Whether to animate
|
|
8556
|
+
* @returns {boolean} True if successful
|
|
8557
|
+
*/
|
|
8558
|
+
remove(square, animate = true) {
|
|
8559
|
+
if (!this.validationService.isValidSquare(square)) {
|
|
8560
|
+
return false;
|
|
8561
|
+
}
|
|
8562
|
+
|
|
8563
|
+
const squareObj = this.boardService.getSquare(square);
|
|
8564
|
+
if (!squareObj) return false;
|
|
8565
|
+
|
|
8566
|
+
// Update game state
|
|
8567
|
+
this.positionService.getGame().remove(square);
|
|
8568
|
+
|
|
8569
|
+
// Update visual representation
|
|
8570
|
+
this._updateBoardPieces(animate, true); // Position change
|
|
8571
|
+
|
|
8572
|
+
return true;
|
|
8573
|
+
}
|
|
8574
|
+
|
|
8888
8575
|
/**
|
|
8889
8576
|
* Gets configuration options
|
|
8890
8577
|
* @returns {Object} Configuration object
|
|
@@ -8946,97 +8633,7 @@ let Chessboard$1 = class Chessboard {
|
|
|
8946
8633
|
|
|
8947
8634
|
// Additional API methods would be added here following the same pattern
|
|
8948
8635
|
// This is a good starting point for the refactored architecture
|
|
8949
|
-
|
|
8950
|
-
// Additional API methods and aliases for backward compatibility
|
|
8951
|
-
insert(square, piece) { return this.putPiece(piece, square); }
|
|
8952
|
-
build() { return this._initialize(); }
|
|
8953
|
-
ascii() { return this.positionService.getGame().ascii(); }
|
|
8954
|
-
board() { return this.positionService.getGame().board(); }
|
|
8955
|
-
getCastlingRights(color) { return this.positionService.getGame().getCastlingRights(color); }
|
|
8956
|
-
getComment() { return this.positionService.getGame().getComment(); }
|
|
8957
|
-
getComments() { return this.positionService.getGame().getComments(); }
|
|
8958
|
-
lastMove() { return this.positionService.getGame().lastMove(); }
|
|
8959
|
-
moveNumber() { return this.positionService.getGame().moveNumber(); }
|
|
8960
|
-
moves(options = {}) { return this.positionService.getGame().moves(options); }
|
|
8961
|
-
squareColor(squareId) { return this.boardService.getSquare(squareId).isWhite() ? 'light' : 'dark'; }
|
|
8962
|
-
isDrawByFiftyMoves() { return this.positionService.getGame().isDrawByFiftyMoves(); }
|
|
8963
|
-
isInsufficientMaterial() { return this.positionService.getGame().isInsufficientMaterial(); }
|
|
8964
|
-
removeComment() { return this.positionService.getGame().removeComment(); }
|
|
8965
|
-
removeComments() { return this.positionService.getGame().removeComments(); }
|
|
8966
|
-
removeHeader(field) { return this.positionService.getGame().removeHeader(field); }
|
|
8967
|
-
setCastlingRights(color, rights) { return this.positionService.getGame().setCastlingRights(color, rights); }
|
|
8968
|
-
setComment(comment) { return this.positionService.getGame().setComment(comment); }
|
|
8969
|
-
setHeader(key, value) { return this.positionService.getGame().setHeader(key, value); }
|
|
8970
|
-
validateFen(fen) { return this.positionService.getGame().validateFen(fen); }
|
|
8971
|
-
|
|
8972
|
-
// Implementazioni reali per highlight/dehighlight
|
|
8973
|
-
highlightSquare(square) {
|
|
8974
|
-
return this.boardService.highlight(square);
|
|
8975
|
-
}
|
|
8976
|
-
dehighlightSquare(square) {
|
|
8977
|
-
return this.boardService.dehighlight(square);
|
|
8978
|
-
}
|
|
8979
|
-
forceSync() { this._updateBoardPieces(true, true); this._updateBoardPieces(true, false); }
|
|
8980
|
-
|
|
8981
|
-
// Metodi mancanti che causano fallimenti nei test
|
|
8982
|
-
/**
|
|
8983
|
-
* Move a piece from one square to another
|
|
8984
|
-
* @param {string|Object} move - Move in format 'e2e4' or {from: 'e2', to: 'e4'}
|
|
8985
|
-
* @param {Object} [opts] - Options
|
|
8986
|
-
* @param {boolean} [opts.animate=true] - Whether to animate
|
|
8987
|
-
* @returns {boolean} True if move was successful
|
|
8988
|
-
*/
|
|
8989
|
-
movePiece(move, opts = {}) {
|
|
8990
|
-
const animate = opts.animate !== undefined ? opts.animate : true;
|
|
8991
|
-
|
|
8992
|
-
// --- API: accetta id/stringhe, ma converte subito in oggetti ---
|
|
8993
|
-
let fromSquareObj, toSquareObj, promotion;
|
|
8994
|
-
if (typeof move === 'string') {
|
|
8995
|
-
if (move.length === 4) {
|
|
8996
|
-
fromSquareObj = this.boardService.getSquare(move.substring(0, 2));
|
|
8997
|
-
toSquareObj = this.boardService.getSquare(move.substring(2, 4));
|
|
8998
|
-
} else if (move.length === 5) {
|
|
8999
|
-
fromSquareObj = this.boardService.getSquare(move.substring(0, 2));
|
|
9000
|
-
toSquareObj = this.boardService.getSquare(move.substring(2, 4));
|
|
9001
|
-
promotion = move.substring(4, 5);
|
|
9002
|
-
} else {
|
|
9003
|
-
throw new Error(`Invalid move format: ${move}`);
|
|
9004
|
-
}
|
|
9005
|
-
} else if (typeof move === 'object' && move.from && move.to) {
|
|
9006
|
-
// Se sono id, converto in oggetti; se sono già oggetti, li uso direttamente
|
|
9007
|
-
fromSquareObj = typeof move.from === 'string' ? this.boardService.getSquare(move.from) : move.from;
|
|
9008
|
-
toSquareObj = typeof move.to === 'string' ? this.boardService.getSquare(move.to) : move.to;
|
|
9009
|
-
promotion = move.promotion;
|
|
9010
|
-
} else {
|
|
9011
|
-
throw new Error(`Invalid move: ${move}`);
|
|
9012
|
-
}
|
|
9013
|
-
|
|
9014
|
-
if (!fromSquareObj || !toSquareObj) {
|
|
9015
|
-
throw new Error(`Invalid squares: ${move.from || move.substring(0, 2)} or ${move.to || move.substring(2, 4)}`);
|
|
9016
|
-
}
|
|
9017
|
-
|
|
9018
|
-
// --- Internamente: lavora solo con oggetti ---
|
|
9019
|
-
const result = this._onMove(fromSquareObj, toSquareObj, promotion, animate);
|
|
9020
|
-
// Dopo ogni mossa, forza la sincronizzazione della board
|
|
9021
|
-
this._updateBoardPieces(true, false);
|
|
9022
|
-
return result;
|
|
9023
|
-
}
|
|
9024
|
-
|
|
9025
|
-
// Aliases for backward compatibility
|
|
9026
|
-
move(move, animate = true) {
|
|
9027
|
-
// On any new move, clear the redo stack
|
|
9028
|
-
this._undoneMoves = [];
|
|
9029
|
-
return this.movePiece(move, { animate });
|
|
9030
|
-
}
|
|
9031
|
-
get(square) { return this.getPiece(square); }
|
|
9032
|
-
piece(square) { return this.getPiece(square); }
|
|
9033
|
-
put(piece, square, opts = {}) { return this.putPiece(piece, square, opts); }
|
|
9034
|
-
remove(square, opts = {}) { return this.removePiece(square, opts); }
|
|
9035
|
-
load(position, opts = {}) { return this.setPosition(position, opts); }
|
|
9036
|
-
resize(size) { return this.resizeBoard(size); }
|
|
9037
|
-
start(opts = {}) { return this.reset(opts); }
|
|
9038
|
-
clearBoard(opts = {}) { return this.clear(opts); }
|
|
9039
|
-
};
|
|
8636
|
+
}
|
|
9040
8637
|
|
|
9041
8638
|
/**
|
|
9042
8639
|
* Structured logging system for Chessboard.js
|
|
@@ -9583,7 +9180,7 @@ class ChessboardFactory {
|
|
|
9583
9180
|
this.validationService.validateConfig(finalConfig);
|
|
9584
9181
|
|
|
9585
9182
|
// Create chessboard instance
|
|
9586
|
-
const chessboard = new Chessboard
|
|
9183
|
+
const chessboard = new Chessboard(finalConfig);
|
|
9587
9184
|
|
|
9588
9185
|
// Store instance for management
|
|
9589
9186
|
this.instances.set(containerId, {
|
|
@@ -9843,44 +9440,13 @@ function createChessboardFromTemplate(containerId, templateName, overrides = {})
|
|
|
9843
9440
|
*/
|
|
9844
9441
|
|
|
9845
9442
|
|
|
9846
|
-
/**
|
|
9847
|
-
* Main Chessboard factory function for backward compatibility
|
|
9848
|
-
* Supports both legacy and modern calling conventions
|
|
9849
|
-
* @param {string|Object} containerElm - Container element ID or configuration object
|
|
9850
|
-
* @param {Object} [config={}] - Configuration options (when first param is string)
|
|
9851
|
-
* @returns {ChessboardClass} Chessboard instance
|
|
9852
|
-
*/
|
|
9853
|
-
function Chessboard(containerElm, config = {}) {
|
|
9854
|
-
const factoryLogger = logger.child('ChessboardFactory');
|
|
9855
|
-
|
|
9856
|
-
try {
|
|
9857
|
-
// If first parameter is an object, treat it as config
|
|
9858
|
-
if (typeof containerElm === 'object' && containerElm !== null) {
|
|
9859
|
-
factoryLogger.debug('Creating chessboard with config object');
|
|
9860
|
-
return new Chessboard$1(containerElm);
|
|
9861
|
-
}
|
|
9862
|
-
|
|
9863
|
-
// Otherwise, treat first parameter as element ID
|
|
9864
|
-
if (typeof containerElm === 'string') {
|
|
9865
|
-
factoryLogger.debug('Creating chessboard with element ID', { elementId: containerElm });
|
|
9866
|
-
const fullConfig = { ...config, id: containerElm };
|
|
9867
|
-
return new Chessboard$1(fullConfig);
|
|
9868
|
-
}
|
|
9869
|
-
|
|
9870
|
-
throw new Error('Invalid parameters: first parameter must be string or object');
|
|
9871
|
-
} catch (error) {
|
|
9872
|
-
factoryLogger.error('Failed to create chessboard instance', { error });
|
|
9873
|
-
throw error;
|
|
9874
|
-
}
|
|
9875
|
-
}
|
|
9876
|
-
|
|
9877
9443
|
/**
|
|
9878
9444
|
* Wrapper class that handles both calling conventions
|
|
9879
9445
|
* Provides enhanced error handling and logging
|
|
9880
9446
|
* @class
|
|
9881
9447
|
* @extends ChessboardClass
|
|
9882
9448
|
*/
|
|
9883
|
-
class ChessboardWrapper extends Chessboard
|
|
9449
|
+
class ChessboardWrapper extends Chessboard {
|
|
9884
9450
|
/**
|
|
9885
9451
|
* Creates a new ChessboardWrapper instance
|
|
9886
9452
|
* @param {string|Object} containerElm - Container element ID or configuration object
|
|
@@ -9909,53 +9475,32 @@ class ChessboardWrapper extends Chessboard$1 {
|
|
|
9909
9475
|
}
|
|
9910
9476
|
}
|
|
9911
9477
|
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
9915
|
-
|
|
9478
|
+
// Attach classes and utilities to the factory function for direct access
|
|
9479
|
+
Chessboard.Class = ChessboardWrapper;
|
|
9480
|
+
Chessboard.Chessboard = ChessboardWrapper;
|
|
9481
|
+
Chessboard.Config = ChessboardConfig;
|
|
9482
|
+
Chessboard.Factory = ChessboardFactory;
|
|
9916
9483
|
|
|
9917
|
-
//
|
|
9918
|
-
/**
|
|
9919
|
-
* Create a new Chessboard instance
|
|
9920
|
-
* @param {string|Object} containerElm
|
|
9921
|
-
* @param {Object} [config]
|
|
9922
|
-
* @returns {Chessboard}
|
|
9923
|
-
*/
|
|
9484
|
+
// Attach factory methods
|
|
9924
9485
|
Chessboard.create = createChessboard;
|
|
9925
|
-
|
|
9926
|
-
* Create a Chessboard from a template
|
|
9927
|
-
* @param {string|Object} containerElm
|
|
9928
|
-
* @param {string} templateName
|
|
9929
|
-
* @param {Object} [config]
|
|
9930
|
-
* @returns {Chessboard}
|
|
9931
|
-
*/
|
|
9932
|
-
Chessboard.fromTemplate = createChessboardFromTemplate;
|
|
9486
|
+
Chessboard.createFromTemplate = createChessboardFromTemplate;
|
|
9933
9487
|
Chessboard.factory = chessboardFactory;
|
|
9934
9488
|
|
|
9935
|
-
//
|
|
9489
|
+
// Static methods for instance management
|
|
9936
9490
|
Chessboard.getInstance = (containerId) => chessboardFactory.getInstance(containerId);
|
|
9937
9491
|
Chessboard.destroyInstance = (containerId) => chessboardFactory.destroy(containerId);
|
|
9938
9492
|
Chessboard.destroyAll = () => chessboardFactory.destroyAll();
|
|
9939
9493
|
Chessboard.listInstances = () => chessboardFactory.listInstances();
|
|
9940
9494
|
|
|
9941
|
-
//
|
|
9495
|
+
// Template management
|
|
9942
9496
|
Chessboard.registerTemplate = (name, config) => chessboardFactory.registerTemplate(name, config);
|
|
9943
9497
|
Chessboard.removeTemplate = (name) => chessboardFactory.removeTemplate(name);
|
|
9944
9498
|
Chessboard.getTemplate = (name) => chessboardFactory.getTemplate(name);
|
|
9945
9499
|
Chessboard.listTemplates = () => chessboardFactory.listTemplates();
|
|
9946
9500
|
|
|
9947
|
-
//
|
|
9501
|
+
// Statistics and debugging
|
|
9948
9502
|
Chessboard.getStats = () => chessboardFactory.getStats();
|
|
9949
9503
|
|
|
9950
|
-
// --- DEPRECATED/LEGACY ALIASES ---
|
|
9951
|
-
/**
|
|
9952
|
-
* @deprecated Use Chessboard.create instead
|
|
9953
|
-
*/
|
|
9954
|
-
Chessboard.Class = ChessboardWrapper;
|
|
9955
|
-
Chessboard.Chessboard = ChessboardWrapper;
|
|
9956
|
-
Chessboard.Config = ChessboardConfig;
|
|
9957
|
-
Chessboard.Factory = ChessboardFactory;
|
|
9958
|
-
|
|
9959
9504
|
/**
|
|
9960
9505
|
* Coordinate utilities for Chessboard.js
|
|
9961
9506
|
*/
|