diff --git a/spec/text-editor-element-spec.coffee b/spec/text-editor-element-spec.coffee index 7ed4a106f..468adaf04 100644 --- a/spec/text-editor-element-spec.coffee +++ b/spec/text-editor-element-spec.coffee @@ -78,6 +78,19 @@ describe "TextEditorElement", -> jasmine.attachToDOM(element) expect(element.querySelectorAll('.decoration').length).toBe initialDecorationCount + it "can be re-focused using the previous `document.activeElement`", -> + editorElement = document.createElement('atom-text-editor') + jasmine.attachToDOM(editorElement) + editorElement.focus() + + activeElement = document.activeElement + + editorElement.remove() + jasmine.attachToDOM(editorElement) + activeElement.focus() + + expect(editorElement.hasFocus()).toBe(true) + describe "focus and blur handling", -> it "proxies focus/blur events to/from the hidden input", -> element = new TextEditorElement diff --git a/src/input-component.coffee b/src/input-component.coffee index b8081b0d6..27543a2fd 100644 --- a/src/input-component.coffee +++ b/src/input-component.coffee @@ -1,15 +1,6 @@ module.exports = class InputComponent - constructor: -> - @domNode = document.createElement('input') - @domNode.classList.add('hidden-input') - @domNode.setAttribute('tabindex', -1) - @domNode.setAttribute('data-react-skip-selection-restoration', true) - @domNode.style['-webkit-transform'] = 'translateZ(0)' - @domNode.addEventListener 'paste', (event) -> event.preventDefault() - - getDomNode: -> - @domNode + constructor: (@domNode) -> updateSync: (state) -> @oldState ?= {} diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 8bf72d62d..e8591819f 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -42,7 +42,7 @@ class TextEditorComponent @assert domNode?, "TextEditorComponent::domNode was set to null." @domNodeValue = domNode - constructor: ({@editor, @hostElement, tileSize, @views, @themes, @styles, @assert}) -> + constructor: ({@editor, @hostElement, tileSize, @views, @themes, @styles, @assert, hiddenInputElement}) -> @tileSize = tileSize if tileSize? @disposables = new CompositeDisposable @@ -70,12 +70,12 @@ class TextEditorComponent @scrollViewNode.classList.add('scroll-view') @domNode.appendChild(@scrollViewNode) - @hiddenInputComponent = new InputComponent - @scrollViewNode.appendChild(@hiddenInputComponent.getDomNode()) + @hiddenInputComponent = new InputComponent(hiddenInputElement) + @scrollViewNode.appendChild(hiddenInputElement) # Add a getModel method to the hidden input component to make it easy to # access the editor in response to DOM events or when using # document.activeElement. - @hiddenInputComponent.getDomNode().getModel = => @editor + hiddenInputElement.getModel = => @editor @linesComponent = new LinesComponent({@presenter, @domElementPool, @assert, @grammars, @views}) @scrollViewNode.appendChild(@linesComponent.getDomNode()) @@ -346,7 +346,6 @@ class TextEditorComponent focused: -> if @mounted @presenter.setFocused(true) - @hiddenInputComponent.getDomNode().focus() blurred: -> if @mounted diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 8f2538ede..8c9792916 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -25,8 +25,17 @@ class TextEditorElement extends HTMLElement @emitter = new Emitter @subscriptions = new CompositeDisposable + @hiddenInputElement = document.createElement('input') + @hiddenInputElement.classList.add('hidden-input') + @hiddenInputElement.setAttribute('tabindex', -1) + @hiddenInputElement.setAttribute('data-react-skip-selection-restoration', true) + @hiddenInputElement.style['-webkit-transform'] = 'translateZ(0)' + @hiddenInputElement.addEventListener 'paste', (event) -> event.preventDefault() + @addEventListener 'focus', @focused.bind(this) @addEventListener 'blur', @blurred.bind(this) + @hiddenInputElement.addEventListener 'focus', @focused.bind(this) + @hiddenInputElement.addEventListener 'blur', @inputNodeBlurred.bind(this) @classList.add('editor') @setAttribute('tabindex', -1) @@ -117,12 +126,10 @@ class TextEditorElement extends HTMLElement themes: @themes styles: @styles workspace: @workspace - assert: @assert + assert: @assert, + hiddenInputElement: @hiddenInputElement ) @rootElement.appendChild(@component.getDomNode()) - inputNode = @component.hiddenInputComponent.getDomNode() - inputNode.addEventListener 'focus', @focused.bind(this) - inputNode.addEventListener 'blur', @inputNodeBlurred.bind(this) unmountComponent: -> if @component? @@ -132,9 +139,10 @@ class TextEditorElement extends HTMLElement focused: (event) -> @component?.focused() + @hiddenInputElement.focus() blurred: (event) -> - if event.relatedTarget is @component?.hiddenInputComponent.getDomNode() + if event.relatedTarget is @hiddenInputElement event.stopImmediatePropagation() return @component?.blurred()