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