editable-text: Clean up render() (#3895)

This commit is contained in:
Abe Jellinek 2024-03-29 01:16:58 -04:00 committed by GitHub
parent f9e25675f0
commit 37a6df4ccb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -185,111 +185,21 @@
} }
input.classList.add('input'); input.classList.add('input');
input.toggleAttribute("no-windows-native", true); input.toggleAttribute("no-windows-native", true);
let handleInput = () => { input.addEventListener('input', this._handleInput);
if (!this.multiline) { input.addEventListener('change', this._handleChange);
this._input.value = this._input.value.replace(/\n/g, ' '); input.addEventListener('focus', this._handleFocus);
} input.addEventListener('blur', this._handleBlur);
this.setAttribute('value', this._input.value); input.addEventListener('keydown', this._handleKeyDown);
}; input.addEventListener('mousedown', this._handleMouseDown);
let handleChange = (event) => { input.addEventListener('dragover', this._handleDragOver);
if (Services.focus.activeWindow !== window) { input.addEventListener('drop', this._handleDrop);
event.stopPropagation();
}
this.setAttribute('value', this._input.value);
};
input.addEventListener('mousedown', () => {
this.setAttribute("mousedown", true);
});
input.addEventListener('input', handleInput);
input.addEventListener('change', handleChange);
input.addEventListener('focus', () => {
// If the last blur was ignored because it was caused by the window becoming inactive,
// ignore this focus event as well
if (this._ignoredWindowInactiveBlur) {
this._ignoredWindowInactiveBlur = false;
return;
}
this.dispatchEvent(new CustomEvent('focus')); let focused = this.focused;
this.classList.add("focused");
// Select all text if focused via keyboard
if (!this.getAttribute("mousedown")) {
this._input.setSelectionRange(0, this._input.value.length, "backward");
}
if (!('initialValue' in this._input.dataset)) {
this._input.dataset.initialValue = this._input.value;
}
});
input.addEventListener('blur', () => {
// Ignore this blur if it was caused by the window becoming inactive (see above)
if (Services.focus.activeWindow !== window) {
this._ignoredWindowInactiveBlur = true;
return;
}
this._ignoredWindowInactiveBlur = false;
this.dispatchEvent(new Event('blur'));
this.classList.remove("focused");
this._input.scrollLeft = 0;
this._input.setSelectionRange(0, 0);
this.removeAttribute("mousedown");
delete this._input.dataset.initialValue;
});
input.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
if (this.multiline === event.shiftKey) {
event.preventDefault();
this.dispatchEvent(new CustomEvent('escape_enter'));
this._input.blur();
}
}
else if (event.key === 'Escape') {
this.dispatchEvent(new CustomEvent('escape_enter'));
let initialValue = this._input.dataset.initialValue ?? '';
this.setAttribute('value', initialValue);
this._input.value = initialValue;
this._input.blur();
}
});
input.addEventListener('mousedown', (event) => {
// Prevent a right-click from focusing the input when unfocused
if (event.button === 2 && document.activeElement !== this._input) {
event.preventDefault();
}
});
input.addEventListener('dragover', (event) => {
// If the input is not focused, override the default drop behavior
if ((document.activeElement !== this._input || Services.focus.activeWindow !== window)
&& !this.readOnly
&& event.dataTransfer.getData('text/plain')) {
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
}
});
input.addEventListener('drop', (event) => {
// If the input is not focused, replace its entire value with the dropped text
// Otherwise, the normal drop effect takes place and the text is inserted at the cursor
if ((document.activeElement !== this._input || Services.focus.activeWindow !== window)
&& !this.readOnly
&& event.dataTransfer.getData('text/plain')) {
event.preventDefault();
document.activeElement?.blur();
// Wait a tick to work around an apparent Firefox bug where the cursor stays inside the old
// input even though the new input becomes visually focused
setTimeout(() => {
this.focus();
this._input.value = event.dataTransfer.getData('text/plain');
handleInput();
});
}
});
let focused = false;
let selectionStart = this._input?.selectionStart; let selectionStart = this._input?.selectionStart;
let selectionEnd = this._input?.selectionEnd; let selectionEnd = this._input?.selectionEnd;
let selectionDirection = this._input?.selectionDirection; let selectionDirection = this._input?.selectionDirection;
if (this._input && document.activeElement === this._input) {
focused = true; if (focused) {
input.dataset.initialValue = this._input?.dataset.initialValue; input.dataset.initialValue = this._input?.dataset.initialValue;
} }
if (this._input) { if (this._input) {
@ -367,6 +277,108 @@
} }
} }
_handleInput = () => {
if (!this.multiline) {
this._input.value = this._input.value.replace(/\n/g, ' ');
}
this.setAttribute('value', this._input.value);
};
_handleChange = (event) => {
if (Services.focus.activeWindow !== window) {
event.stopPropagation();
}
this.setAttribute('value', this._input.value);
};
_handleFocus = () => {
// If the last blur was ignored because it was caused by the window becoming inactive,
// ignore this focus event as well
if (this._ignoredWindowInactiveBlur) {
this._ignoredWindowInactiveBlur = false;
return;
}
this.dispatchEvent(new CustomEvent('focus'));
this.classList.add("focused");
// Select all text if focused via keyboard
if (!this.getAttribute("mousedown")) {
this._input.setSelectionRange(0, this._input.value.length, "backward");
}
if (!('initialValue' in this._input.dataset)) {
this._input.dataset.initialValue = this._input.value;
}
};
_handleBlur = () => {
// Ignore this blur if it was caused by the window becoming inactive (see above)
if (Services.focus.activeWindow !== window) {
this._ignoredWindowInactiveBlur = true;
return;
}
this._ignoredWindowInactiveBlur = false;
this.dispatchEvent(new Event('blur'));
this.classList.remove("focused");
this._input.scrollLeft = 0;
this._input.setSelectionRange(0, 0);
this.removeAttribute("mousedown");
delete this._input.dataset.initialValue;
};
_handleKeyDown = (event) => {
if (event.key === 'Enter') {
if (this.multiline === event.shiftKey) {
event.preventDefault();
this.dispatchEvent(new CustomEvent('escape_enter'));
this._input.blur();
}
}
else if (event.key === 'Escape') {
this.dispatchEvent(new CustomEvent('escape_enter'));
let initialValue = this._input.dataset.initialValue ?? '';
this.setAttribute('value', initialValue);
this._input.value = initialValue;
this._input.blur();
}
};
_handleMouseDown = (event) => {
this.setAttribute("mousedown", true);
// Prevent a right-click from focusing the input when unfocused
if (event.button === 2 && document.activeElement !== this._input) {
event.preventDefault();
}
};
_handleDragOver = (event) => {
// If the input is not focused, override the default drop behavior
if ((document.activeElement !== this._input || Services.focus.activeWindow !== window)
&& !this.readOnly
&& event.dataTransfer.getData('text/plain')) {
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
}
};
_handleDrop = (event) => {
// If the input is not focused, replace its entire value with the dropped text
// Otherwise, the normal drop effect takes place and the text is inserted at the cursor
if ((document.activeElement !== this._input || Services.focus.activeWindow !== window)
&& !this.readOnly
&& event.dataTransfer.getData('text/plain')) {
event.preventDefault();
document.activeElement?.blur();
// Wait a tick to work around an apparent Firefox bug where the cursor stays inside the old
// input even though the new input becomes visually focused
setTimeout(() => {
this.focus();
this._input.value = event.dataTransfer.getData('text/plain');
this._handleInput();
});
}
};
focus(options) { focus(options) {
// If the window isn't active, the focus event won't fire yet, // If the window isn't active, the focus event won't fire yet,
// so store the initial value now // so store the initial value now