Skip to content

Commit e8a7bf4

Browse files
committed
Final bug fixes
1 parent 5a62113 commit e8a7bf4

9 files changed

+56
-40
lines changed

code-input.css

+8-6
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ code-input textarea {
107107
resize: none;
108108
outline: none!important;
109109
}
110-
code-input:focus-within:not(.code-input_mouse-focused) {
110+
code-input:has(textarea:focus):not(.code-input_mouse-focused) {
111111
outline: 2px solid black;
112112
}
113113

@@ -163,21 +163,23 @@ code-input .code-input_dialog-container .code-input_keyboard-navigation-instruct
163163
color: white;
164164
padding: 2px;
165165
padding-left: 10px;
166-
text-wrap: auto;
166+
text-wrap: pretty;
167+
overflow: hidden;
168+
text-overflow: ellipsis;
167169
width: calc(100% - 12px);
168170
max-height: 3em;
169171
}
170172

171-
code-input:not(:focus-within) .code-input_dialog-container .code-input_keyboard-navigation-instructions,
173+
code-input:not(:has(textarea:focus)) .code-input_dialog-container .code-input_keyboard-navigation-instructions,
172174
code-input.code-input_mouse-focused .code-input_dialog-container .code-input_keyboard-navigation-instructions,
173175
code-input .code-input_dialog-container .code-input_keyboard-navigation-instructions:empty {
174176
/* When not keyboard-focused / no instructions don't show instructions */
175177
display: none;
176178
}
177179

178180
/* Things with padding when instructions are present */
179-
code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):focus-within:not(.code-input_mouse-focused) textarea,
180-
code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):focus-within:not(.code-input_mouse-focused):not(.code-input_pre-element-styled) pre code,
181-
code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):focus-within:not(.code-input_mouse-focused).code-input_pre-element-styled pre {
181+
code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:focus):not(.code-input_mouse-focused) textarea,
182+
code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:focus):not(.code-input_mouse-focused):not(.code-input_pre-element-styled) pre code,
183+
code-input:not(:has(.code-input_keyboard-navigation-instructions:empty)):has(textarea:focus):not(.code-input_mouse-focused).code-input_pre-element-styled pre {
182184
padding-top: calc(var(--padding) + 3em)!important;
183185
}

code-input.js

+27-14
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,8 @@ var codeInput = {
482482
* to syntax-highlight it. */
483483

484484
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;
486487

487488
/**
488489
* Highlight the code as soon as possible
@@ -510,6 +511,7 @@ var codeInput = {
510511
update() {
511512
let resultElement = this.codeElement;
512513
let value = this.value;
514+
value += "\n"; // Placeholder for next line
513515

514516
// Update code
515517
resultElement.innerHTML = this.escapeHtml(value);
@@ -523,17 +525,17 @@ var codeInput = {
523525

524526
// If editing here, scroll to the caret by focusing, though this shouldn't count as a focus event
525527
if(this.textareaElement === document.activeElement) {
526-
this.passEventsToTextarea = false;
528+
this.handleEventsFromTextarea = false;
527529
this.textareaElement.blur();
528530
this.textareaElement.focus();
529-
this.passEventsToTextarea = true;
531+
this.handleEventsFromTextarea = true;
530532
}
531533

532534
this.pluginEvt("afterHighlight");
533535
}
534536

535537
/**
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.
537539
*/
538540
syncSize() {
539541
// Synchronise the size of the pre/code and textarea elements
@@ -551,10 +553,15 @@ var codeInput = {
551553
/**
552554
* 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.
553555
* @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.
554557
*/
555-
setKeyboardNavInstructions(instructions) {
558+
setKeyboardNavInstructions(instructions, includeAriaDescriptionFirst) {
556559
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+
}
558565
}
559566

560567
/**
@@ -619,9 +626,6 @@ var codeInput = {
619626

620627
this.initialValue = value; // For form reset
621628

622-
// Disable focusing on the code-input element - only allow the textarea to be focusable
623-
this.setAttribute("tabindex", -1);
624-
625629
// Create textarea
626630
let textarea = document.createElement("textarea");
627631
textarea.placeholder = placeholder;
@@ -630,13 +634,19 @@ var codeInput = {
630634
}
631635
textarea.innerHTML = this.innerHTML;
632636
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";
633643

634644
// Accessibility - detect when mouse focus to remove focus outline + keyboard navigation guidance that could irritate users.
635-
textarea.addEventListener("mousedown", () => {
645+
this.addEventListener("mousedown", () => {
636646
this.classList.add("code-input_mouse-focused");
637647
});
638648
textarea.addEventListener("blur", () => {
639-
if(this.passEventsToTextarea) {
649+
if(this.handleEventsFromTextarea) {
640650
this.classList.remove("code-input_mouse-focused");
641651
}
642652
});
@@ -854,12 +864,15 @@ var codeInput = {
854864
*/
855865
addEventListener(type, listener, options = undefined) {
856866
// 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);
859869
this.boundEventCallbacks[listener] = boundCallback;
860870

861871
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+
863876
if (options === undefined) {
864877
if(this.textareaElement == null) {
865878
this.addEventListener("code-input_load", () => { this.textareaElement.addEventListener(type, boundCallback); });

0 commit comments

Comments
 (0)