cm-chessboard 8.14.0 → 8.14.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.
package/package.json
CHANGED
|
@@ -34,6 +34,9 @@ export const PROMOTION_DIALOG_RESULT_TYPE = {
|
|
|
34
34
|
canceled: "canceled"
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// Keys the open dialog handles itself, see handleKeyDown
|
|
38
|
+
const HANDLED_KEYS = ["ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight", "Enter", " ", "Escape", "Tab"]
|
|
39
|
+
|
|
37
40
|
export class PromotionDialog extends Extension {
|
|
38
41
|
|
|
39
42
|
/** @constructor */
|
|
@@ -259,8 +262,12 @@ export class PromotionDialog extends Extension {
|
|
|
259
262
|
this.promotionDialogOnClickPiece.bind(this))
|
|
260
263
|
this.contextMenuListener = this.contextMenu.bind(this)
|
|
261
264
|
this.chessboard.view.svg.addEventListener("contextmenu", this.contextMenuListener)
|
|
262
|
-
//
|
|
263
|
-
|
|
265
|
+
// Keyboard listener in the capture phase: while the dialog is open its keys
|
|
266
|
+
// must not reach anything else. Applications commonly bind the arrow keys on
|
|
267
|
+
// document for history navigation (chess-console does), and those listeners
|
|
268
|
+
// are registered before the dialog opens, so in the bubble phase they would
|
|
269
|
+
// run first and change the position under the open dialog.
|
|
270
|
+
document.addEventListener("keydown", this.handleKeyDown, true)
|
|
264
271
|
} else if (displayState === DISPLAY_STATE.hidden) {
|
|
265
272
|
if (this.clickDelegate) {
|
|
266
273
|
this.clickDelegate.remove()
|
|
@@ -271,7 +278,7 @@ export class PromotionDialog extends Extension {
|
|
|
271
278
|
this.contextMenuListener = null
|
|
272
279
|
}
|
|
273
280
|
// Remove keyboard listener
|
|
274
|
-
document.removeEventListener("keydown", this.handleKeyDown)
|
|
281
|
+
document.removeEventListener("keydown", this.handleKeyDown, true)
|
|
275
282
|
// Restore focus (only if the dialog was actually shown before)
|
|
276
283
|
if (prevState === DISPLAY_STATE.shown &&
|
|
277
284
|
this.previouslyFocusedElement && this.previouslyFocusedElement.focus) {
|
|
@@ -292,6 +299,12 @@ export class PromotionDialog extends Extension {
|
|
|
292
299
|
if (this.state.displayState !== DISPLAY_STATE.shown) {
|
|
293
300
|
return
|
|
294
301
|
}
|
|
302
|
+
// Keys the dialog owns are consumed here, they must not reach the page below.
|
|
303
|
+
// Without this the arrow keys would also drive an application's own history
|
|
304
|
+
// navigation and change the position while the dialog is waiting for an answer.
|
|
305
|
+
if (HANDLED_KEYS.includes(event.key)) {
|
|
306
|
+
event.stopPropagation()
|
|
307
|
+
}
|
|
295
308
|
switch (event.key) {
|
|
296
309
|
case "ArrowDown":
|
|
297
310
|
event.preventDefault()
|
|
@@ -395,7 +408,7 @@ export class PromotionDialog extends Extension {
|
|
|
395
408
|
clearTimeout(this.announceTimeoutId)
|
|
396
409
|
this.announceTimeoutId = null
|
|
397
410
|
}
|
|
398
|
-
document.removeEventListener("keydown", this.handleKeyDown)
|
|
411
|
+
document.removeEventListener("keydown", this.handleKeyDown, true)
|
|
399
412
|
if (this.liveRegion && this.liveRegion.parentNode) {
|
|
400
413
|
this.liveRegion.parentNode.removeChild(this.liveRegion)
|
|
401
414
|
this.liveRegion = null
|