Don't trigger a blur event when focusing the same editor twice

This commit is contained in:
Antonio Scandurra 2016-10-17 14:32:03 +02:00
parent a6999e4a82
commit 883bb15276
2 changed files with 24 additions and 13 deletions

View File

@ -94,6 +94,23 @@ describe "TextEditorElement", ->
document.body.focus()
expect(blurCalled).toBe true
it "doesn't trigger a blur event on the editor element when focusing an already focused editor element", ->
blurCalled = false
element = new TextEditorElement
element.addEventListener 'blur', -> blurCalled = true
jasmineContent.appendChild(element)
expect(document.activeElement).toBe(document.body)
expect(blurCalled).toBe(false)
element.focus()
expect(document.activeElement).toBe(element.querySelector('input'))
expect(blurCalled).toBe(false)
element.focus()
expect(document.activeElement).toBe(element.querySelector('input'))
expect(blurCalled).toBe(false)
describe "when focused while a parent node is being attached to the DOM", ->
class ElementThatFocusesChild extends HTMLDivElement
attachedCallback: ->

View File

@ -50,7 +50,7 @@ class TextEditorElement extends HTMLElement
@mountComponent() unless @component?
@listenForComponentEvents()
@component.checkForVisibilityChange()
if this is document.activeElement
if @hasFocus()
@focused()
@emitter.emit("did-attach")
@ -121,7 +121,7 @@ class TextEditorElement extends HTMLElement
@rootElement.appendChild(@component.getDomNode())
inputNode = @component.hiddenInputComponent.getDomNode()
inputNode.addEventListener 'focus', @focused.bind(this)
inputNode.addEventListener 'blur', => @dispatchEvent(new FocusEvent('blur', bubbles: false))
inputNode.addEventListener 'blur', @inputNodeBlurred.bind(this)
unmountComponent: ->
if @component?
@ -129,24 +129,18 @@ class TextEditorElement extends HTMLElement
@component.getDomNode().remove()
@component = null
focused: ->
focused: (event) ->
@component?.focused()
blurred: (event) ->
if event.relatedTarget is @component.hiddenInputComponent.getDomNode()
if event.relatedTarget is @component?.hiddenInputComponent.getDomNode()
event.stopImmediatePropagation()
return
@component?.blurred()
# Work around what seems to be a bug in Chromium. Focus can be stolen from the
# hidden input when clicking on the gutter and transferred to the
# already-focused host element. The host element never gets a 'focus' event
# however, which leaves us in a limbo state where the text editor element is
# focused but the hidden input isn't focused. This always refocuses the hidden
# input if a blur event occurs in the shadow DOM that is transferring focus
# back to the host element.
# shadowRootBlurred: (event) ->
# @component.focused() if event.relatedTarget is this
inputNodeBlurred: (event) ->
if event.relatedTarget isnt this
@dispatchEvent(new FocusEvent('blur', bubbles: false))
addGrammarScopeAttribute: ->
@dataset.grammar = @model.getGrammar()?.scopeName?.replace(/\./g, ' ')