@@ -482,7 +482,8 @@ var codeInput = {
482
482
* to syntax-highlight it. */
483
483
484
484
needsHighlight = false ; // Just inputted
485
- passEventsToTextarea = true ; // Turn to false when unusual internal events are called on the textarea
485
+ handleEventsFromTextarea = true ; // Turn to false when unusual internal events are called on the textarea
486
+ originalAriaDescription ;
486
487
487
488
/**
488
489
* Highlight the code as soon as possible
@@ -510,6 +511,7 @@ var codeInput = {
510
511
update ( ) {
511
512
let resultElement = this . codeElement ;
512
513
let value = this . value ;
514
+ value += "\n" ; // Placeholder for next line
513
515
514
516
// Update code
515
517
resultElement . innerHTML = this . escapeHtml ( value ) ;
@@ -523,17 +525,17 @@ var codeInput = {
523
525
524
526
// If editing here, scroll to the caret by focusing, though this shouldn't count as a focus event
525
527
if ( this . textareaElement === document . activeElement ) {
526
- this . passEventsToTextarea = false ;
528
+ this . handleEventsFromTextarea = false ;
527
529
this . textareaElement . blur ( ) ;
528
530
this . textareaElement . focus ( ) ;
529
- this . passEventsToTextarea = true ;
531
+ this . handleEventsFromTextarea = true ;
530
532
}
531
533
532
534
this . pluginEvt ( "afterHighlight" ) ;
533
535
}
534
536
535
537
/**
536
- * Set the size of the pre/code element to the size of the textarea element.
538
+ * Set the size of the textarea element to the size of the pre/code element.
537
539
*/
538
540
syncSize ( ) {
539
541
// Synchronise the size of the pre/code and textarea elements
@@ -551,10 +553,15 @@ var codeInput = {
551
553
/**
552
554
* Show some instructions to the user only if they are using keyboard navigation - for example, a prompt on how to navigate with the keyboard if Tab is repurposed.
553
555
* @param {string } instructions The instructions to display only if keyboard navigation is being used. If it's blank, no instructions will be shown.
556
+ * @param {boolean } includeAriaDescriptionFirst Whether to include the aria-description of the code-input element before the keyboard navigation instructions for a screenreader. Keep this as true when the textarea is first focused.
554
557
*/
555
- setKeyboardNavInstructions ( instructions ) {
558
+ setKeyboardNavInstructions ( instructions , includeAriaDescriptionFirst ) {
556
559
this . dialogContainerElement . querySelector ( ".code-input_keyboard-navigation-instructions" ) . innerText = instructions ;
557
- this . setAttribute ( "aria-description" , "code-input. " + instructions ) ;
560
+ if ( includeAriaDescriptionFirst ) {
561
+ this . textareaElement . setAttribute ( "aria-description" , this . originalAriaDescription + ". " + instructions ) ;
562
+ } else {
563
+ this . textareaElement . setAttribute ( "aria-description" , instructions ) ;
564
+ }
558
565
}
559
566
560
567
/**
@@ -619,9 +626,6 @@ var codeInput = {
619
626
620
627
this . initialValue = value ; // For form reset
621
628
622
- // Disable focusing on the code-input element - only allow the textarea to be focusable
623
- this . setAttribute ( "tabindex" , - 1 ) ;
624
-
625
629
// Create textarea
626
630
let textarea = document . createElement ( "textarea" ) ;
627
631
textarea . placeholder = placeholder ;
@@ -630,13 +634,19 @@ var codeInput = {
630
634
}
631
635
textarea . innerHTML = this . innerHTML ;
632
636
textarea . setAttribute ( "spellcheck" , "false" ) ;
637
+
638
+ // Disable focusing on the code-input element - only allow the textarea to be focusable
639
+ textarea . setAttribute ( "tabindex" , this . getAttribute ( "tabindex" ) || 0 ) ;
640
+ this . setAttribute ( "tabindex" , - 1 ) ;
641
+ // Save aria-description so keyboard navigation guidance can be added.
642
+ this . originalAriaDescription = this . getAttribute ( "aria-description" ) || "Code input field" ;
633
643
634
644
// Accessibility - detect when mouse focus to remove focus outline + keyboard navigation guidance that could irritate users.
635
- textarea . addEventListener ( "mousedown" , ( ) => {
645
+ this . addEventListener ( "mousedown" , ( ) => {
636
646
this . classList . add ( "code-input_mouse-focused" ) ;
637
647
} ) ;
638
648
textarea . addEventListener ( "blur" , ( ) => {
639
- if ( this . passEventsToTextarea ) {
649
+ if ( this . handleEventsFromTextarea ) {
640
650
this . classList . remove ( "code-input_mouse-focused" ) ;
641
651
}
642
652
} ) ;
@@ -854,12 +864,15 @@ var codeInput = {
854
864
*/
855
865
addEventListener ( type , listener , options = undefined ) {
856
866
// Save a copy of the callback where `this` refers to the code-input element.
857
- // This callback is modified to only run when the passEventsToTextarea is set.
858
- let boundCallback = function ( evt ) { if ( this . passEventsToTextarea ) listener ( evt ) ; } . bind ( this ) ;
867
+ // This callback is modified to only run when the handleEventsFromTextarea is set.
868
+ let boundCallback = function ( evt ) { listener ( evt ) ; } . bind ( this ) ;
859
869
this . boundEventCallbacks [ listener ] = boundCallback ;
860
870
861
871
if ( codeInput . textareaSyncEvents . includes ( type ) ) {
862
- // Synchronise with textarea
872
+ // Synchronise with textarea, only when handleEventsFromTextarea is true
873
+ let boundCallback = function ( evt ) { if ( this . handleEventsFromTextarea ) listener ( evt ) ; } . bind ( this ) ;
874
+ this . boundEventCallbacks [ listener ] = boundCallback ;
875
+
863
876
if ( options === undefined ) {
864
877
if ( this . textareaElement == null ) {
865
878
this . addEventListener ( "code-input_load" , ( ) => { this . textareaElement . addEventListener ( type , boundCallback ) ; } ) ;
0 commit comments