From 683bf3790730862e087c68c63a6d2cf7126b047d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Aug 2016 14:10:11 +0200 Subject: [PATCH 1/9] Add `autoWidth` to TextEditor --- spec/text-editor-spec.coffee | 8 ++++++++ src/text-editor-presenter.coffee | 3 +++ src/text-editor.coffee | 10 +++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 605b6cf05..e352a6c88 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -5516,6 +5516,14 @@ describe "TextEditor", -> editor.update({autoHeight: true}) expect(editor.getAutoHeight()).toBe(true) + describe "auto width", -> + it "returns false by default but can be customized", -> + expect(editor.getAutoWidth()).toBe(false) + editor.update({autoWidth: true}) + expect(editor.getAutoWidth()).toBe(true) + editor.update({autoWidth: false}) + expect(editor.getAutoWidth()).toBe(false) + describe '.get/setPlaceholderText()', -> it 'can be created with placeholderText', -> newEditor = atom.workspace.buildTextEditor( diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index cb2d70a67..4f5ca74ef 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -896,6 +896,9 @@ class TextEditorPresenter @updateScrollHeight() @updateEndRow() + didChangeAutoWidth: -> + @emitDidUpdateState() + setContentFrameWidth: (contentFrameWidth) -> if @contentFrameWidth isnt contentFrameWidth or @editorWidthInChars? oldContentFrameWidth = @contentFrameWidth diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 354ac8069..420bee702 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -127,7 +127,7 @@ class TextEditor extends Model @softTabs, @firstVisibleScreenRow, @firstVisibleScreenColumn, initialLine, initialColumn, tabLength, @softWrapped, @decorationManager, @selectionsMarkerLayer, @buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, @largeFileMode, @clipboard, - @assert, grammar, @showInvisibles, @autoHeight, @scrollPastEnd, @editorWidthInChars, + @assert, grammar, @showInvisibles, @autoHeight, @autoWidth, @scrollPastEnd, @editorWidthInChars, @tokenizedBuffer, @displayLayer, @invisibles, @showIndentGuide, @softWrapHangingIndentLength, @softWrapped, @softWrapAtPreferredLineLength, @preferredLineLength } = params @@ -144,6 +144,7 @@ class TextEditor extends Model @selections = [] @hasTerminatedPendingState = false + @autoWidth ?= false @autoHeight ?= true @mini ?= false @scrollPastEnd ?= true @@ -320,6 +321,10 @@ class TextEditor extends Model @autoHeight = value @editorElement?.didChangeAutoHeight() + when 'autoWidth' + if value isnt @autoWidth + @autoWidth = value + @presenter?.didChangeAutoWidth() else throw new TypeError("Invalid TextEditor parameter: '#{param}'") @@ -3552,6 +3557,9 @@ class TextEditor extends Model Grim.deprecate("This is now a view method. Call TextEditorElement::getWidth instead.") @width + getAutoWidth: -> + @autoWidth + # Experimental: Scroll the editor such that the given screen row is at the # top of the visible area. setFirstVisibleScreenRow: (screenRow, fromView) -> From 2e37d7f0cf2a1d6842dae3e3b15fa702b8d862bb Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Aug 2016 16:14:57 +0200 Subject: [PATCH 2/9] Change state.content.width based on autoWidth --- spec/text-editor-presenter-spec.coffee | 33 ++++++++++++++++++++++++++ src/text-editor-presenter.coffee | 9 ++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index e04eadaa2..13e6d218e 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -2664,6 +2664,39 @@ describe "TextEditorPresenter", -> pixelPosition: {top: 10, left: 0} } + describe ".width", -> + describe "when `editor.autoWidth` is false (the default)", -> + it "equals to the max width between the content frame width and the content width + the vertical scrollbar width", -> + editor.setText('abc\ndef\nghi\njkl') + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 33, verticalScrollbarWidth: 7, baseCharacterWidth: 10) + expect(getState(presenter).content.width).toBe(3 * 10 + 7 + 1) + presenter.setContentFrameWidth(50) + expect(getState(presenter).content.width).toBe(50) + presenter.setVerticalScrollbarWidth(27) + expect(getState(presenter).content.width).toBe(3 * 10 + 27 + 1) + + describe "when `editor.autoWidth` is true", -> + it "equals to the width of the content + the vertical scrollbar width", -> + editor.setText('abc\ndef\nghi\njkl') + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 300, verticalScrollbarWidth: 7, baseCharacterWidth: 10) + expectStateUpdate presenter, -> editor.update({autoWidth: true}) + expect(getState(presenter).content.width).toBe(3 * 10 + 7 + 1) + editor.setText('abcdefghi\n') + expect(getState(presenter).content.width).toBe(9 * 10 + 7 + 1) + + it "ignores the vertical scrollbar width when it is unset", -> + editor.setText('abcdef\nghijkl') + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 33, verticalScrollbarWidth: 7, baseCharacterWidth: 10) + presenter.setVerticalScrollbarWidth(null) + expect(getState(presenter).content.width).toBe(6 * 10 + 1) + + it "ignores the content frame width when it is unset", -> + editor.setText('abc\ndef\nghi\njkl') + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 33, verticalScrollbarWidth: 7, baseCharacterWidth: 10) + getState(presenter) # trigger a state update, causing verticalScrollbarWidth to be stored in the presenter + presenter.setContentFrameWidth(null) + expect(getState(presenter).content.width).toBe(3 * 10 + 7 + 1) + describe ".height", -> it "updates model's rows per page when it changes", -> presenter = buildPresenter(explicitHeight: 50, lineHeightInPixels: 10, horizontalScrollbarHeight: 10) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 4f5ca74ef..51fb44345 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -269,7 +269,14 @@ class TextEditorPresenter @sharedGutterStyles.maxHeight = @boundingClientRect.height @state.content.maxHeight = @boundingClientRect.height - @state.content.width = Math.max(@contentWidth + @verticalScrollbarWidth, @contentFrameWidth) + verticalScrollbarWidth = @verticalScrollbarWidth ? 0 + contentFrameWidth = @contentFrameWidth ? 0 + contentWidth = @contentWidth ? 0 + if @model.getAutoWidth() + @state.content.width = contentWidth + verticalScrollbarWidth + else + @state.content.width = Math.max(contentWidth + verticalScrollbarWidth, contentFrameWidth) + @state.content.autoWidth = @model.getAutoWidth() @state.content.scrollWidth = @scrollWidth @state.content.scrollLeft = @scrollLeft @state.content.backgroundColor = if @model.isMini() then null else @backgroundColor From e8f2e3a608b899beef536af933ecfe05dbb8c1e4 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Aug 2016 16:16:16 +0200 Subject: [PATCH 3/9] Size TextEditorElement according to the autoWidth property --- spec/text-editor-component-spec.js | 28 ++++++++++++++++++++++++++ spec/text-editor-presenter-spec.coffee | 2 +- src/text-editor-component.coffee | 11 +++++++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index e23ede439..61998ee2d 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4368,6 +4368,34 @@ describe('TextEditorComponent', function () { }) }) + describe('width', function () { + it('sizes the editor element according to the content width when auto width is true, or according to the container width otherwise', function () { + contentNode.style.width = '600px' + component.measureDimensions() + editor.setText("abcdefghi") + runAnimationFrames() + expect(wrapperNode.offsetWidth).toBe(contentNode.offsetWidth) + + global.debug = true + editor.update({autoWidth: true}) + runAnimationFrames() + const editorWidth1 = wrapperNode.offsetWidth + expect(editorWidth1).toBeGreaterThan(0) + expect(editorWidth1).toBeLessThan(contentNode.offsetWidth) + + editor.setText("abcdefghijkl") + editor.update({autoWidth: true}) + runAnimationFrames() + const editorWidth2 = wrapperNode.offsetWidth + expect(editorWidth2).toBeGreaterThan(editorWidth1) + expect(editorWidth2).toBeLessThan(contentNode.offsetWidth) + + editor.update({autoWidth: false}) + runAnimationFrames() + expect(wrapperNode.offsetWidth).toBe(contentNode.offsetWidth) + }) + }) + describe('when the "mini" property is true', function () { beforeEach(function () { editor.setMini(true) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 13e6d218e..efa1c3393 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -2676,7 +2676,7 @@ describe "TextEditorPresenter", -> expect(getState(presenter).content.width).toBe(3 * 10 + 27 + 1) describe "when `editor.autoWidth` is true", -> - it "equals to the width of the content + the vertical scrollbar width", -> + it "equals to the content width + the vertical scrollbar width", -> editor.setText('abc\ndef\nghi\njkl') presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 300, verticalScrollbarWidth: 7, baseCharacterWidth: 10) expectStateUpdate presenter, -> editor.update({autoWidth: true}) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 262b62301..265f884fe 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -129,7 +129,7 @@ class TextEditorComponent updateSync: -> @updateSyncPreMeasurement() - @oldState ?= {} + @oldState ?= {content: {}} @newState = @presenter.getPostMeasurementState() if @editor.getLastSelection()? and not @editor.getLastSelection().isEmpty() @@ -149,6 +149,15 @@ class TextEditorComponent else @domNode.style.height = '' + if (@newState.content.autoWidth isnt @oldState.content.autoWidth) or (@newState.content.width isnt @oldState.content.width) + if @newState.content.autoWidth + @hostElement.style.width = @newState.content.width + 'px' + else + @hostElement.style.width = '' + + @oldState.content.width = @newState.content.width + @oldState.content.autoWidth = @newState.content.autoWidth + if @newState.gutters.length @mountGutterContainerComponent() unless @gutterContainerComponent? @gutterContainerComponent.updateSync(@newState) From 5b44b5115099d40e93cc181d2d78905af54ad7c5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Aug 2016 17:20:24 +0200 Subject: [PATCH 4/9] :art: Clarify naming --- src/text-editor-presenter.coffee | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 51fb44345..e60b1fc33 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -727,20 +727,20 @@ class TextEditorPresenter return unless @measuredVerticalScrollbarWidth? and @measuredHorizontalScrollbarHeight? return unless @contentWidth? and @contentHeight? - clientWidthWithoutVerticalScrollbar = @contentFrameWidth - clientWidthWithVerticalScrollbar = clientWidthWithoutVerticalScrollbar - @measuredVerticalScrollbarWidth - clientHeightWithoutHorizontalScrollbar = @height - clientHeightWithHorizontalScrollbar = clientHeightWithoutHorizontalScrollbar - @measuredHorizontalScrollbarHeight + clientWidthWithVerticalScrollbar = @contentFrameWidth + clientWidthWithoutVerticalScrollbar = clientWidthWithVerticalScrollbar - @measuredVerticalScrollbarWidth + clientHeightWithHorizontalScrollbar = @height + clientHeightWithoutHorizontalScrollbar = clientHeightWithHorizontalScrollbar - @measuredHorizontalScrollbarHeight horizontalScrollbarVisible = not @model.isMini() and - (@contentWidth > clientWidthWithoutVerticalScrollbar or - @contentWidth > clientWidthWithVerticalScrollbar and @contentHeight > clientHeightWithoutHorizontalScrollbar) + (@contentWidth > clientWidthWithVerticalScrollbar or + @contentWidth > clientWidthWithoutVerticalScrollbar and @contentHeight > clientHeightWithHorizontalScrollbar) verticalScrollbarVisible = not @model.isMini() and - (@contentHeight > clientHeightWithoutHorizontalScrollbar or - @contentHeight > clientHeightWithHorizontalScrollbar and @contentWidth > clientWidthWithoutVerticalScrollbar) + (@contentHeight > clientHeightWithHorizontalScrollbar or + @contentHeight > clientHeightWithoutHorizontalScrollbar and @contentWidth > clientWidthWithVerticalScrollbar) horizontalScrollbarHeight = if horizontalScrollbarVisible From e71027ed36ceb37cf5dc59438c31b502c50c4ae8 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Aug 2016 17:58:36 +0200 Subject: [PATCH 5/9] Ensure editors don't scroll or show scrollbars when autoWidth is enabled --- spec/text-editor-presenter-spec.coffee | 88 ++++++++++++++++---------- src/text-editor-presenter.coffee | 18 ++++-- 2 files changed, 67 insertions(+), 39 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index efa1c3393..784e18e1b 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -425,6 +425,13 @@ describe "TextEditorPresenter", -> editor.setMini(false) expect(getState(presenter).horizontalScrollbar.visible).toBe true + it "is false when `editor.autoWidth` is true", -> + editor.update({autoWidth: true}) + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 30, verticalScrollbarWidth: 7, baseCharacterWidth: 10) + getState(presenter) # trigger a state update to store state in the presenter + editor.setText('abcdefghijklm') + expect(getState(presenter).horizontalScrollbar.visible).toBe(false) + describe ".height", -> it "tracks the value of ::horizontalScrollbarHeight", -> presenter = buildPresenter(horizontalScrollbarHeight: 10) @@ -538,6 +545,21 @@ describe "TextEditorPresenter", -> presenter.setScrollLeft(10) expect(getState(presenter).content.scrollLeft).toBe 0 + it "is always 0 when `editor.autoWidth` is true", -> + editor.update({autoWidth: true}) + editor.setText('abcdefghijklm') + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 30, verticalScrollbarWidth: 15, baseCharacterWidth: 10) + getState(presenter) # trigger a state update to store state in the presenter + + editor.setCursorBufferPosition([0, Infinity]) + editor.insertText('n') + expect(getState(presenter).content.scrollLeft).toBe(0) + + editor.setText('abcdefghijklm\nnopqrstuvwxy') # make the vertical scrollbar appear + editor.setCursorBufferPosition([1, Infinity]) + editor.insertText('z') + expect(getState(presenter).content.scrollLeft).toBe(0) + describe ".verticalScrollbar", -> describe ".visible", -> it "is true if the scrollHeight exceeds the computed client height", -> @@ -755,6 +777,39 @@ describe "TextEditorPresenter", -> expect(getState(presenter).hiddenInput.width).toBe 2 describe ".content", -> + describe '.width', -> + describe "when `editor.autoWidth` is false (the default)", -> + it "equals to the max width between the content frame width and the content width + the vertical scrollbar width", -> + editor.setText('abc\ndef\nghi\njkl') + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 33, verticalScrollbarWidth: 7, baseCharacterWidth: 10) + expect(getState(presenter).content.width).toBe(3 * 10 + 7 + 1) + presenter.setContentFrameWidth(50) + expect(getState(presenter).content.width).toBe(50) + presenter.setVerticalScrollbarWidth(27) + expect(getState(presenter).content.width).toBe(3 * 10 + 27 + 1) + + describe "when `editor.autoWidth` is true", -> + it "equals to the content width + the vertical scrollbar width", -> + editor.setText('abc\ndef\nghi\njkl') + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 300, verticalScrollbarWidth: 7, baseCharacterWidth: 10) + expectStateUpdate presenter, -> editor.update({autoWidth: true}) + expect(getState(presenter).content.width).toBe(3 * 10 + 7 + 1) + editor.setText('abcdefghi\n') + expect(getState(presenter).content.width).toBe(9 * 10 + 7 + 1) + + it "ignores the vertical scrollbar width when it is unset", -> + editor.setText('abcdef\nghijkl') + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 33, verticalScrollbarWidth: 7, baseCharacterWidth: 10) + presenter.setVerticalScrollbarWidth(null) + expect(getState(presenter).content.width).toBe(6 * 10 + 1) + + it "ignores the content frame width when it is unset", -> + editor.setText('abc\ndef\nghi\njkl') + presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 33, verticalScrollbarWidth: 7, baseCharacterWidth: 10) + getState(presenter) # trigger a state update, causing verticalScrollbarWidth to be stored in the presenter + presenter.setContentFrameWidth(null) + expect(getState(presenter).content.width).toBe(3 * 10 + 7 + 1) + describe ".maxHeight", -> it "changes based on boundingClientRect", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10) @@ -2664,39 +2719,6 @@ describe "TextEditorPresenter", -> pixelPosition: {top: 10, left: 0} } - describe ".width", -> - describe "when `editor.autoWidth` is false (the default)", -> - it "equals to the max width between the content frame width and the content width + the vertical scrollbar width", -> - editor.setText('abc\ndef\nghi\njkl') - presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 33, verticalScrollbarWidth: 7, baseCharacterWidth: 10) - expect(getState(presenter).content.width).toBe(3 * 10 + 7 + 1) - presenter.setContentFrameWidth(50) - expect(getState(presenter).content.width).toBe(50) - presenter.setVerticalScrollbarWidth(27) - expect(getState(presenter).content.width).toBe(3 * 10 + 27 + 1) - - describe "when `editor.autoWidth` is true", -> - it "equals to the content width + the vertical scrollbar width", -> - editor.setText('abc\ndef\nghi\njkl') - presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 300, verticalScrollbarWidth: 7, baseCharacterWidth: 10) - expectStateUpdate presenter, -> editor.update({autoWidth: true}) - expect(getState(presenter).content.width).toBe(3 * 10 + 7 + 1) - editor.setText('abcdefghi\n') - expect(getState(presenter).content.width).toBe(9 * 10 + 7 + 1) - - it "ignores the vertical scrollbar width when it is unset", -> - editor.setText('abcdef\nghijkl') - presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 33, verticalScrollbarWidth: 7, baseCharacterWidth: 10) - presenter.setVerticalScrollbarWidth(null) - expect(getState(presenter).content.width).toBe(6 * 10 + 1) - - it "ignores the content frame width when it is unset", -> - editor.setText('abc\ndef\nghi\njkl') - presenter = buildPresenter(explicitHeight: 10, contentFrameWidth: 33, verticalScrollbarWidth: 7, baseCharacterWidth: 10) - getState(presenter) # trigger a state update, causing verticalScrollbarWidth to be stored in the presenter - presenter.setContentFrameWidth(null) - expect(getState(presenter).content.width).toBe(3 * 10 + 7 + 1) - describe ".height", -> it "updates model's rows per page when it changes", -> presenter = buildPresenter(explicitHeight: 50, lineHeightInPixels: 10, horizontalScrollbarHeight: 10) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index e60b1fc33..c65a735d8 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -669,6 +669,7 @@ class TextEditorPresenter if @contentWidth isnt oldContentWidth @updateScrollbarDimensions() + @updateClientWidth() @updateScrollWidth() updateClientHeight: -> @@ -685,7 +686,11 @@ class TextEditorPresenter updateClientWidth: -> return unless @contentFrameWidth? and @verticalScrollbarWidth? - clientWidth = @contentFrameWidth - @verticalScrollbarWidth + if @model.getAutoWidth() + clientWidth = @contentWidth + else + clientWidth = @contentFrameWidth - @verticalScrollbarWidth + @model.setWidth(clientWidth, true) unless @editorWidthInChars unless @clientWidth is clientWidth @@ -727,29 +732,30 @@ class TextEditorPresenter return unless @measuredVerticalScrollbarWidth? and @measuredHorizontalScrollbarHeight? return unless @contentWidth? and @contentHeight? - clientWidthWithVerticalScrollbar = @contentFrameWidth + if @model.getAutoWidth() + clientWidthWithVerticalScrollbar = @contentWidth + @measuredVerticalScrollbarWidth + else + clientWidthWithVerticalScrollbar = @contentFrameWidth clientWidthWithoutVerticalScrollbar = clientWidthWithVerticalScrollbar - @measuredVerticalScrollbarWidth clientHeightWithHorizontalScrollbar = @height clientHeightWithoutHorizontalScrollbar = clientHeightWithHorizontalScrollbar - @measuredHorizontalScrollbarHeight horizontalScrollbarVisible = - not @model.isMini() and (@contentWidth > clientWidthWithVerticalScrollbar or @contentWidth > clientWidthWithoutVerticalScrollbar and @contentHeight > clientHeightWithHorizontalScrollbar) verticalScrollbarVisible = - not @model.isMini() and (@contentHeight > clientHeightWithHorizontalScrollbar or @contentHeight > clientHeightWithoutHorizontalScrollbar and @contentWidth > clientWidthWithVerticalScrollbar) horizontalScrollbarHeight = - if horizontalScrollbarVisible + if horizontalScrollbarVisible and not @model.isMini() @measuredHorizontalScrollbarHeight else 0 verticalScrollbarWidth = - if verticalScrollbarVisible + if verticalScrollbarVisible and not @model.isMini() @measuredVerticalScrollbarWidth else 0 From 6f0fd965cdf29f28166a93355e20f27469b6025c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Aug 2016 18:05:16 +0200 Subject: [PATCH 6/9] Clear out width on TextEditorElement only if autoWidth was previously on --- src/text-editor-component.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 265f884fe..a927651af 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -152,7 +152,7 @@ class TextEditorComponent if (@newState.content.autoWidth isnt @oldState.content.autoWidth) or (@newState.content.width isnt @oldState.content.width) if @newState.content.autoWidth @hostElement.style.width = @newState.content.width + 'px' - else + else if @oldState.content.autoWidth @hostElement.style.width = '' @oldState.content.width = @newState.content.width From 36422923023b2b9e5c40a9959394461b9727915d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Aug 2016 18:05:51 +0200 Subject: [PATCH 7/9] :fire: debugger --- spec/text-editor-component-spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 61998ee2d..5acc2cefc 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4376,7 +4376,6 @@ describe('TextEditorComponent', function () { runAnimationFrames() expect(wrapperNode.offsetWidth).toBe(contentNode.offsetWidth) - global.debug = true editor.update({autoWidth: true}) runAnimationFrames() const editorWidth1 = wrapperNode.offsetWidth From c37138e09e99553a3dcac0efb67a4b24dfdea0d1 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Aug 2016 18:07:52 +0200 Subject: [PATCH 8/9] Revert refactoring to make the diff shorter --- src/text-editor-presenter.coffee | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index c65a735d8..8c1d6ccbd 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -741,21 +741,23 @@ class TextEditorPresenter clientHeightWithoutHorizontalScrollbar = clientHeightWithHorizontalScrollbar - @measuredHorizontalScrollbarHeight horizontalScrollbarVisible = + not @model.isMini() and (@contentWidth > clientWidthWithVerticalScrollbar or @contentWidth > clientWidthWithoutVerticalScrollbar and @contentHeight > clientHeightWithHorizontalScrollbar) verticalScrollbarVisible = + not @model.isMini() and (@contentHeight > clientHeightWithHorizontalScrollbar or @contentHeight > clientHeightWithoutHorizontalScrollbar and @contentWidth > clientWidthWithVerticalScrollbar) horizontalScrollbarHeight = - if horizontalScrollbarVisible and not @model.isMini() + if horizontalScrollbarVisible @measuredHorizontalScrollbarHeight else 0 verticalScrollbarWidth = - if verticalScrollbarVisible and not @model.isMini() + if verticalScrollbarVisible @measuredVerticalScrollbarWidth else 0 From 1587dcbe8963a3a44958ac7db2876b6471c7d22c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Aug 2016 18:33:04 +0200 Subject: [PATCH 9/9] Take the gutter width into account when sizing TextEditorElement --- spec/text-editor-presenter-spec.coffee | 11 +++++++++++ src/text-editor-component.coffee | 14 ++++++-------- src/text-editor-presenter.coffee | 12 +++++++++--- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 784e18e1b..728768799 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -2719,6 +2719,17 @@ describe "TextEditorPresenter", -> pixelPosition: {top: 10, left: 0} } + describe ".width", -> + it "is null when `editor.autoWidth` is false (the default)", -> + presenter = buildPresenter(explicitHeight: 50, gutterWidth: 20, contentFrameWidth: 300, baseCharacterWidth: 10) + expect(getState(presenter).width).toBeNull() + + it "equals to sum of .content.width and the width of the gutter when `editor.autoWidth` is true", -> + editor.setText('abcdef') + editor.update({autoWidth: true}) + presenter = buildPresenter(explicitHeight: 50, gutterWidth: 20, contentFrameWidth: 300, baseCharacterWidth: 10) + expect(getState(presenter).width).toBe(20 + 6 * 10 + 1) + describe ".height", -> it "updates model's rows per page when it changes", -> presenter = buildPresenter(explicitHeight: 50, lineHeightInPixels: 10, horizontalScrollbarHeight: 10) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index a927651af..d40f69e38 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -129,7 +129,7 @@ class TextEditorComponent updateSync: -> @updateSyncPreMeasurement() - @oldState ?= {content: {}} + @oldState ?= {width: null} @newState = @presenter.getPostMeasurementState() if @editor.getLastSelection()? and not @editor.getLastSelection().isEmpty() @@ -149,14 +149,12 @@ class TextEditorComponent else @domNode.style.height = '' - if (@newState.content.autoWidth isnt @oldState.content.autoWidth) or (@newState.content.width isnt @oldState.content.width) - if @newState.content.autoWidth - @hostElement.style.width = @newState.content.width + 'px' - else if @oldState.content.autoWidth + if @newState.width isnt @oldState.width + if @newState.width? + @hostElement.style.width = @newState.width + 'px' + else @hostElement.style.width = '' - - @oldState.content.width = @newState.content.width - @oldState.content.autoWidth = @newState.content.autoWidth + @oldState.width = @newState.width if @newState.gutters.length @mountGutterContainerComponent() unless @gutterContainerComponent? diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 8c1d6ccbd..49df8ab80 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -110,13 +110,14 @@ class TextEditorPresenter @updateLines() - @updateFocusedState() - @updateHeightState() @updateVerticalScrollState() @updateHorizontalScrollState() @updateScrollbarsState() @updateHiddenInputState() @updateContentState() + @updateFocusedState() + @updateHeightState() + @updateWidthState() @updateHighlightDecorations() if @shouldUpdateDecorations @updateTilesState() @updateCursorsState() @@ -224,6 +225,12 @@ class TextEditorPresenter else @state.height = null + updateWidthState: -> + if @model.getAutoWidth() + @state.width = @state.content.width + @gutterWidth + else + @state.width = null + updateVerticalScrollState: -> @state.content.scrollHeight = @scrollHeight @sharedGutterStyles.scrollHeight = @scrollHeight @@ -276,7 +283,6 @@ class TextEditorPresenter @state.content.width = contentWidth + verticalScrollbarWidth else @state.content.width = Math.max(contentWidth + verticalScrollbarWidth, contentFrameWidth) - @state.content.autoWidth = @model.getAutoWidth() @state.content.scrollWidth = @scrollWidth @state.content.scrollLeft = @scrollLeft @state.content.backgroundColor = if @model.isMini() then null else @backgroundColor