From efd20774de62fba5a7adc14582b881d82bd0cff3 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 8 Dec 2016 16:05:45 -0800 Subject: [PATCH 1/2] Make each atom-text-editor keep a consistent hidden input node for its lifetime Signed-off-by: Damien Guard --- spec/text-editor-element-spec.coffee | 13 +++++++++++++ src/input-component.coffee | 8 +------- src/text-editor-component.coffee | 8 ++++---- src/text-editor-element.coffee | 17 ++++++++++++----- 4 files changed, 30 insertions(+), 16 deletions(-) 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..2883488ce 100644 --- a/src/input-component.coffee +++ b/src/input-component.coffee @@ -1,12 +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() + constructor: (@domNode) -> getDomNode: -> @domNode diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 8bf72d62d..db0eaddb8 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()) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 8f2538ede..ee17867df 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? @@ -134,7 +141,7 @@ class TextEditorElement extends HTMLElement @component?.focused() blurred: (event) -> - if event.relatedTarget is @component?.hiddenInputComponent.getDomNode() + if event.relatedTarget is @hiddenInputElement event.stopImmediatePropagation() return @component?.blurred() From 6f4a506517a4865686ac17b240476a67003f7cfe Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 8 Dec 2016 16:12:26 -0800 Subject: [PATCH 2/2] Remove InputComponent.getDomNode method Access the dom node directly in TextEditorElement instead Signed-off-by: Damien Guard --- src/input-component.coffee | 3 --- src/text-editor-component.coffee | 1 - src/text-editor-element.coffee | 1 + 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/input-component.coffee b/src/input-component.coffee index 2883488ce..27543a2fd 100644 --- a/src/input-component.coffee +++ b/src/input-component.coffee @@ -2,9 +2,6 @@ module.exports = class InputComponent constructor: (@domNode) -> - getDomNode: -> - @domNode - updateSync: (state) -> @oldState ?= {} newState = state.hiddenInput diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index db0eaddb8..e8591819f 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -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 ee17867df..8c9792916 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -139,6 +139,7 @@ class TextEditorElement extends HTMLElement focused: (event) -> @component?.focused() + @hiddenInputElement.focus() blurred: (event) -> if event.relatedTarget is @hiddenInputElement