mirror of
https://github.com/atom/atom.git
synced 2026-01-25 06:48:28 -05:00
Handle direct focus of hidden input and avoid redundant focus renders
This commit is contained in:
committed by
Antonio Scandurra
parent
b8a3e2f163
commit
192e7c6b63
@@ -197,7 +197,6 @@ describe('TextEditorComponent', () => {
|
||||
|
||||
element.focus() // focusing back to the element does not blur
|
||||
expect(document.activeElement).toBe(hiddenInput)
|
||||
await component.getNextUpdatePromise()
|
||||
expect(element.classList.contains('is-focused')).toBe(true)
|
||||
|
||||
document.body.focus()
|
||||
@@ -206,6 +205,17 @@ describe('TextEditorComponent', () => {
|
||||
expect(element.classList.contains('is-focused')).toBe(false)
|
||||
})
|
||||
|
||||
it('updates the component when the hidden input is focused directly', async () => {
|
||||
const {component, element, editor} = buildComponent()
|
||||
const {hiddenInput} = component.refs
|
||||
expect(element.classList.contains('is-focused')).toBe(false)
|
||||
expect(document.activeElement).not.toBe(hiddenInput)
|
||||
|
||||
hiddenInput.focus()
|
||||
await component.getNextUpdatePromise()
|
||||
expect(element.classList.contains('is-focused')).toBe(true)
|
||||
})
|
||||
|
||||
it('gracefully handles a focus event that occurs prior to the attachedCallback of the element', () => {
|
||||
const {component, element, editor} = buildComponent({attach: false})
|
||||
const parent = document.createElement('text-editor-component-test-element')
|
||||
|
||||
@@ -383,7 +383,8 @@ class TextEditorComponent {
|
||||
key: 'hiddenInput',
|
||||
className: 'hidden-input',
|
||||
on: {
|
||||
blur: this.didBlur,
|
||||
blur: this.didBlurHiddenInput,
|
||||
focus: this.didFocusHiddenInput,
|
||||
textInput: this.didTextInput,
|
||||
keydown: this.didKeydown,
|
||||
keyup: this.didKeyup,
|
||||
@@ -496,17 +497,22 @@ class TextEditorComponent {
|
||||
// against that case.
|
||||
if (!this.attached) this.didAttach()
|
||||
|
||||
const {hiddenInput} = this.refs
|
||||
if (!this.focused) {
|
||||
this.focused = true
|
||||
this.scheduleUpdate()
|
||||
}
|
||||
|
||||
// Ensure the input is in the visible part of the scrolled content to avoid
|
||||
// the browser trying to auto-scroll to the form-field.
|
||||
// Transfer focus to the hidden input, but first ensure the input is in the
|
||||
// visible part of the scrolled content to avoid the browser trying to
|
||||
// auto-scroll to the form-field.
|
||||
const {hiddenInput} = this.refs
|
||||
hiddenInput.style.top = this.getScrollTop() + 'px'
|
||||
hiddenInput.style.left = this.getScrollLeft() + 'px'
|
||||
|
||||
hiddenInput.focus()
|
||||
this.focused = true
|
||||
|
||||
// Restore the previous position of the field now that it is focused.
|
||||
// Restore the previous position of the field now that it is already focused
|
||||
// and won't cause unwanted scrolling.
|
||||
const currentHiddenInputState = this.getHiddenInputState()
|
||||
if (currentHiddenInputState) {
|
||||
hiddenInput.style.top = currentHiddenInputState.pixelTop + 'px'
|
||||
@@ -515,19 +521,26 @@ class TextEditorComponent {
|
||||
hiddenInput.style.top = 0
|
||||
hiddenInput.style.left = 0
|
||||
}
|
||||
|
||||
this.scheduleUpdate()
|
||||
}
|
||||
|
||||
didBlur (event) {
|
||||
didBlurHiddenInput (event) {
|
||||
if (this.element !== event.relatedTarget && !this.element.contains(event.relatedTarget)) {
|
||||
console.log('blur hi');
|
||||
this.focused = false
|
||||
this.scheduleUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
didFocusHiddenInput () {
|
||||
if (!this.focused) {
|
||||
console.log('focus hi');
|
||||
this.focused = true
|
||||
this.scheduleUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
didScroll () {
|
||||
if (this.measureScrollPosition()) {
|
||||
if (this.measureScrollPosition(true)) {
|
||||
this.updateSync()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user