@alepot55/chessboardjs 2.2.1 → 2.3.0

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.
Files changed (74) hide show
  1. package/README.md +125 -401
  2. package/assets/themes/alepot/theme.json +42 -0
  3. package/assets/themes/default/theme.json +42 -0
  4. package/dist/chessboard.cjs.js +11785 -0
  5. package/dist/chessboard.css +243 -0
  6. package/dist/chessboard.esm.js +11716 -0
  7. package/dist/chessboard.iife.js +11791 -0
  8. package/dist/chessboard.umd.js +11791 -0
  9. package/package.json +33 -3
  10. package/{chessboard.move.js → src/components/Move.js} +3 -3
  11. package/src/components/Piece.js +771 -0
  12. package/{chessboard.square.js → src/components/Square.js} +61 -8
  13. package/src/constants/index.js +15 -0
  14. package/src/constants/positions.js +62 -0
  15. package/src/core/Chessboard.js +2346 -0
  16. package/src/core/ChessboardConfig.js +707 -0
  17. package/src/core/ChessboardFactory.js +385 -0
  18. package/src/core/index.js +141 -0
  19. package/src/errors/ChessboardError.js +133 -0
  20. package/src/errors/index.js +15 -0
  21. package/src/errors/messages.js +189 -0
  22. package/src/index.js +103 -0
  23. package/src/services/AnimationService.js +180 -0
  24. package/src/services/BoardService.js +156 -0
  25. package/src/services/CoordinateService.js +355 -0
  26. package/src/services/EventService.js +955 -0
  27. package/src/services/MoveService.js +567 -0
  28. package/src/services/PieceService.js +339 -0
  29. package/src/services/PositionService.js +237 -0
  30. package/src/services/ValidationService.js +673 -0
  31. package/src/services/index.js +14 -0
  32. package/src/styles/animations.css +46 -0
  33. package/{chessboard.css → src/styles/board.css} +30 -7
  34. package/src/styles/index.css +4 -0
  35. package/src/styles/pieces.css +70 -0
  36. package/src/utils/animations.js +37 -0
  37. package/{chess.js → src/utils/chess.js} +16 -16
  38. package/src/utils/coordinates.js +62 -0
  39. package/src/utils/cross-browser.js +150 -0
  40. package/src/utils/logger.js +422 -0
  41. package/src/utils/performance.js +311 -0
  42. package/src/utils/validation.js +458 -0
  43. package/.babelrc +0 -4
  44. package/chessboard.bundle.js +0 -3422
  45. package/chessboard.config.js +0 -147
  46. package/chessboard.js +0 -979
  47. package/chessboard.piece.js +0 -115
  48. package/jest.config.js +0 -7
  49. package/rollup.config.js +0 -11
  50. package/test/chessboard.test.js +0 -128
  51. /package/{alepot_theme → assets/themes/alepot}/bb.svg +0 -0
  52. /package/{alepot_theme → assets/themes/alepot}/bw.svg +0 -0
  53. /package/{alepot_theme → assets/themes/alepot}/kb.svg +0 -0
  54. /package/{alepot_theme → assets/themes/alepot}/kw.svg +0 -0
  55. /package/{alepot_theme → assets/themes/alepot}/nb.svg +0 -0
  56. /package/{alepot_theme → assets/themes/alepot}/nw.svg +0 -0
  57. /package/{alepot_theme → assets/themes/alepot}/pb.svg +0 -0
  58. /package/{alepot_theme → assets/themes/alepot}/pw.svg +0 -0
  59. /package/{alepot_theme → assets/themes/alepot}/qb.svg +0 -0
  60. /package/{alepot_theme → assets/themes/alepot}/qw.svg +0 -0
  61. /package/{alepot_theme → assets/themes/alepot}/rb.svg +0 -0
  62. /package/{alepot_theme → assets/themes/alepot}/rw.svg +0 -0
  63. /package/{default_pieces → assets/themes/default}/bb.svg +0 -0
  64. /package/{default_pieces → assets/themes/default}/bw.svg +0 -0
  65. /package/{default_pieces → assets/themes/default}/kb.svg +0 -0
  66. /package/{default_pieces → assets/themes/default}/kw.svg +0 -0
  67. /package/{default_pieces → assets/themes/default}/nb.svg +0 -0
  68. /package/{default_pieces → assets/themes/default}/nw.svg +0 -0
  69. /package/{default_pieces → assets/themes/default}/pb.svg +0 -0
  70. /package/{default_pieces → assets/themes/default}/pw.svg +0 -0
  71. /package/{default_pieces → assets/themes/default}/qb.svg +0 -0
  72. /package/{default_pieces → assets/themes/default}/qw.svg +0 -0
  73. /package/{default_pieces → assets/themes/default}/rb.svg +0 -0
  74. /package/{default_pieces → assets/themes/default}/rw.svg +0 -0
@@ -0,0 +1,355 @@
1
+ /**
2
+ * Service for managing coordinate conversions and board orientation
3
+ * @module services/CoordinateService
4
+ * @since 2.0.0
5
+ */
6
+
7
+ import { BOARD_LETTERS } from '../constants/positions.js';
8
+ import { ValidationError } from '../errors/ChessboardError.js';
9
+ import { ERROR_MESSAGES } from '../errors/messages.js';
10
+
11
+ /**
12
+ * Service responsible for coordinate conversions and board orientation
13
+ * @class
14
+ */
15
+ export class CoordinateService {
16
+ /**
17
+ * Creates a new CoordinateService instance
18
+ * @param {ChessboardConfig} config - Board configuration
19
+ */
20
+ constructor(config) {
21
+ this.config = config;
22
+ }
23
+
24
+ /**
25
+ * Converts logical coordinates to real coordinates based on board orientation
26
+ * @param {number} row - Row index (0-7)
27
+ * @param {number} col - Column index (0-7)
28
+ * @returns {Array<number>} Real coordinates [row, col] (1-8)
29
+ */
30
+ realCoord(row, col) {
31
+ let realRow = row;
32
+ let realCol = col;
33
+
34
+ if (this.isWhiteOriented()) {
35
+ realRow = 7 - row;
36
+ } else {
37
+ realCol = 7 - col;
38
+ }
39
+
40
+ return [realRow + 1, realCol + 1];
41
+ }
42
+
43
+ /**
44
+ * Converts board coordinates to square ID
45
+ * @param {number} row - Row index (0-7)
46
+ * @param {number} col - Column index (0-7)
47
+ * @returns {string} Square ID (e.g., 'e4')
48
+ */
49
+ getSquareID(row, col) {
50
+ row = parseInt(row);
51
+ col = parseInt(col);
52
+
53
+ if (this.isWhiteOriented()) {
54
+ row = 8 - row;
55
+ col = col + 1;
56
+ } else {
57
+ row = row + 1;
58
+ col = 8 - col;
59
+ }
60
+
61
+ if (col < 1 || col > 8 || row < 1 || row > 8) {
62
+ throw new ValidationError(
63
+ `Invalid board coordinates: row=${row}, col=${col}`,
64
+ 'coordinates',
65
+ { row, col }
66
+ );
67
+ }
68
+
69
+ const letter = BOARD_LETTERS[col - 1];
70
+ return letter + row;
71
+ }
72
+
73
+ /**
74
+ * Converts square ID to board coordinates
75
+ * @param {string} squareId - Square ID (e.g., 'e4')
76
+ * @returns {Array<number>} Board coordinates [row, col] (0-7)
77
+ */
78
+ getCoordinatesFromSquareID(squareId) {
79
+ if (typeof squareId !== 'string' || squareId.length !== 2) {
80
+ throw new ValidationError(
81
+ ERROR_MESSAGES.invalid_square + squareId,
82
+ 'squareId',
83
+ squareId
84
+ );
85
+ }
86
+
87
+ const letter = squareId[0];
88
+ const number = parseInt(squareId[1]);
89
+
90
+ const col = BOARD_LETTERS.indexOf(letter);
91
+ if (col === -1) {
92
+ throw new ValidationError(
93
+ ERROR_MESSAGES.invalid_square + squareId,
94
+ 'squareId',
95
+ squareId
96
+ );
97
+ }
98
+
99
+ if (number < 1 || number > 8) {
100
+ throw new ValidationError(
101
+ ERROR_MESSAGES.invalid_square + squareId,
102
+ 'squareId',
103
+ squareId
104
+ );
105
+ }
106
+
107
+ let row, boardCol;
108
+
109
+ if (this.isWhiteOriented()) {
110
+ row = 8 - number;
111
+ boardCol = col;
112
+ } else {
113
+ row = number - 1;
114
+ boardCol = 7 - col;
115
+ }
116
+
117
+ return [row, boardCol];
118
+ }
119
+
120
+ /**
121
+ * Converts pixel coordinates to square ID
122
+ * @param {number} x - X coordinate in pixels
123
+ * @param {number} y - Y coordinate in pixels
124
+ * @param {HTMLElement} boardElement - Board DOM element
125
+ * @returns {string|null} Square ID or null if outside board
126
+ */
127
+ pixelToSquareID(x, y, boardElement) {
128
+ if (!boardElement) return null;
129
+
130
+ const rect = boardElement.getBoundingClientRect();
131
+ const { width, height } = rect;
132
+
133
+ // Check if coordinates are within board bounds
134
+ if (x < 0 || x >= width || y < 0 || y >= height) {
135
+ return null;
136
+ }
137
+
138
+ const squareWidth = width / 8;
139
+ const squareHeight = height / 8;
140
+
141
+ const col = Math.floor(x / squareWidth);
142
+ const row = Math.floor(y / squareHeight);
143
+
144
+ try {
145
+ return this.getSquareID(row, col);
146
+ } catch (error) {
147
+ return null;
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Converts square ID to pixel coordinates
153
+ * @param {string} squareId - Square ID (e.g., 'e4')
154
+ * @param {HTMLElement} boardElement - Board DOM element
155
+ * @returns {Object|null} Pixel coordinates {x, y} or null if invalid
156
+ */
157
+ squareIDToPixel(squareId, boardElement) {
158
+ if (!boardElement) return null;
159
+
160
+ try {
161
+ const [row, col] = this.getCoordinatesFromSquareID(squareId);
162
+ const rect = boardElement.getBoundingClientRect();
163
+ const { width, height } = rect;
164
+
165
+ const squareWidth = width / 8;
166
+ const squareHeight = height / 8;
167
+
168
+ const x = col * squareWidth;
169
+ const y = row * squareHeight;
170
+
171
+ return { x, y };
172
+ } catch (error) {
173
+ return null;
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Gets the center pixel coordinates of a square
179
+ * @param {string} squareId - Square ID (e.g., 'e4')
180
+ * @param {HTMLElement} boardElement - Board DOM element
181
+ * @returns {Object|null} Center coordinates {x, y} or null if invalid
182
+ */
183
+ getSquareCenter(squareId, boardElement) {
184
+ const coords = this.squareIDToPixel(squareId, boardElement);
185
+ if (!coords) return null;
186
+
187
+ const rect = boardElement.getBoundingClientRect();
188
+ const squareWidth = rect.width / 8;
189
+ const squareHeight = rect.height / 8;
190
+
191
+ return {
192
+ x: coords.x + squareWidth / 2,
193
+ y: coords.y + squareHeight / 2
194
+ };
195
+ }
196
+
197
+ /**
198
+ * Calculates the distance between two squares
199
+ * @param {string} fromSquare - Source square ID
200
+ * @param {string} toSquare - Target square ID
201
+ * @returns {number} Distance between squares
202
+ */
203
+ getSquareDistance(fromSquare, toSquare) {
204
+ try {
205
+ const [fromRow, fromCol] = this.getCoordinatesFromSquareID(fromSquare);
206
+ const [toRow, toCol] = this.getCoordinatesFromSquareID(toSquare);
207
+
208
+ const rowDiff = Math.abs(toRow - fromRow);
209
+ const colDiff = Math.abs(toCol - fromCol);
210
+
211
+ return Math.sqrt(rowDiff * rowDiff + colDiff * colDiff);
212
+ } catch (error) {
213
+ return 0;
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Checks if the board is oriented from white's perspective
219
+ * @returns {boolean} True if white-oriented
220
+ */
221
+ isWhiteOriented() {
222
+ return this.config.orientation === 'w';
223
+ }
224
+
225
+ /**
226
+ * Checks if the board is oriented from black's perspective
227
+ * @returns {boolean} True if black-oriented
228
+ */
229
+ isBlackOriented() {
230
+ return this.config.orientation === 'b';
231
+ }
232
+
233
+ /**
234
+ * Flips the board orientation
235
+ */
236
+ flipOrientation() {
237
+ this.config.orientation = this.isWhiteOriented() ? 'b' : 'w';
238
+ }
239
+
240
+ /**
241
+ * Sets the board orientation
242
+ * @param {string} orientation - 'w' for white, 'b' for black
243
+ * @throws {ValidationError} When orientation is invalid
244
+ */
245
+ setOrientation(orientation) {
246
+ if (orientation !== 'w' && orientation !== 'b') {
247
+ throw new ValidationError(
248
+ ERROR_MESSAGES.invalid_orientation + orientation,
249
+ 'orientation',
250
+ orientation
251
+ );
252
+ }
253
+
254
+ this.config.orientation = orientation;
255
+ }
256
+
257
+ /**
258
+ * Gets the current orientation
259
+ * @returns {string} Current orientation ('w' or 'b')
260
+ */
261
+ getOrientation() {
262
+ return this.config.orientation;
263
+ }
264
+
265
+ /**
266
+ * Sets the orientation
267
+ * @param {string} orientation - New orientation ('w', 'b', 'white', 'black')
268
+ */
269
+ setOrientation(orientation) {
270
+ // Normalize orientation
271
+ const normalizedOrientation = orientation === 'white' ? 'w' :
272
+ orientation === 'black' ? 'b' : orientation;
273
+
274
+ if (normalizedOrientation !== 'w' && normalizedOrientation !== 'b') {
275
+ throw new ValidationError(
276
+ ERROR_MESSAGES.invalid_orientation + orientation,
277
+ 'orientation',
278
+ orientation
279
+ );
280
+ }
281
+
282
+ this.config.orientation = normalizedOrientation;
283
+ }
284
+
285
+ /**
286
+ * Flips the board orientation
287
+ */
288
+ flipOrientation() {
289
+ this.config.orientation = this.isWhiteOriented() ? 'b' : 'w';
290
+ }
291
+
292
+ /**
293
+ * Gets all square IDs in order
294
+ * @returns {Array<string>} Array of all square IDs
295
+ */
296
+ getAllSquareIDs() {
297
+ const squares = [];
298
+
299
+ for (let row = 0; row < 8; row++) {
300
+ for (let col = 0; col < 8; col++) {
301
+ squares.push(this.getSquareID(row, col));
302
+ }
303
+ }
304
+
305
+ return squares;
306
+ }
307
+
308
+ /**
309
+ * Gets squares in a specific rank (row)
310
+ * @param {number} rank - Rank number (1-8)
311
+ * @returns {Array<string>} Array of square IDs in the rank
312
+ */
313
+ getSquaresByRank(rank) {
314
+ if (rank < 1 || rank > 8) {
315
+ throw new ValidationError(
316
+ `Invalid rank: ${rank}`,
317
+ 'rank',
318
+ rank
319
+ );
320
+ }
321
+
322
+ const squares = [];
323
+
324
+ for (let col = 0; col < 8; col++) {
325
+ const row = this.isWhiteOriented() ? 8 - rank : rank - 1;
326
+ squares.push(this.getSquareID(row, col));
327
+ }
328
+
329
+ return squares;
330
+ }
331
+
332
+ /**
333
+ * Gets squares in a specific file (column)
334
+ * @param {string} file - File letter (a-h)
335
+ * @returns {Array<string>} Array of square IDs in the file
336
+ */
337
+ getSquaresByFile(file) {
338
+ const col = BOARD_LETTERS.indexOf(file);
339
+ if (col === -1) {
340
+ throw new ValidationError(
341
+ `Invalid file: ${file}`,
342
+ 'file',
343
+ file
344
+ );
345
+ }
346
+
347
+ const squares = [];
348
+
349
+ for (let row = 0; row < 8; row++) {
350
+ squares.push(this.getSquareID(row, col));
351
+ }
352
+
353
+ return squares;
354
+ }
355
+ }