Skip to content

Test WebKit AutoCloseBrackets and others with new scrolling #144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Jul 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions code-input.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ code-input textarea, code-input:not(.code-input_pre-element-styled) pre code, co
border: 0;
min-width: calc(100% - var(--padding) * 2);
min-height: calc(100% - var(--padding) * 2);
box-sizing: content-box; /* Make height, width work consistently no matter the box-sizing of ancestors; dialogs can be styled as wanted so are excluded. */
overflow: hidden;
resize: none;
grid-row: 1;
Expand Down
2 changes: 1 addition & 1 deletion code-input.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@webcoder49/code-input",
"version": "2.5.0",
"version": "2.5.1",
"description": "Fully customisable, editable syntax-highlighted textareas.",
"browser": "code-input.js",
"scripts": {
Expand Down
30 changes: 23 additions & 7 deletions plugins/auto-close-brackets.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ codeInput.plugins.AutoCloseBrackets = class extends codeInput.Plugin {

/* Add keystroke events */
afterElementsAdded(codeInput) {
codeInput.textareaElement.addEventListener('keydown', (event) => { this.checkBackspace(codeInput, event) });
codeInput.textareaElement.addEventListener('beforeinput', (event) => { this.checkBrackets(codeInput, event); });
codeInput.pluginData.autoCloseBrackets = { automatedKeypresses: false};
codeInput.textareaElement.addEventListener('keydown', (event) => { this.checkBackspace(codeInput, event); });
codeInput.textareaElement.addEventListener('beforeinput', (event) => { this.checkClosingBracket(codeInput, event); });
codeInput.textareaElement.addEventListener('input', (event) => { this.checkOpeningBracket(codeInput, event); });
}

/* Deal with the automatic creation of closing bracket when opening brackets are typed, and the ability to "retype" a closing
bracket where one has already been placed. */
checkBrackets(codeInput, event) {
/* Deal with the ability to "retype" a closing bracket where one has already
been placed. Runs before input so newly typing a closing bracket can be
prevented.*/
checkClosingBracket(codeInput, event) {
if(codeInput.pluginData.autoCloseBrackets.automatedKeypresses) return;
if(event.data == codeInput.textareaElement.value[codeInput.textareaElement.selectionStart]) {
// Check if a closing bracket is typed
for(let openingBracket in this.bracketPairs) {
Expand All @@ -37,18 +41,30 @@ codeInput.plugins.AutoCloseBrackets = class extends codeInput.Plugin {
break;
}
}
} else if(event.data in this.bracketPairs) {
}
}

/* Deal with the automatic creation of closing bracket when opening brackets are typed. Runs after input for consistency between browsers. */
checkOpeningBracket(codeInput, event) {
if(codeInput.pluginData.autoCloseBrackets.automatedKeypresses) return;
if(event.data in this.bracketPairs) {
// Opening bracket typed; Create bracket pair
let closingBracket = this.bracketPairs[event.data];
// Insert the closing bracket
// automatedKeypresses property to prevent keypresses being captured
// by this plugin during automated input as some browsers
// (e.g. GNOME Web) do.
codeInput.pluginData.autoCloseBrackets.automatedKeypresses = true;
document.execCommand("insertText", false, closingBracket);
codeInput.pluginData.autoCloseBrackets.automatedKeypresses = false;
// Move caret before the inserted closing bracket
codeInput.textareaElement.selectionStart = codeInput.textareaElement.selectionEnd -= 1;
}
}

/* Deal with cases where a backspace deleting an opening bracket deletes the closing bracket straight after it as well */
checkBackspace(codeInput, event) {
if(codeInput.pluginData.autoCloseBrackets.automatedKeypresses) return;
if(event.key == "Backspace" && codeInput.textareaElement.selectionStart == codeInput.textareaElement.selectionEnd) {
let closingBracket = this.bracketPairs[codeInput.textareaElement.value[codeInput.textareaElement.selectionStart-1]];
if(closingBracket != undefined && codeInput.textareaElement.value[codeInput.textareaElement.selectionStart] == closingBracket) {
Expand All @@ -58,4 +74,4 @@ codeInput.plugins.AutoCloseBrackets = class extends codeInput.Plugin {
}
}
}
}
}
2 changes: 1 addition & 1 deletion plugins/auto-close-brackets.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions plugins/find-and-replace.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,11 @@ codeInput.plugins.FindAndReplace = class extends codeInput.Plugin {
const findPreviousButton = document.createElement('button');
const replaceButton = document.createElement('button');
const replaceAllButton = document.createElement('button');

// TODO: Make a button element (semantic HTML for accessibility) in next major version
const cancel = document.createElement('span');
cancel.setAttribute("role", "button");
cancel.setAttribute("aria-label", this.instructions.closeDialog);
cancel.setAttribute("tabindex", 0); // Visible to keyboard navigation
cancel.setAttribute("title", this.instructions.closeDialog);

Expand Down Expand Up @@ -243,8 +247,10 @@ codeInput.plugins.FindAndReplace = class extends codeInput.Plugin {
replaceInput.placeholder = this.instructions.replacePlaceholder;
findNextButton.innerText = "↓";
findNextButton.title = this.instructions.findNext;
findNextButton.setAttribute("aria-label", this.instructions.findNext);
findPreviousButton.innerText = "↑";
findPreviousButton.title = this.instructions.findPrevious;
findNextButton.setAttribute("aria-label", this.instructions.findPrevious);
replaceButton.className = 'code-input_find-and-replace_button-hidden';
replaceButton.innerText = this.instructions.replaceActionShort;
replaceButton.title = this.instructions.replaceAction;
Expand Down
Loading