diff --git a/spec/editor-component-spec.coffee b/spec/editor-component-spec.coffee index d47abdb00..6382a1474 100644 --- a/spec/editor-component-spec.coffee +++ b/spec/editor-component-spec.coffee @@ -462,12 +462,6 @@ describe "EditorComponent", -> expect(component.lineNumberNodeForScreenRow(9).textContent).toBe "10" expect(gutterNode.offsetWidth).toBe initialGutterWidth - it "renders the .line-numbers div at the full height of the editor even if it's taller than its content", -> - node.style.height = node.offsetHeight + 100 + 'px' - component.measureScrollView() - nextTick() - expect(node.querySelector('.line-numbers').offsetHeight).toBe node.offsetHeight - describe "fold decorations", -> describe "rendering fold decorations", -> it "adds the foldable class to line numbers when the line is foldable", -> diff --git a/src/editor-component.coffee b/src/editor-component.coffee index 7f475fb1b..e8b399da5 100644 --- a/src/editor-component.coffee +++ b/src/editor-component.coffee @@ -8,6 +8,8 @@ GutterComponent = require './gutter-component' InputComponent = require './input-component' CursorsComponent = require './cursors-component' LinesComponent = require './lines-component' +HighlightsComponent = require './highlights-component' +UnderlayerComponent = require './underlayer-component' ScrollbarComponent = require './scrollbar-component' ScrollbarCornerComponent = require './scrollbar-corner-component' SubscriberMixin = require './subscriber-mixin' @@ -82,8 +84,8 @@ EditorComponent = React.createClass div className: className, style: {fontSize, lineHeight, fontFamily}, tabIndex: -1, GutterComponent { ref: 'gutter', onMouseDown: @onGutterMouseDown, onWidthChanged: @onGutterWidthChanged, - lineDecorations, defaultCharWidth, editor, renderedRowRange, maxLineNumberDigits, scrollViewHeight, - scrollTop, scrollHeight, lineHeightInPixels, @pendingChanges, mouseWheelScreenRow + lineDecorations, defaultCharWidth, editor, renderedRowRange, maxLineNumberDigits, + scrollTop, lineHeightInPixels, @pendingChanges, mouseWheelScreenRow } div ref: 'scrollView', className: 'scroll-view', onMouseDown: @onMouseDown, @@ -103,7 +105,14 @@ EditorComponent = React.createClass editor, lineHeightInPixels, defaultCharWidth, lineDecorations, highlightDecorations, showIndentGuide, renderedRowRange, @pendingChanges, scrollTop, scrollLeft, @scrollingVertically, scrollHeight, scrollWidth, mouseWheelScreenRow, invisibles, - visible, scrollViewHeight, @scopedCharacterWidthsChangeCount + visible, scrollViewHeight + } + HighlightsComponent { + editor, scrollTop, scrollLeft, scrollHeight, scrollWidth, highlightDecorations, lineHeightInPixels, + defaultCharWidth, @scopedCharacterWidthsChangeCount + } + UnderlayerComponent { + scrollTop, scrollLeft, scrollHeight, scrollWidth } ScrollbarComponent diff --git a/src/editor.coffee b/src/editor.coffee index f5ad5666d..a7466209b 100644 --- a/src/editor.coffee +++ b/src/editor.coffee @@ -443,7 +443,8 @@ class Editor extends Model getText: -> @buffer.getText() # Public: Replaces the entire contents of the buffer with the given {String}. - setText: (text) -> @buffer.setText(text) + setText: (text) -> + @buffer.setText(text) # Get the text in the given {Range}. # diff --git a/src/gutter-component.coffee b/src/gutter-component.coffee index 2555c7ebd..a7e82180d 100644 --- a/src/gutter-component.coffee +++ b/src/gutter-component.coffee @@ -15,13 +15,10 @@ GutterComponent = React.createClass measuredWidth: null render: -> - {scrollHeight, scrollViewHeight, scrollTop, onMouseDown} = @props + {scrollTop, onMouseDown} = @props div className: 'gutter', onClick: @onClick, onMouseDown: onMouseDown, - # The line-numbers div must have the 'editor-colors' class so it has an - # opaque background to avoid sub-pixel anti-aliasing problems on the GPU - div className: 'gutter line-numbers editor-colors', ref: 'lineNumbers', style: - height: Math.max(scrollHeight, scrollViewHeight) + div className: 'line-numbers', ref: 'lineNumbers', style: WebkitTransform: "translate3d(0px, #{-scrollTop}px, 0px)" componentWillMount: -> @@ -38,8 +35,7 @@ GutterComponent = React.createClass # visible row range. shouldComponentUpdate: (newProps) -> return true unless isEqualForProperties(newProps, @props, - 'renderedRowRange', 'scrollTop', 'lineHeightInPixels', 'mouseWheelScreenRow', 'lineDecorations', - 'scrollViewHeight' + 'renderedRowRange', 'scrollTop', 'lineHeightInPixels', 'mouseWheelScreenRow', 'lineDecorations' ) {renderedRowRange, pendingChanges, lineDecorations} = newProps diff --git a/src/highlights-component.coffee b/src/highlights-component.coffee index 292e94892..6a7200e24 100644 --- a/src/highlights-component.coffee +++ b/src/highlights-component.coffee @@ -8,7 +8,16 @@ HighlightsComponent = React.createClass displayName: 'HighlightsComponent' render: -> - div className: 'highlights', @renderHighlights() + if @isMounted() + {scrollTop, scrollLeft, scrollHeight, scrollWidth} = @props + style = + height: scrollHeight + width: scrollWidth + WebkitTransform: "translate3d(#{-scrollLeft}px, #{-scrollTop}px, 0px)" + + div {className: 'highlights', style}, + @renderHighlights() if @isMounted() + renderHighlights: -> {editor, highlightDecorations, lineHeightInPixels} = @props @@ -21,4 +30,7 @@ HighlightsComponent = React.createClass highlightComponents shouldComponentUpdate: (newProps) -> - not isEqualForProperties(newProps, @props, 'highlightDecorations', 'lineHeightInPixels', 'defaultCharWidth', 'scopedCharacterWidthsChangeCount') + not isEqualForProperties(newProps, @props, + 'scrollTop', 'scrollLeft', 'highlightDecorations', 'lineHeightInPixels', + 'defaultCharWidth', 'scopedCharacterWidthsChangeCount' + ) diff --git a/src/lines-component.coffee b/src/lines-component.coffee index afbeb1b57..92b9b7f89 100644 --- a/src/lines-component.coffee +++ b/src/lines-component.coffee @@ -4,8 +4,6 @@ React = require 'react-atom-fork' {debounce, isEqual, isEqualForProperties, multiplyString, toArray} = require 'underscore-plus' {$$} = require 'space-pen' -HighlightsComponent = require './highlights-component' - DummyLineNode = $$(-> @div className: 'line', style: 'position: absolute; visibility: hidden;', => @span 'x')[0] AcceptFilter = {acceptNode: -> NodeFilter.FILTER_ACCEPT} WrapperDiv = document.createElement('div') @@ -17,16 +15,13 @@ LinesComponent = React.createClass render: -> if @isMounted() {editor, highlightDecorations, scrollTop, scrollLeft, scrollHeight, scrollWidth} = @props - {lineHeightInPixels, defaultCharWidth, scrollViewHeight, scopedCharacterWidthsChangeCount} = @props + {lineHeightInPixels, defaultCharWidth, scrollViewHeight} = @props style = height: Math.max(scrollHeight, scrollViewHeight) width: scrollWidth WebkitTransform: "translate3d(#{-scrollLeft}px, #{-scrollTop}px, 0px)" - # The lines div must have the 'editor-colors' class so it has an opaque - # background to avoid sub-pixel anti-aliasing problems on the GPU - div {className: 'lines editor-colors', style}, - HighlightsComponent({editor, highlightDecorations, lineHeightInPixels, defaultCharWidth, scopedCharacterWidthsChangeCount}) if @isMounted() + div {className: 'lines', style} componentWillMount: -> @measuredLines = new WeakSet @@ -39,7 +34,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' ) {renderedRowRange, pendingChanges} = newProps diff --git a/src/react-editor-view.coffee b/src/react-editor-view.coffee index a363026e2..8c0b961d0 100644 --- a/src/react-editor-view.coffee +++ b/src/react-editor-view.coffee @@ -34,7 +34,7 @@ class ReactEditorView extends View node = @component.getDOMNode() @scrollView = $(node).find('.scroll-view') - @underlayer = $(node).find('.highlights').addClass('underlayer') + @underlayer = $(node).find('.underlayer') @overlayer = $(node).find('.lines').addClass('overlayer') @hiddenInput = $(node).find('.hidden-input') diff --git a/src/underlayer-component.coffee b/src/underlayer-component.coffee new file mode 100644 index 000000000..cf106587a --- /dev/null +++ b/src/underlayer-component.coffee @@ -0,0 +1,20 @@ +React = require 'react-atom-fork' +{div} = require 'reactionary-atom-fork' +{isEqualForProperties} = require 'underscore-plus' + +module.exports = +UnderlayerComponent = React.createClass + displayName: 'UnderlayerComponent' + + render: -> + if @isMounted() + {scrollTop, scrollLeft, scrollHeight, scrollWidth} = @props + style = + height: scrollHeight + width: scrollWidth + WebkitTransform: "translate3d(#{-scrollLeft}px, #{-scrollTop}px, 0px)" + + div {className: 'underlayer', style} + + shouldComponentUpdate: (newProps) -> + not isEqualForProperties(@props, newProps, 'scrollTop', 'scrollLeft', 'scrollHeight', 'scrollWidth') diff --git a/static/editor.less b/static/editor.less index 990097d06..e4639327d 100644 --- a/static/editor.less +++ b/static/editor.less @@ -6,13 +6,14 @@ .underlayer { position: absolute; top: 0; - bottom: 0; left: 0; - right: 0; + } + + .highlights { z-index: -2; } - .lines { + .lines, .highlights, .underlayer { min-width: 100%; }