diff --git a/spec/mock-lines-component.coffee b/spec/mock-lines-component.coffee index fd8d04cbc..64c37ad4f 100644 --- a/spec/mock-lines-component.coffee +++ b/spec/mock-lines-component.coffee @@ -8,7 +8,7 @@ class MockLinesComponent @tokenIterator = new TokenIterator @builtLineNodes = [] - dispose: -> + destroy: -> node.remove() for node in @builtLineNodes updateSync: jasmine.createSpy() diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 9560d5794..7a7709e7f 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -5,23 +5,30 @@ TextBuffer = require 'text-buffer' TextEditor = require '../src/text-editor' TextEditorPresenter = require '../src/text-editor-presenter' LinesYardstick = require '../src/lines-yardstick' +MockLinesComponent = require './mock-lines-component' describe "TextEditorPresenter", -> - [buffer, editor, linesYardstick, mockLineNodesProvider] = [] + [buffer, editor, linesYardstick, mockLinesComponent] = [] beforeEach -> # These *should* be mocked in the spec helper, but changing that now would break packages :-( spyOn(window, "setInterval").andCallFake window.fakeSetInterval spyOn(window, "clearInterval").andCallFake window.fakeClearInterval - mockLineNodesProvider = {updateSync: ->} buffer = new TextBuffer(filePath: require.resolve('./fixtures/sample.js')) editor = new TextEditor({buffer}) - waitsForPromise -> buffer.load() + waitsForPromise -> + buffer.load() afterEach -> editor.destroy() buffer.destroy() + mockLinesComponent.destroy() + + buildLinesYardstick = (presenter) -> + mockLinesComponent = new MockLinesComponent(editor) + mockLinesComponent.setDefaultFont("16px monospace") + new LinesYardstick(editor, presenter, mockLinesComponent) buildPresenter = (params={}) -> _.defaults params, @@ -40,7 +47,7 @@ describe "TextEditorPresenter", -> scrollLeft: 0 presenter = new TextEditorPresenter(params) - linesYardstick = new LinesYardstick(editor, presenter, mockLineNodesProvider) + linesYardstick = buildLinesYardstick(presenter) presenter.setLinesYardstick(linesYardstick) presenter @@ -320,24 +327,15 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setContentFrameWidth(10 * maxLineLength + 20) expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 20 - it "updates when the ::baseCharacterWidth changes", -> + it "updates when character widths change", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 1 - expectStateUpdate presenter, -> presenter.setBaseCharacterWidth(15) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 15 * maxLineLength + 1 - - it "updates when the scoped character widths change", -> - waitsForPromise -> atom.packages.activatePackage('language-javascript') - - runs -> - maxLineLength = editor.getMaxScreenLineLength() - presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) - - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 1 - expectStateUpdate presenter, -> presenter.setScopedCharacterWidth(['source.js', 'support.function.js'], 'p', 20) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide + expectStateUpdate presenter, -> + mockLinesComponent.setDefaultFont("33px monospace") + presenter.characterWidthsChanged() + expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 20 * maxLineLength + 1 it "updates when ::softWrapped changes on the editor", -> presenter = buildPresenter(contentFrameWidth: 470, baseCharacterWidth: 10) @@ -564,10 +562,9 @@ describe "TextEditorPresenter", -> presenter = buildPresenter() expect(presenter.getState().hiddenInput.width).toBe 10 - expectStateUpdate presenter, -> presenter.setBaseCharacterWidth(15) - expect(presenter.getState().hiddenInput.width).toBe 15 - - expectStateUpdate presenter, -> presenter.setScopedCharacterWidth(['source.js', 'storage.modifier.js'], 'r', 20) + expectStateUpdate presenter, -> + mockLinesComponent.setDefaultFont("33px monospace") + presenter.characterWidthsChanged() expect(presenter.getState().hiddenInput.width).toBe 20 it "is 2px at the end of lines", -> @@ -654,24 +651,15 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setContentFrameWidth(10 * maxLineLength + 20) expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 20 - it "updates when the ::baseCharacterWidth changes", -> + it "updates when character widths change", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 1 - expectStateUpdate presenter, -> presenter.setBaseCharacterWidth(15) - expect(presenter.getState().content.scrollWidth).toBe 15 * maxLineLength + 1 - - it "updates when the scoped character widths change", -> - waitsForPromise -> atom.packages.activatePackage('language-javascript') - - runs -> - maxLineLength = editor.getMaxScreenLineLength() - presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) - - expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 1 - expectStateUpdate presenter, -> presenter.setScopedCharacterWidth(['source.js', 'support.function.js'], 'p', 20) - expect(presenter.getState().content.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide + expectStateUpdate presenter, -> + mockLinesComponent.setDefaultFont("33px monospace") + presenter.characterWidthsChanged() + expect(presenter.getState().content.scrollWidth).toBe 20 * maxLineLength + 1 it "updates when ::softWrapped changes on the editor", -> presenter = buildPresenter(contentFrameWidth: 470, baseCharacterWidth: 10) @@ -1204,27 +1192,15 @@ describe "TextEditorPresenter", -> expect(stateForCursor(presenter, 3)).toEqual {top: 5, left: 12 * 10, width: 10, height: 5} expect(stateForCursor(presenter, 4)).toEqual {top: 8 * 5 - 20, left: 4 * 10, width: 10, height: 5} - it "updates when ::baseCharacterWidth changes", -> + it "updates when character widths change", -> editor.setCursorBufferPosition([2, 4]) presenter = buildPresenter(explicitHeight: 20, scrollTop: 20) - expectStateUpdate presenter, -> presenter.setBaseCharacterWidth(20) + expectStateUpdate presenter, -> + mockLinesComponent.setDefaultFont("33px monospace") + presenter.characterWidthsChanged() expect(stateForCursor(presenter, 0)).toEqual {top: 0, left: 4 * 20, width: 20, height: 10} - it "updates when scoped character widths change", -> - waitsForPromise -> - atom.packages.activatePackage('language-javascript') - - runs -> - editor.setCursorBufferPosition([1, 4]) - presenter = buildPresenter(explicitHeight: 20) - - expectStateUpdate presenter, -> presenter.setScopedCharacterWidth(['source.js', 'storage.modifier.js'], 'v', 20) - expect(stateForCursor(presenter, 0)).toEqual {top: 1 * 10, left: (3 * 10) + 20, width: 10, height: 10} - - expectStateUpdate presenter, -> presenter.setScopedCharacterWidth(['source.js', 'storage.modifier.js'], 'r', 20) - expect(stateForCursor(presenter, 0)).toEqual {top: 1 * 10, left: (3 * 10) + 20, width: 20, height: 10} - it "updates when cursors are added, moved, hidden, shown, or destroyed", -> editor.setSelectedBufferRanges([ [[1, 2], [1, 2]], @@ -1538,7 +1514,7 @@ describe "TextEditorPresenter", -> ] } - it "updates when ::baseCharacterWidth changes", -> + it "updates when character widths change", -> editor.setSelectedBufferRanges([ [[2, 2], [2, 4]], ]) @@ -1548,30 +1524,13 @@ describe "TextEditorPresenter", -> expectValues stateForSelectionInTile(presenter, 0, 2), { regions: [{top: 0, left: 2 * 10, width: 2 * 10, height: 10}] } - expectStateUpdate presenter, -> presenter.setBaseCharacterWidth(20) + expectStateUpdate presenter, -> + mockLinesComponent.setDefaultFont("33px monospace") + presenter.characterWidthsChanged() expectValues stateForSelectionInTile(presenter, 0, 2), { regions: [{top: 0, left: 2 * 20, width: 2 * 20, height: 10}] } - it "updates when scoped character widths change", -> - waitsForPromise -> - atom.packages.activatePackage('language-javascript') - - runs -> - editor.setSelectedBufferRanges([ - [[2, 4], [2, 6]], - ]) - - presenter = buildPresenter(explicitHeight: 20, scrollTop: 0, tileSize: 2) - - expectValues stateForSelectionInTile(presenter, 0, 2), { - regions: [{top: 0, left: 4 * 10, width: 2 * 10, height: 10}] - } - expectStateUpdate presenter, -> presenter.setScopedCharacterWidth(['source.js', 'keyword.control.js'], 'i', 20) - expectValues stateForSelectionInTile(presenter, 0, 2), { - regions: [{top: 0, left: 4 * 10, width: 20 + 10, height: 10}] - } - it "updates when highlight decorations are added, moved, hidden, shown, or destroyed", -> editor.setSelectedBufferRanges([ [[1, 2], [1, 4]], @@ -1720,7 +1679,7 @@ describe "TextEditorPresenter", -> pixelPosition: {top: 3 * 10 - presenter.state.content.scrollTop, left: 13 * 10} } - it "updates when ::baseCharacterWidth changes", -> + it "updates when character widths change", -> scrollTop = 20 marker = editor.markBufferPosition([2, 13], invalidate: 'touch') decoration = editor.decorateMarker(marker, {type: 'overlay', item}) @@ -1731,7 +1690,9 @@ describe "TextEditorPresenter", -> pixelPosition: {top: 3 * 10 - scrollTop, left: 13 * 10} } - expectStateUpdate presenter, -> presenter.setBaseCharacterWidth(5) + expectStateUpdate presenter, -> + mockLinesComponent.setDefaultFont("8px monospace") + presenter.characterWidthsChanged() expectValues stateForOverlay(presenter, decoration), { item: item diff --git a/src/lines-component.coffee b/src/lines-component.coffee index 2861e55b4..4bddb302e 100644 --- a/src/lines-component.coffee +++ b/src/lines-component.coffee @@ -10,7 +10,7 @@ module.exports = class LinesComponent extends TiledComponent placeholderTextDiv: null - constructor: ({@presenter, @hostElement, @useShadowDOM, visible, @domElementPool}) -> + constructor: ({@presenter, @useShadowDOM, @domElementPool}) -> @domNode = document.createElement('div') @domNode.classList.add('lines') @tilesNode = document.createElement("div") diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index e02609105..00b532213 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1060,6 +1060,8 @@ class TextEditorPresenter @characterWidthsChanged() unless @batchingCharacterMeasurement characterWidthsChanged: -> + @linesYardstick.clearCache() + @shouldUpdateHorizontalScrollState = true @shouldUpdateVerticalScrollState = true @shouldUpdateScrollbarsState = true