kokopu-react 1.5.2 → 1.5.3
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/CHANGELOG.md +6 -0
- package/dist/lib/Movetext.js +154 -67
- package/graphic_test_app/16_movetext_interaction.js +1 -0
- package/package.json +1 -1
- package/src/Movetext.js +128 -68
- package/test/8_movetext_interaction.js +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
ChangeLog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
1.5.3 (April 30, 2022)
|
|
5
|
+
----------------------
|
|
6
|
+
* Add method `Movetext#focus()`.
|
|
7
|
+
* Expose static methods `Movetext#firstNodeId(..)`, `Movetext#previousNodeId(..)`, `Movetext#nextNodeId(..)`
|
|
8
|
+
and `Movetext#lastNodeId(..)`.
|
|
9
|
+
|
|
4
10
|
1.5.2 (April 29, 2022)
|
|
5
11
|
----------------------
|
|
6
12
|
* Prevent default actions when handling key events in component `Movetext`.
|
package/dist/lib/Movetext.js
CHANGED
|
@@ -523,46 +523,35 @@ var Movetext = /*#__PURE__*/function (_React$Component) {
|
|
|
523
523
|
}, {
|
|
524
524
|
key: "handleKeyDownInFocusField",
|
|
525
525
|
value: function handleKeyDownInFocusField(evt) {
|
|
526
|
-
if (evt.key
|
|
527
|
-
|
|
526
|
+
if (evt.key !== 'Home' && evt.key !== 'ArrowLeft' && evt.key !== 'ArrowRight' && evt.key !== 'End') {
|
|
527
|
+
return;
|
|
528
528
|
}
|
|
529
529
|
|
|
530
|
+
evt.preventDefault();
|
|
531
|
+
|
|
530
532
|
if (!this.props.selection) {
|
|
531
533
|
return;
|
|
532
534
|
}
|
|
533
535
|
|
|
534
|
-
var
|
|
535
|
-
|
|
536
|
+
var _parseGame = parseGame(this.props.game, this.props.gameIndex),
|
|
537
|
+
game = _parseGame.game;
|
|
538
|
+
|
|
539
|
+
var nodeId = undefined;
|
|
536
540
|
var evtOrigin = '';
|
|
537
541
|
|
|
538
|
-
if (
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
542
|
+
if (evt.key === 'Home') {
|
|
543
|
+
nodeId = Movetext.firstNodeId(game, this.props.selection);
|
|
544
|
+
evtOrigin = 'key-first';
|
|
545
|
+
} else if (evt.key === 'ArrowLeft') {
|
|
546
|
+
nodeId = Movetext.previousNodeId(game, this.props.selection);
|
|
547
|
+
evtOrigin = 'key-previous';
|
|
548
|
+
} else if (evt.key === 'ArrowRight') {
|
|
549
|
+
nodeId = Movetext.nextNodeId(game, this.props.selection);
|
|
550
|
+
evtOrigin = 'key-next';
|
|
546
551
|
} else {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
if (evt.key === 'Home') {
|
|
554
|
-
nodeId = 'start';
|
|
555
|
-
evtOrigin = 'key-first';
|
|
556
|
-
} else if (evt.key === 'ArrowLeft') {
|
|
557
|
-
nodeId = getPreviousNodeId(currentNode);
|
|
558
|
-
evtOrigin = 'key-previous';
|
|
559
|
-
} else if (evt.key === 'ArrowRight') {
|
|
560
|
-
nodeId = getNextNodeId(currentNode, false);
|
|
561
|
-
evtOrigin = 'key-next';
|
|
562
|
-
} else if (evt.key === 'End') {
|
|
563
|
-
nodeId = getLastNodeId(currentNode, false);
|
|
564
|
-
evtOrigin = 'key-last';
|
|
565
|
-
}
|
|
552
|
+
// evt.key === 'End'
|
|
553
|
+
nodeId = Movetext.lastNodeId(game, this.props.selection);
|
|
554
|
+
evtOrigin = 'key-last';
|
|
566
555
|
}
|
|
567
556
|
|
|
568
557
|
if (nodeId && this.props.onMoveSelected) {
|
|
@@ -572,7 +561,7 @@ var Movetext = /*#__PURE__*/function (_React$Component) {
|
|
|
572
561
|
}, {
|
|
573
562
|
key: "handleNodeClicked",
|
|
574
563
|
value: function handleNodeClicked(nodeId) {
|
|
575
|
-
this.
|
|
564
|
+
this.focus();
|
|
576
565
|
|
|
577
566
|
if (this.props.onMoveSelected) {
|
|
578
567
|
this.props.onMoveSelected(nodeId === this.props.selection ? undefined : nodeId, 'click');
|
|
@@ -612,6 +601,139 @@ var Movetext = /*#__PURE__*/function (_React$Component) {
|
|
|
612
601
|
};
|
|
613
602
|
}
|
|
614
603
|
}
|
|
604
|
+
/**
|
|
605
|
+
* Set the focus to the current component.
|
|
606
|
+
*
|
|
607
|
+
* @public
|
|
608
|
+
*/
|
|
609
|
+
|
|
610
|
+
}, {
|
|
611
|
+
key: "focus",
|
|
612
|
+
value: function focus() {
|
|
613
|
+
this.focusFieldRef.current.focus();
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Return the ID of the main variation in the given chess game.
|
|
617
|
+
* If the given selection corresponds already at the main variation, `undefined` is returned.
|
|
618
|
+
*
|
|
619
|
+
* This corresponds to the operation performed when the user presses key "home" on a `Movetext` component.
|
|
620
|
+
*
|
|
621
|
+
* @param {kokopu.Game} game Considered chess game.
|
|
622
|
+
* @param {string} selection ID of the selected move (or `'start'` for the beginning of the main variation).
|
|
623
|
+
* @returns {string?}
|
|
624
|
+
* @public
|
|
625
|
+
*/
|
|
626
|
+
|
|
627
|
+
}], [{
|
|
628
|
+
key: "firstNodeId",
|
|
629
|
+
value: function firstNodeId(game, selection) {
|
|
630
|
+
if (!game.findById(selection)) {
|
|
631
|
+
return undefined;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
return selection === 'start' ? undefined : 'start';
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Return the ID of the node immediately preceding the given selection in the given chess game.
|
|
638
|
+
* If no such node exists, `undefined` is returned.
|
|
639
|
+
*
|
|
640
|
+
* This corresponds to the operation performed when the user presses key "arrow left" on a `Movetext` component.
|
|
641
|
+
*
|
|
642
|
+
* @param {kokopu.Game} game Considered chess game.
|
|
643
|
+
* @param {string} selection ID of the selected move (or `'start'` for the beginning of the main variation).
|
|
644
|
+
* @returns {string?}
|
|
645
|
+
* @public
|
|
646
|
+
*/
|
|
647
|
+
|
|
648
|
+
}, {
|
|
649
|
+
key: "previousNodeId",
|
|
650
|
+
value: function previousNodeId(game, selection) {
|
|
651
|
+
var currentNode = game.findById(selection);
|
|
652
|
+
|
|
653
|
+
if (!currentNode) {
|
|
654
|
+
return undefined;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if (selection === 'start') {
|
|
658
|
+
return undefined;
|
|
659
|
+
} else if (selection.endsWith('start')) {
|
|
660
|
+
currentNode = currentNode.parentNode(); // `.parentNode()` returns always non-null ref here
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
while (currentNode) {
|
|
664
|
+
var previousNode = currentNode.previous();
|
|
665
|
+
|
|
666
|
+
if (previousNode) {
|
|
667
|
+
return previousNode.id();
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
currentNode = currentNode.parentVariation().parentNode();
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
return 'start';
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Return the ID of the node immediately following the given selection in the given chess game.
|
|
677
|
+
* If no such node exists, `undefined` is returned.
|
|
678
|
+
*
|
|
679
|
+
* This corresponds to the operation performed when the user presses key "arrow right" on a `Movetext` component.
|
|
680
|
+
*
|
|
681
|
+
* @param {kokopu.Game} game Considered chess game.
|
|
682
|
+
* @param {string} selection ID of the selected move (or `'start'` for the beginning of the main variation).
|
|
683
|
+
* @returns {string?}
|
|
684
|
+
* @public
|
|
685
|
+
*/
|
|
686
|
+
|
|
687
|
+
}, {
|
|
688
|
+
key: "nextNodeId",
|
|
689
|
+
value: function nextNodeId(game, selection) {
|
|
690
|
+
var currentNode = game.findById(selection);
|
|
691
|
+
|
|
692
|
+
if (!currentNode) {
|
|
693
|
+
return undefined;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
var nextNode = selection.endsWith('start') ? currentNode.first() : currentNode.next();
|
|
697
|
+
return nextNode ? nextNode.id() : undefined;
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Return the ID of the node at then end of the variation in which lies the given selection in the given chess game.
|
|
701
|
+
* If the selection is already at the end its variation, `undefined` is returned.
|
|
702
|
+
*
|
|
703
|
+
* This corresponds to the operation performed when the user presses key "end" on a `Movetext` component.
|
|
704
|
+
*
|
|
705
|
+
* @param {kokopu.Game} game Considered chess game.
|
|
706
|
+
* @param {string} selection ID of the selected move (or `'start'` for the beginning of the main variation).
|
|
707
|
+
* @returns {string?}
|
|
708
|
+
* @public
|
|
709
|
+
*/
|
|
710
|
+
|
|
711
|
+
}, {
|
|
712
|
+
key: "lastNodeId",
|
|
713
|
+
value: function lastNodeId(game, selection) {
|
|
714
|
+
var currentNode = game.findById(selection);
|
|
715
|
+
|
|
716
|
+
if (!currentNode) {
|
|
717
|
+
return undefined;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
currentNode = selection.endsWith('start') ? currentNode.first() : currentNode.next();
|
|
721
|
+
|
|
722
|
+
if (!currentNode) {
|
|
723
|
+
// Ensure that the input node is not already the last one.
|
|
724
|
+
return undefined;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
while (true) {
|
|
728
|
+
var nextNode = currentNode.next();
|
|
729
|
+
|
|
730
|
+
if (!nextNode) {
|
|
731
|
+
return currentNode.id();
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
currentNode = nextNode;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
615
737
|
}]);
|
|
616
738
|
|
|
617
739
|
return Movetext;
|
|
@@ -779,41 +901,6 @@ function figurineNotation(text, fontName) {
|
|
|
779
901
|
|
|
780
902
|
return result;
|
|
781
903
|
}
|
|
782
|
-
|
|
783
|
-
function getPreviousNodeId(currentNode) {
|
|
784
|
-
var previousNode = currentNode.previous();
|
|
785
|
-
|
|
786
|
-
if (previousNode) {
|
|
787
|
-
return previousNode.id();
|
|
788
|
-
} else {
|
|
789
|
-
var parentNode = currentNode.parentVariation().parentNode();
|
|
790
|
-
return parentNode ? getPreviousNodeId(parentNode) : 'start';
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
function getNextNodeId(currentNode, isVariation) {
|
|
795
|
-
var nextNode = isVariation ? currentNode.first() : currentNode.next();
|
|
796
|
-
return nextNode ? nextNode.id() : false;
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
function getLastNodeId(currentNode, isVariation) {
|
|
800
|
-
currentNode = isVariation ? currentNode.first() : currentNode.next();
|
|
801
|
-
|
|
802
|
-
if (!currentNode) {
|
|
803
|
-
// Ensure that the input node is not already the last one.
|
|
804
|
-
return false;
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
while (true) {
|
|
808
|
-
var nextNode = currentNode.next();
|
|
809
|
-
|
|
810
|
-
if (!nextNode) {
|
|
811
|
-
return currentNode.id();
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
currentNode = nextNode;
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
904
|
/**
|
|
818
905
|
* Try to interpret the given object as a chess game.
|
|
819
906
|
*/
|
|
@@ -39,4 +39,5 @@ testApp([ /* eslint-disable react/jsx-key */
|
|
|
39
39
|
<Movetext game={pgn} gameIndex={7} headerVisible={false} onMoveSelected={onMoveSelected} interactionMode="selectMove" selection="1w" />,
|
|
40
40
|
<Movetext game={pgn} gameIndex={7} headerVisible={false} onMoveSelected={onMoveSelected} interactionMode="selectMove" selection="6b" />,
|
|
41
41
|
<Movetext game={pgn} gameIndex={7} headerVisible={false} onMoveSelected={onMoveSelected} interactionMode="selectMove" selection="invalid-id" />,
|
|
42
|
+
<Movetext game={pgn} gameIndex={8} headerVisible={false} onMoveSelected={onMoveSelected} interactionMode="selectMove" selection="1b-v0-start" />,
|
|
42
43
|
], 'width-600'); /* eslint-enable react/jsx-key */
|
package/package.json
CHANGED
package/src/Movetext.js
CHANGED
|
@@ -331,46 +331,31 @@ export default class Movetext extends React.Component {
|
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
handleKeyDownInFocusField(evt) {
|
|
334
|
-
if (evt.key
|
|
335
|
-
|
|
334
|
+
if (evt.key !== 'Home' && evt.key !== 'ArrowLeft' && evt.key !== 'ArrowRight' && evt.key !== 'End') {
|
|
335
|
+
return;
|
|
336
336
|
}
|
|
337
|
+
evt.preventDefault();
|
|
337
338
|
if (!this.props.selection) {
|
|
338
339
|
return;
|
|
339
340
|
}
|
|
340
|
-
let game = parseGame(this.props.game, this.props.gameIndex)
|
|
341
|
-
let nodeId =
|
|
341
|
+
let { game } = parseGame(this.props.game, this.props.gameIndex);
|
|
342
|
+
let nodeId = undefined;
|
|
342
343
|
let evtOrigin = '';
|
|
343
|
-
if (
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
evtOrigin = 'key-next';
|
|
347
|
-
}
|
|
348
|
-
else if (evt.key === 'End') {
|
|
349
|
-
nodeId = getLastNodeId(game.mainVariation(), true);
|
|
350
|
-
evtOrigin = 'key-last';
|
|
351
|
-
}
|
|
344
|
+
if (evt.key === 'Home') {
|
|
345
|
+
nodeId = Movetext.firstNodeId(game, this.props.selection);
|
|
346
|
+
evtOrigin = 'key-first';
|
|
352
347
|
}
|
|
353
|
-
else {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
evtOrigin = 'key-previous';
|
|
365
|
-
}
|
|
366
|
-
else if (evt.key === 'ArrowRight') {
|
|
367
|
-
nodeId = getNextNodeId(currentNode, false);
|
|
368
|
-
evtOrigin = 'key-next';
|
|
369
|
-
}
|
|
370
|
-
else if (evt.key === 'End') {
|
|
371
|
-
nodeId = getLastNodeId(currentNode, false);
|
|
372
|
-
evtOrigin = 'key-last';
|
|
373
|
-
}
|
|
348
|
+
else if (evt.key === 'ArrowLeft') {
|
|
349
|
+
nodeId = Movetext.previousNodeId(game, this.props.selection);
|
|
350
|
+
evtOrigin = 'key-previous';
|
|
351
|
+
}
|
|
352
|
+
else if (evt.key === 'ArrowRight') {
|
|
353
|
+
nodeId = Movetext.nextNodeId(game, this.props.selection);
|
|
354
|
+
evtOrigin = 'key-next';
|
|
355
|
+
}
|
|
356
|
+
else { // evt.key === 'End'
|
|
357
|
+
nodeId = Movetext.lastNodeId(game, this.props.selection);
|
|
358
|
+
evtOrigin = 'key-last';
|
|
374
359
|
}
|
|
375
360
|
if (nodeId && this.props.onMoveSelected) {
|
|
376
361
|
this.props.onMoveSelected(nodeId, evtOrigin);
|
|
@@ -378,7 +363,7 @@ export default class Movetext extends React.Component {
|
|
|
378
363
|
}
|
|
379
364
|
|
|
380
365
|
handleNodeClicked(nodeId) {
|
|
381
|
-
this.
|
|
366
|
+
this.focus();
|
|
382
367
|
if (this.props.onMoveSelected) {
|
|
383
368
|
this.props.onMoveSelected(nodeId === this.props.selection ? undefined : nodeId, 'click');
|
|
384
369
|
}
|
|
@@ -403,6 +388,114 @@ export default class Movetext extends React.Component {
|
|
|
403
388
|
return notation => notation;
|
|
404
389
|
}
|
|
405
390
|
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Set the focus to the current component.
|
|
394
|
+
*
|
|
395
|
+
* @public
|
|
396
|
+
*/
|
|
397
|
+
focus() {
|
|
398
|
+
this.focusFieldRef.current.focus();
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/**
|
|
402
|
+
* Return the ID of the main variation in the given chess game.
|
|
403
|
+
* If the given selection corresponds already at the main variation, `undefined` is returned.
|
|
404
|
+
*
|
|
405
|
+
* This corresponds to the operation performed when the user presses key "home" on a `Movetext` component.
|
|
406
|
+
*
|
|
407
|
+
* @param {kokopu.Game} game Considered chess game.
|
|
408
|
+
* @param {string} selection ID of the selected move (or `'start'` for the beginning of the main variation).
|
|
409
|
+
* @returns {string?}
|
|
410
|
+
* @public
|
|
411
|
+
*/
|
|
412
|
+
static firstNodeId(game, selection) {
|
|
413
|
+
if (!game.findById(selection)) {
|
|
414
|
+
return undefined;
|
|
415
|
+
}
|
|
416
|
+
return selection === 'start' ? undefined : 'start';
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Return the ID of the node immediately preceding the given selection in the given chess game.
|
|
421
|
+
* If no such node exists, `undefined` is returned.
|
|
422
|
+
*
|
|
423
|
+
* This corresponds to the operation performed when the user presses key "arrow left" on a `Movetext` component.
|
|
424
|
+
*
|
|
425
|
+
* @param {kokopu.Game} game Considered chess game.
|
|
426
|
+
* @param {string} selection ID of the selected move (or `'start'` for the beginning of the main variation).
|
|
427
|
+
* @returns {string?}
|
|
428
|
+
* @public
|
|
429
|
+
*/
|
|
430
|
+
static previousNodeId(game, selection) {
|
|
431
|
+
let currentNode = game.findById(selection);
|
|
432
|
+
if (!currentNode) {
|
|
433
|
+
return undefined;
|
|
434
|
+
}
|
|
435
|
+
if (selection === 'start') {
|
|
436
|
+
return undefined;
|
|
437
|
+
}
|
|
438
|
+
else if (selection.endsWith('start')) {
|
|
439
|
+
currentNode = currentNode.parentNode(); // `.parentNode()` returns always non-null ref here
|
|
440
|
+
}
|
|
441
|
+
while (currentNode) {
|
|
442
|
+
let previousNode = currentNode.previous();
|
|
443
|
+
if (previousNode) {
|
|
444
|
+
return previousNode.id();
|
|
445
|
+
}
|
|
446
|
+
currentNode = currentNode.parentVariation().parentNode();
|
|
447
|
+
}
|
|
448
|
+
return 'start';
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Return the ID of the node immediately following the given selection in the given chess game.
|
|
453
|
+
* If no such node exists, `undefined` is returned.
|
|
454
|
+
*
|
|
455
|
+
* This corresponds to the operation performed when the user presses key "arrow right" on a `Movetext` component.
|
|
456
|
+
*
|
|
457
|
+
* @param {kokopu.Game} game Considered chess game.
|
|
458
|
+
* @param {string} selection ID of the selected move (or `'start'` for the beginning of the main variation).
|
|
459
|
+
* @returns {string?}
|
|
460
|
+
* @public
|
|
461
|
+
*/
|
|
462
|
+
static nextNodeId(game, selection) {
|
|
463
|
+
let currentNode = game.findById(selection);
|
|
464
|
+
if (!currentNode) {
|
|
465
|
+
return undefined;
|
|
466
|
+
}
|
|
467
|
+
let nextNode = selection.endsWith('start') ? currentNode.first() : currentNode.next();
|
|
468
|
+
return nextNode ? nextNode.id() : undefined;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Return the ID of the node at then end of the variation in which lies the given selection in the given chess game.
|
|
473
|
+
* If the selection is already at the end its variation, `undefined` is returned.
|
|
474
|
+
*
|
|
475
|
+
* This corresponds to the operation performed when the user presses key "end" on a `Movetext` component.
|
|
476
|
+
*
|
|
477
|
+
* @param {kokopu.Game} game Considered chess game.
|
|
478
|
+
* @param {string} selection ID of the selected move (or `'start'` for the beginning of the main variation).
|
|
479
|
+
* @returns {string?}
|
|
480
|
+
* @public
|
|
481
|
+
*/
|
|
482
|
+
static lastNodeId(game, selection) {
|
|
483
|
+
let currentNode = game.findById(selection);
|
|
484
|
+
if (!currentNode) {
|
|
485
|
+
return undefined;
|
|
486
|
+
}
|
|
487
|
+
currentNode = selection.endsWith('start') ? currentNode.first() : currentNode.next();
|
|
488
|
+
if (!currentNode) { // Ensure that the input node is not already the last one.
|
|
489
|
+
return undefined;
|
|
490
|
+
}
|
|
491
|
+
while (true) {
|
|
492
|
+
let nextNode = currentNode.next();
|
|
493
|
+
if (!nextNode) {
|
|
494
|
+
return currentNode.id();
|
|
495
|
+
}
|
|
496
|
+
currentNode = nextNode;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
406
499
|
}
|
|
407
500
|
|
|
408
501
|
|
|
@@ -569,39 +662,6 @@ function figurineNotation(text, fontName) {
|
|
|
569
662
|
}
|
|
570
663
|
|
|
571
664
|
|
|
572
|
-
function getPreviousNodeId(currentNode) {
|
|
573
|
-
let previousNode = currentNode.previous();
|
|
574
|
-
if (previousNode) {
|
|
575
|
-
return previousNode.id();
|
|
576
|
-
}
|
|
577
|
-
else {
|
|
578
|
-
let parentNode = currentNode.parentVariation().parentNode();
|
|
579
|
-
return parentNode ? getPreviousNodeId(parentNode) : 'start';
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
function getNextNodeId(currentNode, isVariation) {
|
|
585
|
-
let nextNode = isVariation ? currentNode.first() : currentNode.next();
|
|
586
|
-
return nextNode ? nextNode.id() : false;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
function getLastNodeId(currentNode, isVariation) {
|
|
591
|
-
currentNode = isVariation ? currentNode.first() : currentNode.next();
|
|
592
|
-
if (!currentNode) { // Ensure that the input node is not already the last one.
|
|
593
|
-
return false;
|
|
594
|
-
}
|
|
595
|
-
while (true) {
|
|
596
|
-
let nextNode = currentNode.next();
|
|
597
|
-
if (!nextNode) {
|
|
598
|
-
return currentNode.id();
|
|
599
|
-
}
|
|
600
|
-
currentNode = nextNode;
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
|
|
605
665
|
/**
|
|
606
666
|
* Try to interpret the given object as a chess game.
|
|
607
667
|
*/
|
|
@@ -90,6 +90,10 @@ describe('Movetext interaction', function() {
|
|
|
90
90
|
await setSandbox(browserContext, '');
|
|
91
91
|
await focusFieldElement.sendKeys(Key.END);
|
|
92
92
|
await compareSandbox(browserContext, expectedOnGoLast);
|
|
93
|
+
|
|
94
|
+
await setSandbox(browserContext, '');
|
|
95
|
+
await focusFieldElement.sendKeys(Key.ARROW_UP);
|
|
96
|
+
await compareSandbox(browserContext, '');
|
|
93
97
|
});
|
|
94
98
|
}
|
|
95
99
|
|
|
@@ -100,4 +104,5 @@ describe('Movetext interaction', function() {
|
|
|
100
104
|
itCheckKeyboardActions(5, 'key on first selected', tpl('start', 'key-first'), tpl('start', 'key-previous'), tpl('1b', 'key-next'), tpl('6b', 'key-last'));
|
|
101
105
|
itCheckKeyboardActions(6, 'key on last selected', tpl('start', 'key-first'), tpl('6w', 'key-previous'), '', '');
|
|
102
106
|
itCheckKeyboardActions(7, 'key on invalid selection', '', '', '', '');
|
|
107
|
+
itCheckKeyboardActions(8, 'key on sub-variation selected', tpl('start', 'key-first'), tpl('1w', 'key-previous'), tpl('1b-v0-1b', 'key-next'), tpl('1b-v0-3w', 'key-last'));
|
|
103
108
|
});
|