diff --git a/spec/editor-component-spec.coffee b/spec/editor-component-spec.coffee index 4a4939dfe..b9335c697 100644 --- a/spec/editor-component-spec.coffee +++ b/spec/editor-component-spec.coffee @@ -153,6 +153,31 @@ describe "EditorComponent", -> linesNode = node.querySelector('.lines') expect(linesNode.offsetHeight).toBe 300 + it "assigns the width of each line so it extends across the full width of the editor", -> + gutterWidth = node.querySelector('.gutter').offsetWidth + scrollViewNode = node.querySelector('.scroll-view') + lineNodes = node.querySelectorAll('.line') + + node.style.width = gutterWidth + (30 * charWidth) + 'px' + component.measureScrollView() + runSetImmediateCallbacks() + expect(editor.getScrollWidth()).toBeGreaterThan scrollViewNode.offsetWidth + + # At the time of writing, using width: 100% to achieve the full-width + # lines caused full-screen repaints after switching away from an editor + # and back again Please ensure you don't cause a performance regression if + # you change this behavior. + for lineNode in lineNodes + expect(lineNode.style.width).toBe editor.getScrollWidth() + 'px' + + node.style.width = gutterWidth + editor.getScrollWidth() + 100 + 'px' + component.measureScrollView() + runSetImmediateCallbacks() + scrollViewWidth = scrollViewNode.offsetWidth + + for lineNode in lineNodes + expect(lineNode.style.width).toBe scrollViewWidth + 'px' + describe "when showInvisibles is enabled", -> invisibles = null diff --git a/src/editor-component.coffee b/src/editor-component.coffee index 50ab1e7d0..3c1bae114 100644 --- a/src/editor-component.coffee +++ b/src/editor-component.coffee @@ -68,6 +68,7 @@ EditorComponent = React.createClass lineHeightInPixels = editor.getLineHeightInPixels() defaultCharWidth = editor.getDefaultCharWidth() scrollViewHeight = editor.getHeight() + lineWidth = Math.max(scrollWidth, editor.getWidth()) horizontalScrollbarHeight = editor.getHorizontalScrollbarHeight() verticalScrollbarWidth = editor.getVerticalScrollbarWidth() verticallyScrollable = editor.verticallyScrollable() @@ -106,7 +107,7 @@ EditorComponent = React.createClass editor, lineHeightInPixels, defaultCharWidth, lineDecorations, highlightDecorations, showIndentGuide, renderedRowRange, @pendingChanges, scrollTop, scrollLeft, @scrollingVertically, scrollHeight, scrollWidth, mouseWheelScreenRow, invisibles, - visible, scrollViewHeight, @scopedCharacterWidthsChangeCount + visible, scrollViewHeight, @scopedCharacterWidthsChangeCount, lineWidth } ScrollbarComponent diff --git a/src/lines-component.coffee b/src/lines-component.coffee index 4762246dd..79160fc04 100644 --- a/src/lines-component.coffee +++ b/src/lines-component.coffee @@ -39,7 +39,7 @@ LinesComponent = React.createClass return true unless isEqualForProperties(newProps, @props, 'renderedRowRange', 'lineDecorations', 'highlightDecorations', 'lineHeightInPixels', 'defaultCharWidth', 'scrollTop', 'scrollLeft', 'showIndentGuide', 'scrollingVertically', 'invisibles', 'visible', - 'scrollViewHeight', 'mouseWheelScreenRow', 'scopedCharacterWidthsChangeCount' + 'scrollViewHeight', 'mouseWheelScreenRow', 'scopedCharacterWidthsChangeCount', 'lineWidth' ) {renderedRowRange, pendingChanges} = newProps @@ -54,20 +54,20 @@ LinesComponent = React.createClass @clearScreenRowCaches() unless prevProps.lineHeightInPixels is @props.lineHeightInPixels @removeLineNodes() unless isEqualForProperties(prevProps, @props, 'showIndentGuide', 'invisibles') - @updateLines() + @updateLines(@props.lineWidth isnt prevProps.lineWidth) @measureCharactersInNewLines() if visible and not scrollingVertically clearScreenRowCaches: -> @screenRowsByLineId = {} @lineIdsByScreenRow = {} - updateLines: -> + updateLines: (updateWidth) -> {editor, renderedRowRange, showIndentGuide, selectionChanged, lineDecorations} = @props [startRow, endRow] = renderedRowRange visibleLines = editor.linesForScreenRows(startRow, endRow - 1) @removeLineNodes(visibleLines) - @appendOrUpdateVisibleLineNodes(visibleLines, startRow) + @appendOrUpdateVisibleLineNodes(visibleLines, startRow, updateWidth) removeLineNodes: (visibleLines=[]) -> {mouseWheelScreenRow} = @props @@ -83,7 +83,7 @@ LinesComponent = React.createClass delete @renderedDecorationsByLineId[lineId] node.removeChild(lineNode) - appendOrUpdateVisibleLineNodes: (visibleLines, startRow) -> + appendOrUpdateVisibleLineNodes: (visibleLines, startRow, updateWidth) -> {lineDecorations} = @props newLines = null @@ -93,7 +93,7 @@ LinesComponent = React.createClass screenRow = startRow + index if @hasLineNode(line.id) - @updateLineNode(line, screenRow) + @updateLineNode(line, screenRow, updateWidth) else newLines ?= [] newLinesHTML ?= "" @@ -118,7 +118,7 @@ LinesComponent = React.createClass @lineNodesByLineId.hasOwnProperty(lineId) buildLineHTML: (line, screenRow) -> - {editor, mini, showIndentGuide, lineHeightInPixels, lineDecorations} = @props + {editor, mini, showIndentGuide, lineHeightInPixels, lineDecorations, lineWidth} = @props {tokens, text, lineEnding, fold, isSoftWrapped, indentLevel} = line classes = '' @@ -129,7 +129,7 @@ LinesComponent = React.createClass classes += 'line' top = screenRow * lineHeightInPixels - lineHTML = "
" + lineHTML = "
" if text is "" lineHTML += @buildEmptyLineInnerHTML(line) @@ -203,8 +203,8 @@ LinesComponent = React.createClass scopeStack.push(scope) "" - updateLineNode: (line, screenRow) -> - {editor, lineHeightInPixels, lineDecorations} = @props + updateLineNode: (line, screenRow, updateWidth) -> + {editor, lineHeightInPixels, lineDecorations, lineWidth} = @props lineNode = @lineNodesByLineId[line.id] decorations = lineDecorations[screenRow] @@ -219,6 +219,8 @@ LinesComponent = React.createClass if editor.decorationMatchesType(decoration, 'line') and not _.deepContains(previousDecorations, decoration) lineNode.classList.add(decoration.class) + lineNode.style.width = lineWidth + 'px' if updateWidth + unless @screenRowsByLineId[line.id] is screenRow lineNode.style.top = screenRow * lineHeightInPixels + 'px' lineNode.dataset.screenRow = screenRow