cm-chessboard 3.17.8 → 3.18.1

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.
@@ -44,6 +44,7 @@ function inputHandler(event) {
44
44
  position: "start",
45
45
  sprite: {url: "../assets/images/chessboard-sprite-staunty.svg"}
46
46
  })
47
+
47
48
  window.board.enableMoveInput(inputHandler)
48
49
  function inputHandler(event) {
49
50
  console.log(event)
@@ -7,13 +7,25 @@
7
7
  <link rel="stylesheet" href="styles/examples.css"/>
8
8
  <link rel="stylesheet" href="../assets/styles/cm-chessboard.css"/>
9
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/chess.js/0.10.2/chess.js"></script>
10
+ <style>
11
+ .visually-hidden {
12
+ position: absolute;
13
+ left: -10000px;
14
+ top: auto;
15
+ width: 1px;
16
+ height: 1px;
17
+ overflow: hidden;
18
+ }
19
+ </style>
10
20
  </head>
11
21
  <body>
12
- <h1><a href="../">cm-chessboard</a></h1>
13
- <h2>Example: Input enabled, move validation with chess.js</h2>
22
+ <h1>Example: Input enabled, move validation with chess.js</h1>
23
+ <a href="../">Back to the cm-chessboard overview</a>
14
24
  <p>Input enabled for white. <a href="https://github.com/jhlywa/chess.js">chess.js</a> does the validation and answers
15
25
  with random moves.</p>
26
+ <h2 class="visually-hidden">The Board</h2>
16
27
  <div class="board" id="board"></div>
28
+ <h2 class="visually-hidden">The Sourcecode of the example</h2>
17
29
  <pre>
18
30
  import {INPUT_EVENT_TYPE, COLOR, Chessboard, MARKER_TYPE} from "../src/cm-chessboard/Chessboard.js"
19
31
 
@@ -105,6 +117,7 @@ board.enableMoveInput(inputHandler, COLOR.white)
105
117
 
106
118
  const board = new Chessboard(document.getElementById("board"), {
107
119
  position: chess.fen(),
120
+ accessible: true,
108
121
  // animationDuration: 2000,
109
122
  sprite: {url: "../assets/images/chessboard-sprite-staunty.svg"},
110
123
  style: {moveFromMarker: undefined, moveToMarker: undefined}, // disable standard markers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cm-chessboard",
3
- "version": "3.17.8",
3
+ "version": "3.18.1",
4
4
  "description": "A JavaScript chessboard which is lightweight, ES6 module based, responsive, SVG rendered and without dependencies.",
5
5
  "keywords": [
6
6
  "chess",
@@ -41,11 +41,12 @@ export const FEN_EMPTY_POSITION = "8/8/8/8/8/8/8/8"
41
41
 
42
42
  export class Chessboard {
43
43
 
44
- constructor(element, props = {}) { // TODO rename element to context
45
- if (!element) {
46
- throw new Error("container element is " + element)
44
+ constructor(context, props = {}) {
45
+ if (!context) {
46
+ throw new Error("container element is " + context)
47
47
  }
48
- this.element = element
48
+ this.context = context
49
+ this.id = (Math.random() + 1).toString(36).substr(2, 6)
49
50
  let defaultProps = {
50
51
  position: "empty", // set as fen, "start" or "empty"
51
52
  orientation: COLOR.white, // white on bottom
@@ -57,8 +58,6 @@ export class Chessboard {
57
58
  aspectRatio: 1, // height/width. Set to `undefined`, if you want to define it only in the css.
58
59
  moveFromMarker: MARKER_TYPE.frame, // the marker used to mark the start square
59
60
  moveToMarker: MARKER_TYPE.frame, // the marker used to mark the square where the figure is moving to
60
- moveMarker: MARKER_TYPE.frame, // deprecated => moveFromMarker // TODO remove in future
61
- hoverMarker: MARKER_TYPE.frame // deprecated => moveToMarker // TODO remove in future
62
61
  },
63
62
  responsive: true, // resizes the board based on element size
64
63
  animationDuration: 300, // pieces animation duration in milliseconds
@@ -79,31 +78,20 @@ export class Chessboard {
79
78
  if (props.style) {
80
79
  Object.assign(this.props.style, props.style)
81
80
  }
82
- if(this.props.style.moveMarker !== MARKER_TYPE.frame) { // TODO remove in future
83
- console.warn("this.props.style.moveMarker is deprecated, use this.props.style.moveFromMarker")
84
- this.props.style.moveFromMarker = this.props.style.moveMarker
85
- }
86
- if(this.props.style.hoverMarker !== MARKER_TYPE.frame) { // TODO remove in future
87
- console.warn("this.props.style.hoverMarker is deprecated, use this.props.style.moveToMarker")
88
- this.props.style.moveToMarker = this.props.style.hoverMarker
89
- }
90
81
  if (this.props.style.aspectRatio) {
91
- this.element.style.height = (this.element.offsetWidth * this.props.style.aspectRatio) + "px"
82
+ this.context.style.height = (this.context.offsetWidth * this.props.style.aspectRatio) + "px"
92
83
  }
93
84
  this.state = new ChessboardState()
85
+ if (this.props.position === "start") {
86
+ this.state.setPosition(FEN_START_POSITION)
87
+ } else if (this.props.position === "empty" || this.props.position === undefined) {
88
+ this.state.setPosition(FEN_EMPTY_POSITION)
89
+ } else {
90
+ this.state.setPosition(this.props.position)
91
+ }
94
92
  this.state.orientation = this.props.orientation
95
-
96
93
  const viewType = this.props.accessible ? ChessboardViewAccessible : ChessboardView
97
- this.view = new viewType(this, (view) => {
98
- if (this.props.position === "start") {
99
- this.state.setPosition(FEN_START_POSITION)
100
- } else if (this.props.position === "empty" || this.props.position === undefined) {
101
- this.state.setPosition(FEN_EMPTY_POSITION)
102
- } else {
103
- this.state.setPosition(this.props.position)
104
- }
105
- view.redraw()
106
- })
94
+ this.view = new viewType(this)
107
95
  }
108
96
 
109
97
  // API //
@@ -211,9 +199,9 @@ export class Chessboard {
211
199
  this.view = undefined
212
200
  this.state = undefined
213
201
  if (this.squareSelectListener) {
214
- this.element.removeEventListener("contextmenu", this.squareSelectListener)
215
- this.element.removeEventListener("mouseup", this.squareSelectListener)
216
- this.element.removeEventListener("touchend", this.squareSelectListener)
202
+ this.context.removeEventListener("contextmenu", this.squareSelectListener)
203
+ this.context.removeEventListener("mouseup", this.squareSelectListener)
204
+ this.context.removeEventListener("touchend", this.squareSelectListener)
217
205
  }
218
206
  }
219
207
 
@@ -260,20 +248,20 @@ export class Chessboard {
260
248
  square: SQUARE_COORDINATES[index]
261
249
  })
262
250
  }
263
- this.element.addEventListener("contextmenu", this.squareSelectListener)
264
- this.element.addEventListener("mouseup", this.squareSelectListener)
265
- this.element.addEventListener("touchend", this.squareSelectListener)
251
+ this.context.addEventListener("contextmenu", this.squareSelectListener)
252
+ this.context.addEventListener("mouseup", this.squareSelectListener)
253
+ this.context.addEventListener("touchend", this.squareSelectListener)
266
254
  this.state.squareSelectEnabled = true
267
- this.view.setCursor()
255
+ this.view.visualizeInputState()
268
256
  }
269
257
 
270
258
  disableSquareSelect() {
271
- this.element.removeEventListener("contextmenu", this.squareSelectListener)
272
- this.element.removeEventListener("mouseup", this.squareSelectListener)
273
- this.element.removeEventListener("touchend", this.squareSelectListener)
259
+ this.context.removeEventListener("contextmenu", this.squareSelectListener)
260
+ this.context.removeEventListener("mouseup", this.squareSelectListener)
261
+ this.context.removeEventListener("touchend", this.squareSelectListener)
274
262
  this.squareSelectListener = undefined
275
263
  this.state.squareSelectEnabled = false
276
- this.view.setCursor()
264
+ this.view.visualizeInputState()
277
265
  }
278
266
 
279
267
  }
@@ -60,7 +60,7 @@ export const SQUARE_COORDINATES = [
60
60
 
61
61
  export class ChessboardView {
62
62
 
63
- constructor(chessboard, callbackAfterCreation) {
63
+ constructor(chessboard) {
64
64
  this.animationRunning = false
65
65
  this.currentAnimation = undefined
66
66
  this.chessboard = chessboard
@@ -80,7 +80,7 @@ export class ChessboardView {
80
80
  this.resizeObserver = new ResizeObserver(() => {
81
81
  this.handleResize()
82
82
  })
83
- this.resizeObserver.observe(this.chessboard.element)
83
+ this.resizeObserver.observe(this.chessboard.context)
84
84
  } else {
85
85
  this.resizeListener = this.handleResize.bind(this)
86
86
  window.addEventListener("resize", this.resizeListener)
@@ -88,15 +88,15 @@ export class ChessboardView {
88
88
  }
89
89
 
90
90
  this.pointerDownListener = this.pointerDownHandler.bind(this)
91
- this.chessboard.element.addEventListener("mousedown", this.pointerDownListener)
92
- this.chessboard.element.addEventListener("touchstart", this.pointerDownListener)
91
+ this.chessboard.context.addEventListener("mousedown", this.pointerDownListener)
92
+ this.chessboard.context.addEventListener("touchstart", this.pointerDownListener)
93
93
 
94
94
  this.createSvgAndGroups()
95
95
  this.updateMetrics()
96
- callbackAfterCreation(this)
97
96
  if (chessboard.props.responsive) {
98
97
  this.handleResize()
99
98
  }
99
+ this.redraw()
100
100
  }
101
101
 
102
102
  pointerDownHandler(e) {
@@ -106,13 +106,13 @@ export class ChessboardView {
106
106
  destroy() {
107
107
  this.moveInput.destroy()
108
108
  if (this.resizeObserver) {
109
- this.resizeObserver.unobserve(this.chessboard.element)
109
+ this.resizeObserver.unobserve(this.chessboard.context)
110
110
  }
111
111
  if (this.resizeListener) {
112
112
  window.removeEventListener("resize", this.resizeListener)
113
113
  }
114
- this.chessboard.element.removeEventListener("mousedown", this.pointerDownListener)
115
- this.chessboard.element.removeEventListener("touchstart", this.pointerDownListener)
114
+ this.chessboard.context.removeEventListener("mousedown", this.pointerDownListener)
115
+ this.chessboard.context.removeEventListener("touchstart", this.pointerDownListener)
116
116
  Svg.removeElement(this.svg)
117
117
  this.animationQueue = []
118
118
  if (this.currentAnimation) {
@@ -142,7 +142,7 @@ export class ChessboardView {
142
142
  if (this.svg) {
143
143
  Svg.removeElement(this.svg)
144
144
  }
145
- this.svg = Svg.createSvg(this.chessboard.element)
145
+ this.svg = Svg.createSvg(this.chessboard.context)
146
146
  let description = document.createElement("description")
147
147
  description.innerText = "Chessboard"
148
148
  description.id = "svg-description"
@@ -159,8 +159,8 @@ export class ChessboardView {
159
159
  }
160
160
 
161
161
  updateMetrics() {
162
- this.width = this.chessboard.element.clientWidth
163
- this.height = this.chessboard.element.clientHeight
162
+ this.width = this.chessboard.context.clientWidth
163
+ this.height = this.chessboard.context.clientHeight
164
164
  if (this.chessboard.props.style.borderType === BORDER_TYPE.frame) {
165
165
  this.borderSize = this.width / 25
166
166
  } else if (this.chessboard.props.style.borderType === BORDER_TYPE.thin) {
@@ -179,10 +179,10 @@ export class ChessboardView {
179
179
 
180
180
  handleResize() {
181
181
  if (this.chessboard.props.style.aspectRatio) {
182
- this.chessboard.element.style.height = (this.chessboard.element.clientWidth * this.chessboard.props.style.aspectRatio) + "px"
182
+ this.chessboard.context.style.height = (this.chessboard.context.clientWidth * this.chessboard.props.style.aspectRatio) + "px"
183
183
  }
184
- if (this.chessboard.element.clientWidth !== this.width ||
185
- this.chessboard.element.clientHeight !== this.height) {
184
+ if (this.chessboard.context.clientWidth !== this.width ||
185
+ this.chessboard.context.clientHeight !== this.height) {
186
186
  this.updateMetrics()
187
187
  this.redraw()
188
188
  }
@@ -194,7 +194,7 @@ export class ChessboardView {
194
194
  this.drawBoard()
195
195
  this.drawCoordinates()
196
196
  this.drawMarkers()
197
- this.setCursor()
197
+ this.visualizeInputState()
198
198
  this.drawPieces(this.chessboard.state.squares)
199
199
  }
200
200
 
@@ -413,7 +413,7 @@ export class ChessboardView {
413
413
  }
414
414
  this.chessboard.state.inputEnabled = true
415
415
  this.moveInputCallback = eventHandler
416
- this.setCursor()
416
+ this.visualizeInputState()
417
417
  }
418
418
 
419
419
  disableMoveInput() {
@@ -421,7 +421,7 @@ export class ChessboardView {
421
421
  this.chessboard.state.inputBlackEnabled = false
422
422
  this.chessboard.state.inputEnabled = false
423
423
  this.moveInputCallback = undefined
424
- this.setCursor()
424
+ this.visualizeInputState()
425
425
  }
426
426
 
427
427
  // callbacks //
@@ -465,7 +465,7 @@ export class ChessboardView {
465
465
 
466
466
  // Helpers //
467
467
 
468
- setCursor() {
468
+ visualizeInputState() {
469
469
  if (this.chessboard.state) { // fix https://github.com/shaack/cm-chessboard/issues/47
470
470
  if (this.chessboard.state.inputWhiteEnabled || this.chessboard.state.inputBlackEnabled || this.chessboard.state.squareSelectEnabled) {
471
471
  this.boardGroup.setAttribute("class", "board input-enabled")
@@ -7,17 +7,28 @@ import {ChessboardView, renderPieceTitle} from "./ChessboardView.js"
7
7
  import {COLOR} from "./Chessboard.js"
8
8
  import {piecesTranslations} from "./ChessboardView.js"
9
9
 
10
- let count = 0
11
-
12
-
13
10
  const hlTranslations = {
14
- en: {
15
- pieces_lists: "Pieces lists",
16
- board_as_table: "Chessboard as table"
17
- },
18
11
  de: {
19
12
  pieces_lists: "Figurenlisten",
20
- board_as_table: "Schachbrett als Tabelle"
13
+ board_as_table: "Schachbrett als Tabelle",
14
+ move_piece: "Figur bewegen",
15
+ from: "von",
16
+ to: "nach",
17
+ move: "bewegen",
18
+ input_white_enabled: "Eingabe Weiß aktiviert",
19
+ input_black_enabled: "Eingabe Schwarz aktiviert",
20
+ input_disabled: "Eingabe deaktiviert"
21
+ },
22
+ en: {
23
+ pieces_lists: "Pieces lists",
24
+ board_as_table: "Chessboard as table",
25
+ move_piece: "Move piece",
26
+ from: "from",
27
+ to: "to",
28
+ move: "move",
29
+ input_white_enabled: "Input white enabled",
30
+ input_black_enabled: "Input black enabled",
31
+ input_disabled: "Input disabled"
21
32
  }
22
33
  }
23
34
 
@@ -32,19 +43,58 @@ export class ChessboardViewAccessible extends ChessboardView {
32
43
  this.translations = piecesTranslations
33
44
  this.t = this.translations[this.lang]
34
45
  this.th = hlTranslations[this.lang]
35
- this.piecesListContainer = this.createElement(`<div class="cm-chessboard-content visually-hidden"><h3>${this.th.pieces_lists}</h3><div class="list"></div></div>`)
36
- this.piecesList = this.piecesListContainer.querySelector(".list")
37
- this.chessboard.element.appendChild(this.piecesListContainer)
38
- this.boardAsTableContainer = this.createElement(`<div class="cm-chessboard-content visually-hidden"><h3>${this.th.board_as_table}</h3><div class="table"></div></div>`)
46
+
47
+ this.accessibleContainer = this.createElement(`<div class="cm-chessboard-content visually-hidden"></div>`)
48
+
49
+ this.movePieceFormContainer = this.createElement(`<div><h3>${this.th.move_piece}</h3><form>
50
+ <label for="move_piece_input_from_${chessboard.id}">${this.th.from}</label><input class="input-from" type="text" size="2" id="move_piece_input_from_${chessboard.id}"/>
51
+ <label for="move_piece_input_to_${chessboard.id}">${this.th.to}</label><input class="input-to" type="text" size="2" id="move_piece_input_to_${chessboard.id}"/>
52
+ <button type="button" class="button-move">${this.th.move}</button>
53
+ </form><div class="input-status" aria-live="polite"></div></div>`)
54
+ this.inputFrom = this.movePieceFormContainer.querySelector(".input-from")
55
+ this.inputTo = this.movePieceFormContainer.querySelector(".input-to")
56
+ this.moveButton = this.movePieceFormContainer.querySelector(".button-move")
57
+ this.moveButton.addEventListener("click", () => {
58
+ this.chessboard.movePiece(this.inputFrom.value, this.inputTo.value, true)
59
+ })
60
+ this.accessibleContainer.appendChild(this.movePieceFormContainer)
61
+
62
+ this.boardAsTableContainer = this.createElement(`<div><h3>${this.th.board_as_table}</h3><div class="table"></div></div>`)
39
63
  this.boardAsTable = this.boardAsTableContainer.querySelector(".table")
40
- this.chessboard.element.appendChild(this.boardAsTableContainer)
64
+ this.accessibleContainer.appendChild(this.boardAsTableContainer)
65
+
66
+ this.piecesListContainer = this.createElement(`<div><h3>${this.th.pieces_lists}</h3><div class="list"></div></div>`)
67
+ this.piecesList = this.piecesListContainer.querySelector(".list")
68
+ this.accessibleContainer.appendChild(this.piecesListContainer)
69
+
70
+ this.chessboard.context.appendChild(this.accessibleContainer)
71
+ this.updateFormInputs()
72
+ }
73
+
74
+ visualizeInputState() {
75
+ super.visualizeInputState()
76
+ this.updateFormInputs()
77
+ }
78
+
79
+ updateFormInputs() {
80
+ if (this.inputFrom) {
81
+ if (this.chessboard.state.inputWhiteEnabled || this.chessboard.state.inputBlackEnabled) {
82
+ this.inputFrom.disabled = false
83
+ this.inputTo.disabled = false
84
+ this.moveButton.disabled = false
85
+ } else {
86
+ this.inputFrom.disabled = true
87
+ this.inputTo.disabled = true
88
+ this.moveButton.disabled = true
89
+ }
90
+ }
41
91
  }
42
92
 
43
93
  drawPieces(squares = this.chessboard.state.squares) {
44
94
  super.drawPieces(squares)
45
95
  setTimeout(() => {
46
- this.redrawPiecesLists()
47
96
  this.redrawBoardAsTable()
97
+ this.redrawPiecesLists()
48
98
  })
49
99
  }
50
100
 
@@ -59,12 +109,11 @@ export class ChessboardViewAccessible extends ChessboardView {
59
109
  listB += `<li class="list-inline-item">${renderPieceTitle(this.lang, piece.name)} ${piece.position}</li>`
60
110
  }
61
111
  }
62
- count++
63
112
  this.piecesList.innerHTML = `
64
- <h4 id="white-${count}">${this.t.colors_long.w}</h4>
65
- <ul aria-labelledby="white-${count}" class="list-inline">${listW}</ul>
66
- <h4 id="black-${count}">${this.t.colors_long.b}</h4>
67
- <ul aria-labelledby="black-${count}" class="list-inline">${listB}</ul>`
113
+ <h4 id="white_${this.chessboard.id}">${this.t.colors_long.w}</h4>
114
+ <ul aria-labelledby="white_${this.chessboard.id}" class="list-inline">${listW}</ul>
115
+ <h4 id="black_${this.chessboard.id}">${this.t.colors_long.b}</h4>
116
+ <ul aria-labelledby="black_${this.chessboard.id}" class="list-inline">${listB}</ul>`
68
117
  }
69
118
 
70
119
  redrawBoardAsTable() {
package/test/TestBoard.js CHANGED
@@ -23,7 +23,7 @@ describe("TestBoard", () => {
23
23
  sprite: {url: "../assets/images/chessboard-sprite.svg"},
24
24
  position: "start"
25
25
  })
26
- assert.equals(chessboard.element.childNodes.length, 1)
26
+ assert.equals(chessboard.context.childNodes.length, 1)
27
27
  chessboard.destroy()
28
28
  assert.equals(chessboard.state, undefined)
29
29
  })