@alepot55/chessboardjs 2.2.1 → 2.2.2

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 (80) hide show
  1. package/.eslintrc.json +227 -0
  2. package/README.md +125 -401
  3. package/assets/themes/alepot/theme.json +42 -0
  4. package/assets/themes/default/theme.json +42 -0
  5. package/chessboard.bundle.js +708 -58
  6. package/config/jest.config.js +15 -0
  7. package/config/rollup.config.js +36 -0
  8. package/dist/chessboard.cjs.js +10690 -0
  9. package/dist/chessboard.css +228 -0
  10. package/dist/chessboard.esm.js +10621 -0
  11. package/dist/chessboard.iife.js +10696 -0
  12. package/dist/chessboard.umd.js +10696 -0
  13. package/jest.config.js +2 -7
  14. package/package.json +18 -3
  15. package/rollup.config.js +2 -11
  16. package/{chessboard.move.js → src/components/Move.js} +3 -3
  17. package/src/components/Piece.js +288 -0
  18. package/{chessboard.square.js → src/components/Square.js} +60 -7
  19. package/src/constants/index.js +15 -0
  20. package/src/constants/positions.js +62 -0
  21. package/src/core/Chessboard.js +1939 -0
  22. package/src/core/ChessboardConfig.js +458 -0
  23. package/src/core/ChessboardFactory.js +385 -0
  24. package/src/core/index.js +141 -0
  25. package/src/errors/ChessboardError.js +133 -0
  26. package/src/errors/index.js +15 -0
  27. package/src/errors/messages.js +189 -0
  28. package/src/index.js +103 -0
  29. package/src/services/AnimationService.js +180 -0
  30. package/src/services/BoardService.js +156 -0
  31. package/src/services/CoordinateService.js +355 -0
  32. package/src/services/EventService.js +955 -0
  33. package/src/services/MoveService.js +629 -0
  34. package/src/services/PieceService.js +312 -0
  35. package/src/services/PositionService.js +237 -0
  36. package/src/services/ValidationService.js +673 -0
  37. package/src/services/index.js +14 -0
  38. package/src/styles/animations.css +46 -0
  39. package/{chessboard.css → src/styles/board.css} +8 -4
  40. package/src/styles/index.css +4 -0
  41. package/src/styles/pieces.css +70 -0
  42. package/src/utils/animations.js +37 -0
  43. package/{chess.js → src/utils/chess.js} +16 -16
  44. package/src/utils/coordinates.js +62 -0
  45. package/src/utils/cross-browser.js +150 -0
  46. package/src/utils/logger.js +422 -0
  47. package/src/utils/performance.js +311 -0
  48. package/src/utils/validation.js +458 -0
  49. package/tests/unit/chessboard-config-animations.test.js +106 -0
  50. package/tests/unit/chessboard-robust.test.js +163 -0
  51. package/tests/unit/chessboard.test.js +183 -0
  52. package/chessboard.config.js +0 -147
  53. package/chessboard.js +0 -979
  54. package/chessboard.piece.js +0 -115
  55. package/test/chessboard.test.js +0 -128
  56. /package/{alepot_theme → assets/themes/alepot}/bb.svg +0 -0
  57. /package/{alepot_theme → assets/themes/alepot}/bw.svg +0 -0
  58. /package/{alepot_theme → assets/themes/alepot}/kb.svg +0 -0
  59. /package/{alepot_theme → assets/themes/alepot}/kw.svg +0 -0
  60. /package/{alepot_theme → assets/themes/alepot}/nb.svg +0 -0
  61. /package/{alepot_theme → assets/themes/alepot}/nw.svg +0 -0
  62. /package/{alepot_theme → assets/themes/alepot}/pb.svg +0 -0
  63. /package/{alepot_theme → assets/themes/alepot}/pw.svg +0 -0
  64. /package/{alepot_theme → assets/themes/alepot}/qb.svg +0 -0
  65. /package/{alepot_theme → assets/themes/alepot}/qw.svg +0 -0
  66. /package/{alepot_theme → assets/themes/alepot}/rb.svg +0 -0
  67. /package/{alepot_theme → assets/themes/alepot}/rw.svg +0 -0
  68. /package/{default_pieces → assets/themes/default}/bb.svg +0 -0
  69. /package/{default_pieces → assets/themes/default}/bw.svg +0 -0
  70. /package/{default_pieces → assets/themes/default}/kb.svg +0 -0
  71. /package/{default_pieces → assets/themes/default}/kw.svg +0 -0
  72. /package/{default_pieces → assets/themes/default}/nb.svg +0 -0
  73. /package/{default_pieces → assets/themes/default}/nw.svg +0 -0
  74. /package/{default_pieces → assets/themes/default}/pb.svg +0 -0
  75. /package/{default_pieces → assets/themes/default}/pw.svg +0 -0
  76. /package/{default_pieces → assets/themes/default}/qb.svg +0 -0
  77. /package/{default_pieces → assets/themes/default}/qw.svg +0 -0
  78. /package/{default_pieces → assets/themes/default}/rb.svg +0 -0
  79. /package/{default_pieces → assets/themes/default}/rw.svg +0 -0
  80. /package/{.babelrc → config/.babelrc} +0 -0
@@ -0,0 +1,458 @@
1
+ /**
2
+ * Configuration management for Chessboard.js
3
+ * @module core/ChessboardConfig
4
+ * @since 2.0.0
5
+ */
6
+
7
+ import { ValidationService } from '../services/ValidationService.js';
8
+ import { ConfigurationError } from '../errors/ChessboardError.js';
9
+
10
+ /**
11
+ * Animation timing constants
12
+ * @constant
13
+ * @type {Object}
14
+ */
15
+ const ANIMATION_TIMES = Object.freeze({
16
+ fast: 200,
17
+ slow: 600,
18
+ normal: 400,
19
+ verySlow: 1000,
20
+ veryFast: 100
21
+ });
22
+
23
+ /**
24
+ * Boolean value mappings
25
+ * @constant
26
+ * @type {Object}
27
+ */
28
+ const BOOLEAN_VALUES = Object.freeze({
29
+ true: true,
30
+ false: false,
31
+ none: false,
32
+ 1: true,
33
+ 0: false
34
+ });
35
+
36
+ /**
37
+ * CSS transition functions
38
+ * @constant
39
+ * @type {Object}
40
+ */
41
+ const TRANSITION_FUNCTIONS = Object.freeze({
42
+ ease: 'ease',
43
+ linear: 'linear',
44
+ 'ease-in': 'ease-in',
45
+ 'ease-out': 'ease-out',
46
+ 'ease-in-out': 'ease-in-out',
47
+ none: null
48
+ });
49
+
50
+ /**
51
+ * Default configuration values
52
+ * @constant
53
+ * @type {Object}
54
+ */
55
+ const DEFAULT_CONFIG = Object.freeze({
56
+ id: 'board',
57
+ position: 'start',
58
+ orientation: 'w',
59
+ mode: 'normal',
60
+ size: 'auto',
61
+ draggable: true,
62
+ hints: true,
63
+ clickable: true,
64
+ movableColors: 'both',
65
+ moveHighlight: true,
66
+ overHighlight: true,
67
+ moveAnimation: 'ease',
68
+ moveTime: 'fast',
69
+ dropOffBoard: 'snapback',
70
+ snapbackTime: 'fast',
71
+ snapbackAnimation: 'ease',
72
+ dropCenterTime: 'veryFast',
73
+ dropCenterAnimation: 'ease',
74
+ fadeTime: 'fast',
75
+ fadeAnimation: 'ease',
76
+ ratio: 0.9,
77
+ piecesPath: '../assets/themes/default',
78
+ animationStyle: 'simultaneous',
79
+ simultaneousAnimationDelay: 100,
80
+ onMove: () => true,
81
+ onMoveEnd: () => true,
82
+ onChange: () => true,
83
+ onDragStart: () => true,
84
+ onDragMove: () => true,
85
+ onDrop: () => true,
86
+ onSnapbackEnd: () => true,
87
+ whiteSquare: '#f0d9b5',
88
+ blackSquare: '#b58863',
89
+ highlight: 'yellow',
90
+ selectedSquareWhite: '#ababaa',
91
+ selectedSquareBlack: '#ababaa',
92
+ movedSquareWhite: '#f1f1a0',
93
+ movedSquareBlack: '#e9e981',
94
+ choiceSquare: 'white',
95
+ coverSquare: 'black',
96
+ hintColor: '#ababaa'
97
+ });
98
+
99
+ /**
100
+ * Configuration management class for Chessboard.js
101
+ * Handles validation, normalization, and CSS property management
102
+ * @class
103
+ */
104
+ class ChessboardConfig {
105
+ /**
106
+ * Creates a new ChessboardConfig instance
107
+ * @param {Object} settings - User-provided configuration
108
+ * @throws {ConfigurationError} If configuration is invalid
109
+ */
110
+ constructor(settings = {}) {
111
+ // Initialize validation service
112
+ this._validationService = new ValidationService();
113
+
114
+ // Validate input
115
+ this._validateInput(settings);
116
+
117
+ // Merge with defaults
118
+ const config = this._mergeWithDefaults(settings);
119
+
120
+ // Process and validate configuration
121
+ this._processConfiguration(config);
122
+
123
+ // Set CSS properties
124
+ this._setCSSProperties(config);
125
+
126
+ // Configure mode-specific settings
127
+ this._configureModeSettings();
128
+ }
129
+
130
+ /**
131
+ * Validates input configuration
132
+ * @private
133
+ * @param {Object} settings - Input settings
134
+ * @throws {ConfigurationError} If input is invalid
135
+ */
136
+ _validateInput(settings) {
137
+ if (settings !== null && typeof settings !== 'object') {
138
+ throw new ConfigurationError('Settings must be an object', 'settings', settings);
139
+ }
140
+
141
+ // Validate using validation service
142
+ try {
143
+ this._validationService.validateConfig(settings);
144
+ } catch (error) {
145
+ throw new ConfigurationError(error.message, error.field, error.value);
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Merges user settings with defaults
151
+ * @private
152
+ * @param {Object} settings - User settings
153
+ * @returns {Object} Merged configuration
154
+ */
155
+ _mergeWithDefaults(settings) {
156
+ return Object.assign({}, DEFAULT_CONFIG, settings);
157
+ }
158
+
159
+ /**
160
+ * Processes and validates configuration values
161
+ * @private
162
+ * @param {Object} config - Configuration object
163
+ */
164
+ _processConfiguration(config) {
165
+ // Basic properties
166
+ this.id_div = config.id;
167
+ this.position = config.position;
168
+ this.orientation = config.orientation;
169
+ this.mode = config.mode;
170
+ this.dropOffBoard = config.dropOffBoard;
171
+ this.size = config.size;
172
+ this.movableColors = config.movableColors;
173
+ this.piecesPath = config.piecesPath;
174
+
175
+ // Event handlers
176
+ this.onMove = this._validateCallback(config.onMove);
177
+ this.onMoveEnd = this._validateCallback(config.onMoveEnd);
178
+ this.onChange = this._validateCallback(config.onChange);
179
+ this.onDragStart = this._validateCallback(config.onDragStart);
180
+ this.onDragMove = this._validateCallback(config.onDragMove);
181
+ this.onDrop = this._validateCallback(config.onDrop);
182
+ this.onSnapbackEnd = this._validateCallback(config.onSnapbackEnd);
183
+
184
+ // Animation properties
185
+ this.moveAnimation = this._setTransitionFunction(config.moveAnimation);
186
+ this.snapbackAnimation = this._setTransitionFunction(config.snapbackAnimation);
187
+ this.dropCenterAnimation = this._setTransitionFunction(config.dropCenterAnimation);
188
+ this.fadeAnimation = this._setTransitionFunction(config.fadeAnimation);
189
+
190
+ // Boolean properties
191
+ this.hints = this._setBoolean(config.hints);
192
+ this.clickable = this._setBoolean(config.clickable);
193
+ this.draggable = this._setBoolean(config.draggable);
194
+ this.moveHighlight = this._setBoolean(config.moveHighlight);
195
+ this.overHighlight = this._setBoolean(config.overHighlight);
196
+
197
+ // Timing properties
198
+ this.moveTime = this._setTime(config.moveTime);
199
+ this.snapbackTime = this._setTime(config.snapbackTime);
200
+ this.dropCenterTime = this._setTime(config.dropCenterTime);
201
+ this.fadeTime = this._setTime(config.fadeTime);
202
+
203
+ // Animation style properties
204
+ this.animationStyle = this._validateAnimationStyle(config.animationStyle);
205
+ this.simultaneousAnimationDelay = this._validateDelay(config.simultaneousAnimationDelay);
206
+ }
207
+
208
+ /**
209
+ * Sets CSS custom properties
210
+ * @private
211
+ * @param {Object} config - Configuration object
212
+ */
213
+ _setCSSProperties(config) {
214
+ const cssProperties = {
215
+ pieceRatio: config.ratio,
216
+ whiteSquare: config.whiteSquare,
217
+ blackSquare: config.blackSquare,
218
+ highlightSquare: config.highlight,
219
+ selectedSquareWhite: config.selectedSquareWhite,
220
+ selectedSquareBlack: config.selectedSquareBlack,
221
+ movedSquareWhite: config.movedSquareWhite,
222
+ movedSquareBlack: config.movedSquareBlack,
223
+ choiceSquare: config.choiceSquare,
224
+ coverSquare: config.coverSquare,
225
+ hintColor: config.hintColor
226
+ };
227
+
228
+ Object.entries(cssProperties).forEach(([property, value]) => {
229
+ this._setCSSProperty(property, value);
230
+ });
231
+ }
232
+
233
+ /**
234
+ * Configures mode-specific settings
235
+ * @private
236
+ */
237
+ _configureModeSettings() {
238
+ switch (this.mode) {
239
+ case 'creative':
240
+ this.onlyLegalMoves = false;
241
+ this.hints = false;
242
+ break;
243
+ case 'normal':
244
+ this.onlyLegalMoves = true;
245
+ break;
246
+ default:
247
+ this.onlyLegalMoves = true;
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Validates a callback function
253
+ * @private
254
+ * @param {Function} callback - Callback to validate
255
+ * @returns {Function} Validated callback
256
+ * @throws {ConfigurationError} If callback is invalid
257
+ */
258
+ _validateCallback(callback) {
259
+ if (!this._validationService.isValidCallback(callback)) {
260
+ throw new ConfigurationError('Callback must be a function', 'callback', callback);
261
+ }
262
+ return callback;
263
+ }
264
+
265
+ /**
266
+ * Validates animation style
267
+ * @private
268
+ * @param {string} style - Animation style
269
+ * @returns {string} Validated style
270
+ * @throws {ConfigurationError} If style is invalid
271
+ */
272
+ _validateAnimationStyle(style) {
273
+ if (!this._validationService.isValidAnimationStyle(style)) {
274
+ throw new ConfigurationError('Invalid animation style', 'animationStyle', style);
275
+ }
276
+ return style;
277
+ }
278
+
279
+ /**
280
+ * Validates animation delay
281
+ * @private
282
+ * @param {number} delay - Animation delay
283
+ * @returns {number} Validated delay
284
+ * @throws {ConfigurationError} If delay is invalid
285
+ */
286
+ _validateDelay(delay) {
287
+ if (typeof delay !== 'number' || delay < 0 || delay > 5000) {
288
+ throw new ConfigurationError('Invalid animation delay', 'simultaneousAnimationDelay', delay);
289
+ }
290
+ return delay;
291
+ }
292
+
293
+ /**
294
+ * Sets a CSS custom property
295
+ * @private
296
+ * @param {string} property - Property name
297
+ * @param {string} value - Property value
298
+ */
299
+ _setCSSProperty(property, value) {
300
+ try {
301
+ if (typeof document !== 'undefined' && document.documentElement) {
302
+ document.documentElement.style.setProperty(`--${property}`, value);
303
+ }
304
+ } catch (error) {
305
+ console.warn(`Failed to set CSS property ${property}:`, error.message);
306
+ }
307
+ }
308
+
309
+ /**
310
+ * Sets orientation with validation
311
+ * @param {string} orientation - Orientation value
312
+ * @returns {ChessboardConfig} This instance for chaining
313
+ * @throws {ConfigurationError} If orientation is invalid
314
+ */
315
+ setOrientation(orientation) {
316
+ const validatedOrientation = this._validationService.validateOrientation(orientation);
317
+ this.orientation = validatedOrientation;
318
+ return this;
319
+ }
320
+
321
+ /**
322
+ * Validates and sets time value
323
+ * @private
324
+ * @param {string|number} value - Time value
325
+ * @returns {number} Validated time value
326
+ * @throws {ConfigurationError} If time value is invalid
327
+ */
328
+ _setTime(value) {
329
+ if (typeof value === 'number') {
330
+ if (!this._validationService.isValidTime(value)) {
331
+ throw new ConfigurationError('Invalid time value', 'time', value);
332
+ }
333
+ return value;
334
+ }
335
+
336
+ if (typeof value === 'string' && value in ANIMATION_TIMES) {
337
+ return ANIMATION_TIMES[value];
338
+ }
339
+
340
+ throw new ConfigurationError('Invalid time value', 'time', value);
341
+ }
342
+
343
+ /**
344
+ * Validates and sets boolean value
345
+ * @private
346
+ * @param {*} value - Boolean value
347
+ * @returns {boolean} Validated boolean value
348
+ * @throws {ConfigurationError} If boolean value is invalid
349
+ */
350
+ _setBoolean(value) {
351
+ if (typeof value === 'boolean') {
352
+ return value;
353
+ }
354
+
355
+ if (value in BOOLEAN_VALUES) {
356
+ return BOOLEAN_VALUES[value];
357
+ }
358
+
359
+ throw new ConfigurationError('Invalid boolean value', 'boolean', value);
360
+ }
361
+
362
+ /**
363
+ * Validates and sets transition function
364
+ * @private
365
+ * @param {string|boolean|null} value - Transition function value
366
+ * @returns {string|null} Validated transition function
367
+ * @throws {ConfigurationError} If transition function is invalid
368
+ */
369
+ _setTransitionFunction(value) {
370
+ // Handle boolean values - true means use default 'ease', false/null means no animation
371
+ if (typeof value === 'boolean') {
372
+ return value ? TRANSITION_FUNCTIONS.ease : null;
373
+ }
374
+
375
+ // Handle string values
376
+ if (typeof value === 'string' && value in TRANSITION_FUNCTIONS) {
377
+ return TRANSITION_FUNCTIONS[value];
378
+ }
379
+
380
+ // Handle null/undefined
381
+ if (value === null || value === undefined) {
382
+ return null;
383
+ }
384
+
385
+ throw new ConfigurationError('Invalid transition function', 'transitionFunction', value);
386
+ }
387
+
388
+ /**
389
+ * Gets the current configuration as a plain object
390
+ * @returns {Object} Configuration object
391
+ */
392
+ toObject() {
393
+ return {
394
+ id_div: this.id_div,
395
+ position: this.position,
396
+ orientation: this.orientation,
397
+ mode: this.mode,
398
+ size: this.size,
399
+ draggable: this.draggable,
400
+ hints: this.hints,
401
+ clickable: this.clickable,
402
+ movableColors: this.movableColors,
403
+ moveHighlight: this.moveHighlight,
404
+ overHighlight: this.overHighlight,
405
+ moveAnimation: this.moveAnimation,
406
+ moveTime: this.moveTime,
407
+ dropOffBoard: this.dropOffBoard,
408
+ snapbackTime: this.snapbackTime,
409
+ snapbackAnimation: this.snapbackAnimation,
410
+ dropCenterTime: this.dropCenterTime,
411
+ dropCenterAnimation: this.dropCenterAnimation,
412
+ fadeTime: this.fadeTime,
413
+ fadeAnimation: this.fadeAnimation,
414
+ piecesPath: this.piecesPath,
415
+ animationStyle: this.animationStyle,
416
+ simultaneousAnimationDelay: this.simultaneousAnimationDelay,
417
+ onlyLegalMoves: this.onlyLegalMoves
418
+ };
419
+ }
420
+
421
+ /**
422
+ * Updates configuration with new values
423
+ * @param {Object} updates - Configuration updates
424
+ * @returns {ChessboardConfig} This instance for chaining
425
+ * @throws {ConfigurationError} If updates are invalid
426
+ */
427
+ update(updates) {
428
+ if (!updates || typeof updates !== 'object') {
429
+ throw new ConfigurationError('Updates must be an object', 'updates', updates);
430
+ }
431
+
432
+ // Validate updates
433
+ this._validationService.validateConfig(updates);
434
+
435
+ // Apply updates
436
+ const newConfig = Object.assign({}, this.toObject(), updates);
437
+
438
+ // Re-process configuration
439
+ this._processConfiguration(newConfig);
440
+ this._setCSSProperties(newConfig);
441
+ this._configureModeSettings();
442
+
443
+ return this;
444
+ }
445
+
446
+ /**
447
+ * Cleans up resources
448
+ */
449
+ destroy() {
450
+ if (this._validationService) {
451
+ this._validationService.destroy();
452
+ this._validationService = null;
453
+ }
454
+ }
455
+ }
456
+
457
+ export { ChessboardConfig };
458
+ export default ChessboardConfig;