Skip to content

Commit caa9569

Browse files
committed
Fix AutoCloseBrackets and Indent across WebKit and others (Fixes #131, Fixes #138)
1 parent 11c3227 commit caa9569

File tree

3 files changed

+29
-10
lines changed

3 files changed

+29
-10
lines changed

plugins/auto-close-brackets.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ codeInput.plugins.AutoCloseBrackets = class extends codeInput.Plugin {
2121
afterElementsAdded(codeInput) {
2222
codeInput.pluginData.autoCloseBrackets = { automatedKeypresses: false};
2323
codeInput.textareaElement.addEventListener('keydown', (event) => { this.checkBackspace(codeInput, event); });
24-
codeInput.textareaElement.addEventListener('beforeinput', (event) => { this.checkBrackets(codeInput, event); });
24+
codeInput.textareaElement.addEventListener('beforeinput', (event) => { this.checkClosingBracket(codeInput, event); });
25+
codeInput.textareaElement.addEventListener('input', (event) => { this.checkOpeningBracket(codeInput, event); });
2526
}
2627

27-
/* Deal with the automatic creation of closing bracket when opening brackets are typed, and the ability to "retype" a closing
28-
bracket where one has already been placed. */
29-
checkBrackets(codeInput, event) {
28+
/* Deal with the ability to "retype" a closing bracket where one has already
29+
been placed. Runs before input so newly typing a closing bracket can be
30+
prevented.*/
31+
checkClosingBracket(codeInput, event) {
3032
if(codeInput.pluginData.autoCloseBrackets.automatedKeypresses) return;
3133
if(event.data == codeInput.textareaElement.value[codeInput.textareaElement.selectionStart]) {
3234
// Check if a closing bracket is typed
@@ -39,7 +41,13 @@ codeInput.plugins.AutoCloseBrackets = class extends codeInput.Plugin {
3941
break;
4042
}
4143
}
42-
} else if(event.data in this.bracketPairs) {
44+
}
45+
}
46+
47+
/* Deal with the automatic creation of closing bracket when opening brackets are typed. Runs after input for consistency between browsers. */
48+
checkOpeningBracket(codeInput, event) {
49+
if(codeInput.pluginData.autoCloseBrackets.automatedKeypresses) return;
50+
if(event.data in this.bracketPairs) {
4351
// Opening bracket typed; Create bracket pair
4452
let closingBracket = this.bracketPairs[event.data];
4553
// Insert the closing bracket

plugins/indent.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
275275
}
276276

277277
// insert our indents and any text from the previous line that might have been after the line break
278+
// negative indents shouldn't exist and would only break future calculations.
279+
if(numberIndents < 0) {
280+
numberIndents = 0;
281+
}
278282
for (let i = 0; i < numberIndents; i++) {
279283
newLine += this.indentation;
280284
}
@@ -339,7 +343,8 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
339343
if(codeInput.value.substring(codeInput.textareaElement.selectionStart - this.indentationNumChars, codeInput.textareaElement.selectionStart) == this.indentation) {
340344
// Indentation before cursor = delete it
341345
codeInput.textareaElement.selectionStart -= this.indentationNumChars;
342-
document.execCommand("delete", false, "");
346+
// document.execCommand("delete", false, "");
347+
// event.preventDefault();
343348
}
344349
}
345350
}

tests/tester.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ function testAddingText(group, textarea, action, correctOutput, correctLengthToS
5959
/* Assuming the textarea is focused, add the given text to it, emitting 'input' and 'beforeinput' keyboard events (and 'keydown'/'keyup' Enter on newlines, if enterEvents is true) which plugins can handle */
6060
function addText(textarea, text, enterEvents=false) {
6161
for(let i = 0; i < text.length; i++) {
62+
const selectionStartBefore = textarea.selectionStart;
6263
if(enterEvents && text[i] == "\n") {
6364
textarea.dispatchEvent(new KeyboardEvent("keydown", { "key": "Enter" }));
6465
textarea.dispatchEvent(new KeyboardEvent("keyup", { "key": "Enter" }));
@@ -162,22 +163,27 @@ function startLoad(codeInputElem, isHLJS) {
162163
}
163164

164165
/* Make input events work and be trusted in the inputElement - thanks for this SO answer: https://stackoverflow.com/a/49519772/21785620 */
165-
function allowInputEvents(inputElement) {
166+
function allowInputEvents(inputElement, codeInputElement=undefined) {
166167
inputElement.addEventListener('input', function(e){
167168
if(!e.isTrusted){
168169
e.preventDefault();
169170
// Manually trigger
171+
// Prevent auto-close-brackets plugin recapturing the event
172+
// Needed because this interception is hacky.
173+
// TODO: Potentially plugin-agnostic way, probably automatedKeypresses var in core, won't be needed much but may be helpful extra feature.
174+
if(codeInputElement !== undefined) codeInputElement.pluginData.autoCloseBrackets.automatedKeypresses = true;
170175
document.execCommand("insertText", false, e.data);
176+
if(codeInputElement !== undefined) codeInputElement.pluginData.autoCloseBrackets.automatedKeypresses = false;
171177
}
172178
}, false);
173179
}
174180

175181
/* Start the tests using the textarea inside the code-input element and whether highlight.js is being used (as the Autodetect plugin only works with highlight.js, for example) */
176182
async function startTests(textarea, isHLJS) {
177183
textarea.focus();
178-
allowInputEvents(textarea);
179184

180185
codeInputElement = textarea.parentElement;
186+
allowInputEvents(textarea, codeInputElement);
181187

182188
/*--- Tests for core functionality ---*/
183189

@@ -438,7 +444,7 @@ console.log("I've got another line!", 2 &lt; 3, "should be true.");
438444
findInput.focus();
439445
allowInputEvents(findInput);
440446
addText(findInput, "hello");
441-
await waitAsync(150); // Wait for highlighting so matches update
447+
await waitAsync(200); // Wait for highlighting so matches update
442448

443449
replaceInput.value = "hi";
444450
replaceAllButton.click();
@@ -590,4 +596,4 @@ console.log("I've got another line!", 2 &lt; 3, "should be true.");
590596
document.querySelector("h2").style.backgroundColor = "lightgreen";
591597
document.querySelector("h2").textContent = "All Tests have Passed.";
592598
}
593-
}
599+
}

0 commit comments

Comments
 (0)