Skip to content

Commit

Permalink
Merge pull request #100 from WebCoder49/fix-caret-out-of-view
Browse files Browse the repository at this point in the history
Fix caret out of view
  • Loading branch information
WebCoder49 committed May 27, 2024
2 parents c068194 + 3ab457c commit 6cbcc23
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 19 deletions.
6 changes: 4 additions & 2 deletions code-input.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ code-input textarea, code-input:not(.code-input_pre-element-styled) pre code, co
margin: 0px!important;
padding: var(--padding, 16px)!important;
border: 0;
min-width: calc(100% - var(--padding, 16px) * 2);
min-height: calc(100% - var(--padding, 16px) * 2);
min-width: 100%;
min-height: 100%;
box-sizing: border-box; /* Don't need to worry about padding to calculate width! */
overflow: hidden;
resize: none;
grid-row: 1;
grid-column: 1;
display: block;
}

code-input:not(.code-input_pre-element-styled) pre code, code-input.code-input_pre-element-styled pre {
height: max-content;
width: max-content;
Expand Down
39 changes: 23 additions & 16 deletions code-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ var codeInput = {
* to syntax-highlight it. */

needsHighlight = false; // Just inputted
passEventsToTextarea = true; // Turn to false when unusual internal events are called on the textarea

/**
* Highlight the code as soon as possible
Expand All @@ -494,17 +495,6 @@ var codeInput = {
* Call an animation frame
*/
animateFrame() {
// Synchronise the size of the pre/code and textarea elements
if(this.template.preElementStyled) {
this.style.backgroundColor = getComputedStyle(this.preElement).backgroundColor;
this.textareaElement.style.height = getComputedStyle(this.preElement).height;
this.textareaElement.style.width = getComputedStyle(this.preElement).width;
} else {
this.style.backgroundColor = getComputedStyle(this.codeElement).backgroundColor;
this.textareaElement.style.height = getComputedStyle(this.codeElement).height;
this.textareaElement.style.width = getComputedStyle(this.codeElement).width;
}

// Synchronise the contents of the pre/code and textarea elements
if(this.needsHighlight) {
this.update();
Expand Down Expand Up @@ -534,6 +524,22 @@ var codeInput = {
if (this.template.includeCodeInputInHighlightFunc) this.template.highlight(resultElement, this);
else this.template.highlight(resultElement);

// Synchronise the size of the pre/code and textarea elements
if(this.template.preElementStyled) {
this.style.backgroundColor = getComputedStyle(this.preElement).backgroundColor;
this.textareaElement.style.height = getComputedStyle(this.preElement).height;
this.textareaElement.style.width = getComputedStyle(this.preElement).width;
} else {
this.style.backgroundColor = getComputedStyle(this.codeElement).backgroundColor;
this.textareaElement.style.height = getComputedStyle(this.codeElement).height;
this.textareaElement.style.width = getComputedStyle(this.codeElement).width;
}
// Scroll to the caret by focusing, though this shouldn't count as a focus event
this.passEventsToTextarea = false;
this.textareaElement.blur();
this.textareaElement.focus();
this.passEventsToTextarea = true;

this.pluginEvt("afterHighlight");
}

Expand Down Expand Up @@ -737,7 +743,7 @@ var codeInput = {
if (this.template.preElementStyled) this.classList.add("code-input_pre-element-styled");
else this.classList.remove("code-input_pre-element-styled");
// Syntax Highlight
this.needsHighlight = true;
this.scheduleHighlight();

break;

Expand Down Expand Up @@ -769,7 +775,7 @@ var codeInput = {

if (mainTextarea.placeholder == oldValue) mainTextarea.placeholder = newValue;

this.needsHighlight = true;
this.scheduleHighlight();

break;
default:
Expand Down Expand Up @@ -806,8 +812,9 @@ var codeInput = {
* @override
*/
addEventListener(type, listener, options = undefined) {
// Save a copy of the callback where `this` refers to the code-input element
let boundCallback = listener.bind(this);
// Save a copy of the callback where `this` refers to the code-input element.
// This callback is modified to only run when the passEventsToTextarea is set.
let boundCallback = function(evt) { if(this.passEventsToTextarea) listener(evt); }.bind(this);
this.boundEventCallbacks[listener] = boundCallback;

if (codeInput.textareaSyncEvents.includes(type)) {
Expand Down Expand Up @@ -885,7 +892,7 @@ var codeInput = {
// Save in editable textarea element
this.textareaElement.value = val;
// Trigger highlight
this.needsHighlight = true;
this.scheduleHighlight();
return val;
}

Expand Down
33 changes: 32 additions & 1 deletion plugins/indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,33 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
}
}

/* Add keystroke events */
/* Add keystroke events, and get the width of the indentation in pixels. */
afterElementsAdded(codeInput) {
let textarea = codeInput.textareaElement;
textarea.addEventListener('keydown', (event) => { this.checkTab(codeInput, event); this.checkEnter(codeInput, event); this.checkBackspace(codeInput, event); });
textarea.addEventListener('beforeinput', (event) => { this.checkCloseBracket(codeInput, event); });

// Get the width of the indentation in pixels
let testIndentationWidthPre = document.createElement("pre");
testIndentationWidthPre.setAttribute("aria-hidden", "true"); // Hide for screen readers
let testIndentationWidthSpan = document.createElement("span");
if(codeInput.template.preElementStyled) {
testIndentationWidthPre.appendChild(testIndentationWidthSpan);
testIndentationWidthPre.classList.add("code-input_autocomplete_test-indentation-width");
codeInput.appendChild(testIndentationWidthPre); // Styled like first pre, but first pre found to update
} else {
let testIndentationWidthCode = document.createElement("code");
testIndentationWidthCode.appendChild(testIndentationWidthSpan);
testIndentationWidthCode.classList.add("code-input_autocomplete_test-indentation-width");
testIndentationWidthPre.appendChild(testIndentationWidthCode);
codeInput.appendChild(testIndentationWidthPre); // Styled like first pre, but first pre found to update
}

testIndentationWidthSpan.innerHTML = codeInput.escapeHtml(this.indentation);
let indentationWidthPx = testIndentationWidthSpan.offsetWidth;
codeInput.removeChild(testIndentationWidthPre);

codeInput.pluginData.indent = {indentationWidthPx: indentationWidthPx};
}

/* Deal with the Tab key causing indentation, and Tab+Selection indenting / Shift+Tab+Selection unindenting lines */
Expand Down Expand Up @@ -93,6 +115,15 @@ codeInput.plugins.Indent = class extends codeInput.Plugin {
// move cursor
inputElement.selectionStart = selectionStartI;
inputElement.selectionEnd = selectionEndI;

// move scroll position to follow code
console.log("indw", codeInput.pluginData.indent.indentationWidthPx);
if(event.shiftKey) {
console.log("shift");
codeInput.scrollBy(-codeInput.pluginData.indent.indentationWidthPx, 0);
} else {
codeInput.scrollBy(codeInput.pluginData.indent.indentationWidthPx, 0);
}
}

codeInput.value = inputElement.value;
Expand Down

0 comments on commit 6cbcc23

Please sign in to comment.