From 112ee01bd920a748f01ff795c544eba0ddc55edc Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 6 Oct 2015 11:46:51 +0200 Subject: [PATCH] Don't use atom globals in TextEditorElement ...except when the element is instantiated via HTML --- spec/text-editor-component-spec.coffee | 4 +-- spec/text-editor-presenter-spec.coffee | 1 + src/atom-environment.coffee | 4 +-- src/text-editor-component.coffee | 37 +++++++++++++------------- src/text-editor-element.coffee | 34 ++++++++++++++++++----- src/text-editor-presenter.coffee | 14 +++++----- 6 files changed, 58 insertions(+), 36 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 836516759..be51d3a78 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -35,7 +35,7 @@ describe "TextEditorComponent", -> wrapperNode = new TextEditorElement() wrapperNode.tileSize = tileSize - wrapperNode.initialize(editor) + wrapperNode.initialize(editor, atom) wrapperNode.setUpdatedSynchronously(false) jasmine.attachToDOM(wrapperNode) @@ -2902,7 +2902,7 @@ describe "TextEditorComponent", -> wrapperNode = new TextEditorElement() wrapperNode.tileSize = tileSize - wrapperNode.initialize(editor) + wrapperNode.initialize(editor, atom) hiddenParent.appendChild(wrapperNode) {component} = wrapperNode diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index bc60da469..da816a050 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -39,6 +39,7 @@ describe "TextEditorPresenter", -> verticalScrollbarWidth: 10 scrollTop: 0 scrollLeft: 0 + config: atom.config new TextEditorPresenter(params) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 140df9385..162187bbe 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -207,8 +207,8 @@ class AtomEnvironment extends Model new PaneAxisElement().initialize(model) @views.addViewProvider Pane, (model) -> new PaneElement().initialize(model) - @views.addViewProvider TextEditor, (model) -> - new TextEditorElement().initialize(model) + @views.addViewProvider TextEditor, (model, env) -> + new TextEditorElement().initialize(model, env) @views.addViewProvider(Gutter, createGutterView) registerDefaultOpeners: -> diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index ef1711a04..a3bc9f7ee 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -38,15 +38,15 @@ class TextEditorComponent Object.defineProperty @prototype, "domNode", get: -> @domNodeValue set: (domNode) -> - atom.assert domNode?, "TextEditorComponent::domNode was set to null." + @assert domNode?, "TextEditorComponent::domNode was set to null." @domNodeValue = domNode - constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize}) -> + constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize, @views, @themes, @config, @workspace, @assert}) -> @tileSize = tileSize if tileSize? @disposables = new CompositeDisposable @observeConfig() - @setScrollSensitivity(atom.config.get('editor.scrollSensitivity')) + @setScrollSensitivity(@config.get('editor.scrollSensitivity')) @presenter = new TextEditorPresenter model: @editor @@ -58,6 +58,7 @@ class TextEditorComponent cursorBlinkPeriod: @cursorBlinkPeriod cursorBlinkResumeDelay: @cursorBlinkResumeDelay stoppedScrollingDelay: 200 + config: @config @presenter.onDidUpdateState(@requestUpdate) @@ -102,11 +103,11 @@ class TextEditorComponent @disposables.add @stylesElement.onDidAddStyleElement @onStylesheetsChanged @disposables.add @stylesElement.onDidUpdateStyleElement @onStylesheetsChanged @disposables.add @stylesElement.onDidRemoveStyleElement @onStylesheetsChanged - unless atom.themes.isInitialLoadComplete() - @disposables.add atom.themes.onDidChangeActiveThemes @onAllThemesLoaded + unless @themes.isInitialLoadComplete() + @disposables.add @themes.onDidChangeActiveThemes @onAllThemesLoaded @disposables.add scrollbarStyle.onDidChangePreferredScrollbarStyle @refreshScrollbars - @disposables.add atom.views.pollDocument(@pollDOM) + @disposables.add @views.pollDocument(@pollDOM) @updateSync() @checkForVisibilityChange() @@ -199,10 +200,10 @@ class TextEditorComponent @updateSync() else unless @updateRequested @updateRequested = true - atom.views.updateDocument => + @views.updateDocument => @updateRequested = false @updateSync() if @canUpdate() - atom.views.readDocument(@readAfterUpdateSync) + @views.readDocument(@readAfterUpdateSync) canUpdate: -> @mounted and @editor.isAlive() @@ -270,9 +271,9 @@ class TextEditorComponent timeoutId = setTimeout(writeSelectedTextToSelectionClipboard) observeConfig: -> - @disposables.add atom.config.onDidChange 'editor.fontSize', @sampleFontStyling - @disposables.add atom.config.onDidChange 'editor.fontFamily', @sampleFontStyling - @disposables.add atom.config.onDidChange 'editor.lineHeight', @sampleFontStyling + @disposables.add @config.onDidChange 'editor.fontSize', @sampleFontStyling + @disposables.add @config.onDidChange 'editor.fontFamily', @sampleFontStyling + @disposables.add @config.onDidChange 'editor.lineHeight', @sampleFontStyling onGrammarChanged: => if @scopedConfigDisposables? @@ -283,7 +284,7 @@ class TextEditorComponent @disposables.add(@scopedConfigDisposables) scope = @editor.getRootScopeDescriptor() - @scopedConfigDisposables.add atom.config.observe 'editor.scrollSensitivity', {scope}, @setScrollSensitivity + @scopedConfigDisposables.add @config.observe 'editor.scrollSensitivity', {scope}, @setScrollSensitivity focused: -> if @mounted @@ -343,11 +344,11 @@ class TextEditorComponent {wheelDeltaX, wheelDeltaY} = event # Ctrl+MouseWheel adjusts font size. - if event.ctrlKey and atom.config.get('editor.zoomFontWhenCtrlScrolling') + if event.ctrlKey and @config.get('editor.zoomFontWhenCtrlScrolling') if wheelDeltaY > 0 - atom.workspace.increaseFontSize() + @workspace.increaseFontSize() else if wheelDeltaY < 0 - atom.workspace.decreaseFontSize() + @workspace.decreaseFontSize() event.preventDefault() return @@ -540,7 +541,7 @@ class TextEditorComponent onStylesheetsChanged: (styleElement) => return unless @performedInitialMeasurement - return unless atom.themes.isInitialLoadComplete() + return unless @themes.isInitialLoadComplete() # This delay prevents the styling from going haywire when stylesheets are # reloaded in dev mode. It seems like a workaround for a browser bug, but @@ -647,7 +648,7 @@ class TextEditorComponent isVisible: -> # Investigating an exception that occurs here due to ::domNode being null. - atom.assert @domNode?, "TextEditorComponent::domNode was null.", (error) => + @assert @domNode?, "TextEditorComponent::domNode was null.", (error) => error.metadata = {@initialized} @domNode? and (@domNode.offsetHeight > 0 or @domNode.offsetWidth > 0) @@ -847,7 +848,7 @@ class TextEditorComponent @sampleFontStyling() setShowIndentGuide: (showIndentGuide) -> - atom.config.set("editor.showIndentGuide", showIndentGuide) + @config.set("editor.showIndentGuide", showIndentGuide) setScrollSensitivity: (scrollSensitivity) => if scrollSensitivity = parseInt(scrollSensitivity) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index d8667770f..68d84a560 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -16,24 +16,32 @@ class TextEditorElement extends HTMLElement focusOnAttach: false hasTiledRendering: true logicalDisplayBuffer: true + alreadySetUp: false createdCallback: -> + # Use globals when the following instance variables aren't set. + @config = atom.config + @themes = atom.themes + @workspace = atom.workspace + @assert = atom.assert + @views = atom.views + @emitter = new Emitter @subscriptions = new CompositeDisposable - @initializeContent() + @addEventListener 'focus', @focused.bind(this) @addEventListener 'blur', @blurred.bind(this) - initializeContent: (attributes) -> @classList.add('editor') @setAttribute('tabindex', -1) - if atom.config.get('editor.useShadowDOM') + initializeContent: (attributes) -> + if @config.get('editor.useShadowDOM') @useShadowDOM = true unless ShadowStyleSheet? ShadowStyleSheet = document.createElement('style') - ShadowStyleSheet.textContent = atom.themes.loadLessStylesheet(require.resolve('../static/text-editor-shadow.less')) + ShadowStyleSheet.textContent = @themes.loadLessStylesheet(require.resolve('../static/text-editor-shadow.less')) @createShadowRoot() @@ -56,7 +64,7 @@ class TextEditorElement extends HTMLElement attachedCallback: -> @buildModel() unless @getModel()? - atom.assert(@model.isAlive(), "Attaching a view for a destroyed editor") + @assert(@model.isAlive(), "Attaching a view for a destroyed editor") @mountComponent() unless @component? @listenForComponentEvents() @component.checkForVisibilityChange() @@ -76,7 +84,13 @@ class TextEditorElement extends HTMLElement @subscriptions.add @component.onDidChangeScrollLeft => @emitter.emit("did-change-scroll-left", arguments...) - initialize: (model) -> + initialize: (model, {@views, @config, @themes, @workspace, @assert}) -> + throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @views? + throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @config? + throw new Error("Must pass a themes parameter when initializing TextEditorElements") unless @themes? + throw new Error("Must pass a workspace parameter when initializing TextEditorElements") unless @workspace? + throw new Error("Must pass a assert parameter when initializing TextEditorElements") unless @assert? + @setModel(model) this @@ -85,6 +99,7 @@ class TextEditorElement extends HTMLElement return if model.isDestroyed() @model = model + @initializeContent() @mountComponent() @addGrammarScopeAttribute() @addMiniAttribute() if @model.isMini() @@ -99,7 +114,7 @@ class TextEditorElement extends HTMLElement @model ? @buildModel() buildModel: -> - @setModel(atom.workspace.buildTextEditor( + @setModel(@workspace.buildTextEditor( buffer: new TextBuffer(@textContent) softWrapped: false tabLength: 2 @@ -117,6 +132,11 @@ class TextEditorElement extends HTMLElement editor: @model tileSize: @tileSize useShadowDOM: @useShadowDOM + views: @views + themes: @themes + config: @config + workspace: @workspace + assert: @assert ) @rootElement.appendChild(@component.getDomNode()) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index f5ca2bd6e..ed5826ee8 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -14,7 +14,7 @@ class TextEditorPresenter minimumReflowInterval: 200 constructor: (params) -> - {@model, @autoHeight, @explicitHeight, @contentFrameWidth, @scrollTop, @scrollLeft, @scrollColumn, @scrollRow, @boundingClientRect, @windowWidth, @windowHeight, @gutterWidth} = params + {@model, @config, @autoHeight, @explicitHeight, @contentFrameWidth, @scrollTop, @scrollLeft, @scrollColumn, @scrollRow, @boundingClientRect, @windowWidth, @windowHeight, @gutterWidth} = params {horizontalScrollbarHeight, verticalScrollbarWidth} = params {@lineHeight, @baseCharacterWidth, @backgroundColor, @gutterBackgroundColor, @tileSize} = params {@cursorBlinkPeriod, @cursorBlinkResumeDelay, @stoppedScrollingDelay, @focused} = params @@ -169,9 +169,9 @@ class TextEditorPresenter observeConfig: -> configParams = {scope: @model.getRootScopeDescriptor()} - @scrollPastEnd = atom.config.get('editor.scrollPastEnd', configParams) - @showLineNumbers = atom.config.get('editor.showLineNumbers', configParams) - @showIndentGuide = atom.config.get('editor.showIndentGuide', configParams) + @scrollPastEnd = @config.get('editor.scrollPastEnd', configParams) + @showLineNumbers = @config.get('editor.showLineNumbers', configParams) + @showIndentGuide = @config.get('editor.showIndentGuide', configParams) if @configDisposables? @configDisposables?.dispose() @@ -180,19 +180,19 @@ class TextEditorPresenter @configDisposables = new CompositeDisposable @disposables.add(@configDisposables) - @configDisposables.add atom.config.onDidChange 'editor.showIndentGuide', configParams, ({newValue}) => + @configDisposables.add @config.onDidChange 'editor.showIndentGuide', configParams, ({newValue}) => @showIndentGuide = newValue @shouldUpdateContentState = true @emitDidUpdateState() - @configDisposables.add atom.config.onDidChange 'editor.scrollPastEnd', configParams, ({newValue}) => + @configDisposables.add @config.onDidChange 'editor.scrollPastEnd', configParams, ({newValue}) => @scrollPastEnd = newValue @shouldUpdateVerticalScrollState = true @shouldUpdateScrollbarsState = true @updateScrollHeight() @emitDidUpdateState() - @configDisposables.add atom.config.onDidChange 'editor.showLineNumbers', configParams, ({newValue}) => + @configDisposables.add @config.onDidChange 'editor.showLineNumbers', configParams, ({newValue}) => @showLineNumbers = newValue @shouldUpdateLineNumberGutterState = true @shouldUpdateGutterOrderState = true