Skip to content
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

Fix caret out of view #100

Merged
merged 2 commits into from
May 27, 2024
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
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