From bc65137911bf606d8d9bc5a5ea87d90ce612e35d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 3 Jan 2014 16:23:23 -0700 Subject: [PATCH] Remove telepath from Project, WorkspaceView, and Pane* --- spec/git-spec.coffee | 2 +- spec/pane-spec.coffee | 10 ++--- spec/project-spec.coffee | 10 ++--- spec/spec-helper.coffee | 2 +- spec/text-buffer-spec.coffee | 1 - spec/window-spec.coffee | 2 +- spec/workspace-view-spec.coffee | 6 ++- src/atom.coffee | 4 +- src/cursor-view.coffee | 2 +- src/cursor.coffee | 2 +- src/editor.coffee | 1 + src/pane-axis.coffee | 57 ++++++------------------- src/pane-container.coffee | 37 ++++------------ src/pane.coffee | 76 +++++++++++---------------------- src/project.coffee | 37 ++++++++-------- src/workspace-view.coffee | 38 ++++++----------- 16 files changed, 97 insertions(+), 190 deletions(-) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index c6ef5dde2..50e5f5cce 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -257,7 +257,7 @@ describe "Git", -> it "subscribes to all the serialized buffers in the project", -> atom.project.openSync('sample.js') - project2 = atom.project.testPersistence() + project2 = atom.project.testSerialization() buffer = project2.getBuffers()[0] waitsFor -> diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index 356013b4b..a4a669b23 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -677,12 +677,12 @@ describe "Pane", -> describe "serialization", -> it "can serialize and deserialize the pane and all its items", -> - newPane = atom.deserializers.deserialize(pane.serialize().testPersistence()) + newPane = pane.testSerialization() expect(newPane.getItems()).toEqual [view1, editor1, view2, editor2] it "restores the active item on deserialization", -> pane.showItem(editor2) - newPane = atom.deserializers.deserialize(pane.serialize().testPersistence()) + newPane = pane.testSerialization() expect(newPane.activeItem).toEqual editor2 it "does not show items that cannot be deserialized", -> @@ -693,7 +693,7 @@ describe "Pane", -> pane.showItem(new Unserializable) - state = pane.serialize().testPersistence() + state = pane.testSerialization() newPane = atom.deserializers.deserialize(state) expect(newPane.activeItem).toEqual pane.items[0] expect(newPane.items.length).toBe pane.items.length - 1 @@ -702,13 +702,13 @@ describe "Pane", -> container.attachToDom() pane.focus() - container2 = atom.deserializers.deserialize(container.serialize().testPersistence()) + container2 = container.testSerialization() pane2 = container2.getRoot() container2.attachToDom() expect(pane2).toMatchSelector(':has(:focus)') $(document.activeElement).blur() - container3 = atom.deserializers.deserialize(container.serialize().testPersistence()) + container3 = container.testSerialization() pane3 = container3.getRoot() container3.attachToDom() expect(pane3).not.toMatchSelector(':has(:focus)') diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index 5f199b575..da710f724 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -16,21 +16,17 @@ describe "Project", -> afterEach -> deserializedProject?.destroy() - it "destroys unretained buffers and does not include them in the serialized state", -> + it "does not include unretained buffers in the serialized state", -> atom.project.bufferForPathSync('a') expect(atom.project.getBuffers().length).toBe 1 - atom.project.getState().serializeForPersistence() - deserializedProject = atom.project.testPersistence() - + deserializedProject = atom.project.testSerialization() expect(deserializedProject.getBuffers().length).toBe 0 - expect(atom.project.getBuffers().length).toBe 0 it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", -> atom.project.openSync('a') expect(atom.project.getBuffers().length).toBe 1 - atom.project.getState().serializeForPersistence() - deserializedProject = atom.project.testPersistence() + deserializedProject = atom.project.testSerialization() expect(deserializedProject.getBuffers().length).toBe 1 deserializedProject.getBuffers()[0].destroy() diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 618f81503..8555bea4b 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -7,7 +7,7 @@ path = require 'path' {_, $, File, WorkspaceView, fs} = require 'atom' Keymap = require '../src/keymap' Config = require '../src/config' -{Point} = require 'telepath' +{Point} = require 'text-buffer' Project = require '../src/project' Editor = require '../src/editor' EditorView = require '../src/editor-view' diff --git a/spec/text-buffer-spec.coffee b/spec/text-buffer-spec.coffee index 1d1d75cd8..7f26c663b 100644 --- a/spec/text-buffer-spec.coffee +++ b/spec/text-buffer-spec.coffee @@ -1,7 +1,6 @@ {_, fs} = require 'atom' path = require 'path' temp = require 'temp' -{Site} = require 'telepath' TextBuffer = require '../src/text-buffer' describe 'TextBuffer', -> diff --git a/spec/window-spec.coffee b/spec/window-spec.coffee index de01bf375..e83f7c43c 100644 --- a/spec/window-spec.coffee +++ b/spec/window-spec.coffee @@ -93,7 +93,7 @@ describe "Window", -> atom.unloadEditorWindow() - expect(atom.state.getObject('workspaceView')).toEqual workspaceViewState.toObject() + expect(atom.state.getObject('workspaceView')).toEqual workspaceViewState expect(atom.state.getObject('syntax')).toEqual syntaxState expect(atom.saveSync).toHaveBeenCalled() diff --git a/spec/workspace-view-spec.coffee b/spec/workspace-view-spec.coffee index 3147ee13a..1b77bd2d8 100644 --- a/spec/workspace-view-spec.coffee +++ b/spec/workspace-view-spec.coffee @@ -19,9 +19,11 @@ describe "WorkspaceView", -> viewState = null simulateReload = -> - state = atom.workspaceView.serialize().testPersistence() + workspaceState = atom.workspaceView.serialize() + projectState = atom.project.serialize() atom.workspaceView.remove() - atom.workspaceView = WorkspaceView.deserialize(state) + atom.project = atom.deserializers.deserialize(projectState) + atom.workspaceView = WorkspaceView.deserialize(workspaceState) atom.workspaceView.attachToDom() describe "when the serialized WorkspaceView has an unsaved buffer", -> diff --git a/src/atom.coffee b/src/atom.coffee index 90c7049c1..b2a12d071 100644 --- a/src/atom.coffee +++ b/src/atom.coffee @@ -223,7 +223,7 @@ class Atom extends Model # Private: deserializeProject: -> Project = require './project' - @project ?= new Project(path: @getLoadSettings().initialPath) + @project ?= @deserializers.deserialize(@project) ? new Project(path: @getLoadSettings().initialPath) # Private: deserializeWorkspaceView: -> @@ -231,7 +231,7 @@ class Atom extends Model @workspaceView = @deserializers.deserialize(@state.get('workspaceView')) unless @workspaceView? @workspaceView = new WorkspaceView() - @state.set('workspaceView', @workspaceView.getState()) + @state.set('workspaceView', @workspaceView.serialize()) $(@workspaceViewParentSelector).append(@workspaceView) # Private: diff --git a/src/cursor-view.coffee b/src/cursor-view.coffee index 6eca35342..5a5bff89f 100644 --- a/src/cursor-view.coffee +++ b/src/cursor-view.coffee @@ -1,5 +1,5 @@ {View} = require './space-pen-extensions' -{Point, Range} = require 'telepath' +{Point, Range} = require 'text-buffer' _ = require 'underscore-plus' ### Internal ### diff --git a/src/cursor.coffee b/src/cursor.coffee index 46ba11619..95a83450b 100644 --- a/src/cursor.coffee +++ b/src/cursor.coffee @@ -1,4 +1,4 @@ -{Point, Range} = require 'telepath' +{Point, Range} = require 'text-buffer' {Emitter} = require 'emissary' _ = require 'underscore-plus' diff --git a/src/editor.coffee b/src/editor.coffee index 52c77d28a..873be4f38 100644 --- a/src/editor.coffee +++ b/src/editor.coffee @@ -32,6 +32,7 @@ TextMateScopeSelector = require('first-mate').ScopeSelector module.exports = class Editor extends Model Serializable.includeInto(this) + atom.deserializers.add(this) @properties scrollTop: 0 diff --git a/src/pane-axis.coffee b/src/pane-axis.coffee index f8ed436a3..eecf3ee17 100644 --- a/src/pane-axis.coffee +++ b/src/pane-axis.coffee @@ -1,39 +1,26 @@ +Serializable = require 'nostalgia' {$, View} = require './space-pen-extensions' -{TelepathicObject} = require 'telepath' ### Internal ### module.exports = class PaneAxis extends View - @acceptsDocuments: true + Serializable.includeInto(this) - @deserialize: (state) -> - new this(state) + initialize: ({children}={}) -> + @addChild(child) for child in children ? [] - initialize: (args...) -> - if args[0] instanceof TelepathicObject - @state = args[0] - @state.get('children').each (child, index) => - @addChild(atom.deserializers.deserialize(child), index, updateState: false) - else - @state = atom.create(deserializer: @className(), children: []) - @addChild(child) for child in args + serializeParams: -> + children: @children().views().map (child) -> child.serialize() - @state.get('children').on 'changed', ({index, insertedValues, removedValues, siteId}) => - return if siteId is @state.siteId - for childState in removedValues - @removeChild(@children(":eq(#{index})").view(), updateState: false) - for childState, i in insertedValues - @addChild(atom.deserializers.deserialize(childState), index + i, updateState: false) + deserializeParams: (params) -> + params.children = params.children.map (childState) -> atom.deserializers.deserialize(childState) + params - addChild: (child, index=@children().length, options={}) -> + addChild: (child, index=@children().length) -> @insertAt(index, child) - state = child.getState() - @state.get('children').insert(index, state) if options.updateState ? true @getContainer()?.adjustPaneDimensions() - removeChild: (child, options={}) -> - options.updateState ?= true - + removeChild: (child) -> parent = @parent().view() container = @getContainer() childWasInactive = not child.isActive?() @@ -54,11 +41,10 @@ class PaneAxis extends View if parent.setRoot? parent.setRoot(sibling, suppressPaneItemChangeEvents: childWasInactive) else - parent.insertChildBefore(this, sibling, options) - parent.removeChild(this, options) + parent.insertChildBefore(this, sibling) + parent.removeChild(this) sibling.focus() if siblingFocused else - @state.get('children').remove(@indexOf(child)) if options.updateState primitiveRemove(child) container.adjustPaneDimensions() @@ -66,7 +52,6 @@ class PaneAxis extends View container.trigger 'pane:removed', [child] if child instanceof Pane detachChild: (child) -> - @state.get('children').remove(@indexOf(child)) child.detach() getContainer: -> @@ -78,25 +63,11 @@ class PaneAxis extends View getActivePane: -> @find('.pane.active').view() ? @find('.pane:first').view() - insertChildBefore: (child, newChild, options={}) -> + insertChildBefore: (child, newChild) -> newChild.insertBefore(child) - if options.updateState ? true - children = @state.get('children') - childIndex = children.indexOf(child.getState()) - children.insert(childIndex, newChild.getState()) insertChildAfter: (child, newChild) -> newChild.insertAfter(child) - children = @state.get('children') - childIndex = children.indexOf(child.getState()) - children.insert(childIndex + 1, newChild.getState()) - - serialize: -> - state = @state.clone() - state.set('children', child.serialize() for child in @children().views()) - state - - getState: -> @state horizontalChildUnits: -> $(child).view().horizontalGridUnits() for child in @children() diff --git a/src/pane-container.coffee b/src/pane-container.coffee index 97818aef7..8db9b7b44 100644 --- a/src/pane-container.coffee +++ b/src/pane-container.coffee @@ -1,3 +1,4 @@ +Serializable = require 'nostalgia' {$, View} = require './space-pen-extensions' Pane = require './pane' {TelepathicObject} = require 'telepath' @@ -5,33 +6,14 @@ Pane = require './pane' # Private: Manages the list of panes within a {WorkspaceView} module.exports = class PaneContainer extends View + Serializable.includeInto(this) atom.deserializers.add(this) - ### Internal ### - @acceptsDocuments: true - - @deserialize: (state) -> - container = new PaneContainer(state) - container.removeEmptyPanes() - container - @content: -> @div class: 'panes' - initialize: (state) -> - if state instanceof TelepathicObject - @state = state - @setRoot(atom.deserializers.deserialize(@state.get('root'))) - else - @state = atom.create(deserializer: 'PaneContainer') - - @subscribe @state, 'changed', ({newValues, siteId}) => - return if siteId is @state.siteId - if newValues.hasOwnProperty('root') - if rootState = newValues.root - @setRoot(deserialize(rootState)) - else - @setRoot(null) + initialize: ({root}={}) -> + @setRoot(root) @subscribe this, 'pane:attached', (event, pane) => @triggerActiveItemChange() if @getActivePane() is pane @@ -48,12 +30,12 @@ class PaneContainer extends View triggerActiveItemChange: -> @trigger 'pane-container:active-pane-item-changed', [@getActivePaneItem()] - serialize: -> - state = @state.clone() - state.set('root', @getRoot()?.serialize()) - state + serializeParams: -> + root: @getRoot()?.serialize() - getState: -> @state + deserializeParams: (params) -> + params.root = atom.deserializers.deserialize(params.root) + params ### Public ### @@ -95,7 +77,6 @@ class PaneContainer extends View if root? @append(root) root.makeActive?() - @state.set(root: root?.getState()) removeChild: (child) -> throw new Error("Removing non-existant child") unless @getRoot() is child diff --git a/src/pane.coffee b/src/pane.coffee index 0133b134a..f52d8114c 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -1,7 +1,8 @@ {dirname} = require 'path' {$, View} = require './space-pen-extensions' _ = require 'underscore-plus' -{TelepathicObject} = require 'telepath' +Serializable = require 'nostalgia' + PaneRow = require './pane-row' PaneColumn = require './pane-column' @@ -13,51 +14,31 @@ PaneColumn = require './pane-column' # building a package that deals with switching between panes or tiems. module.exports = class Pane extends View + Serializable.includeInto(this) - @acceptsDocuments: true + @version: 1 @content: (wrappedView) -> @div class: 'pane', tabindex: -1, => @div class: 'item-views', outlet: 'itemViews' - @deserialize: (state) -> - pane = new Pane(state) - pane.focusOnAttach = true if state.get('focused') - pane - activeItem: null items: null viewsByItem: null # Views without a setModel() method are stored here # Private: initialize: (args...) -> - @items = [] - if args[0] instanceof TelepathicObject - @state = args[0] - @items = _.compact(@state.get('items').getValues()) - item?.created?() for item in @getItems() + if args[0]?.items # deserializing + {@items, activeItemUri, @focusOnAttach} = args[0] else @items = args - @state = atom.create - deserializer: 'Pane' - items: @items + + @items ?= [] @handleItemEvents(item) for item in @items - @subscribe @state.get('items'), 'changed', ({index, removedValues, insertedValues, siteId}) => - return if siteId is @state.siteId - for item in removedValues - @removeItemAtIndex(index, updateState: false) - for item, i in insertedValues - @addItem(itemState, index + i, updateState: false) - - @subscribe @state, 'changed', ({newValues, siteId}) => - return if siteId is @state.siteId - if newValues.activeItemUri - @showItemForUri(newValues.activeItemUri) - @viewsByItem = new WeakMap() - activeItemUri = @state.get('activeItemUri') + unless activeItemUri? and @showItemForUri(activeItemUri) @showItem(@items[0]) if @items.length > 0 @@ -84,6 +65,15 @@ class Pane extends View @on 'focus', => @activeView?.focus(); false @on 'focusin', => @makeActive() + deserializeParams: (params) -> + params.items = _.compact(params.items.map (itemState) -> atom.deserializers.deserialize(itemState)) + params + + serializeParams: -> + items: _.compact(@items.map (item) -> item.serialize?()) + focusOnAttach: @is(':has(:focus)') + activeItemUri: @getActivePaneItem()?.getUri?() + # Private: afterAttach: (onDom) -> if @focusOnAttach and onDom @@ -173,17 +163,14 @@ class Pane extends View @activeView = view @trigger 'pane:active-item-changed', [item] - @state.set('activeItemUri', item.getUri?()) - # Private: activeItemTitleChanged: => @trigger 'pane:active-item-title-changed' # Public: Add an additional item at the specified index. - addItem: (item, index=@getActiveItemIndex()+1, options={}) -> + addItem: (item, index=@getActiveItemIndex() + 1) -> return if _.include(@items, item) - @state.get('items').splice(index, 0, item) if options.updateState ? true @items.splice(index, 0, item) @trigger 'pane:item-added', [item, index] @handleItemEvents(item) @@ -191,8 +178,7 @@ class Pane extends View handleItemEvents: (item) -> if _.isFunction(item.on) - @subscribe item, 'destroyed', => - @destroyItem(item) if @state.isAlive() + @subscribe item, 'destroyed', => @destroyItem(item) # Public: Remove the currently active item. destroyActiveItem: => @@ -268,17 +254,16 @@ class Pane extends View @saveItem(item) for item in @getItems() # Public: - removeItem: (item, options) -> + removeItem: (item) -> index = @items.indexOf(item) - @removeItemAtIndex(index, options) if index >= 0 + @removeItemAtIndex(index) if index >= 0 # Public: Just remove the item at the given index. - removeItemAtIndex: (index, options={}) -> + removeItemAtIndex: (index) -> item = @items[index] @activeItem.off? 'title-changed', @activeItemTitleChanged if item is @activeItem @showNextItem() if item is @activeItem and @items.length > 1 _.remove(@items, item) - @state.get('items').splice(index, 1) if options.updateState ? true @cleanupItemView(item) @trigger 'pane:item-removed', [item, index] @@ -287,14 +272,13 @@ class Pane extends View oldIndex = @items.indexOf(item) @items.splice(oldIndex, 1) @items.splice(newIndex, 0, item) - @state.get('items').insert(newIndex, item) @trigger 'pane:item-moved', [item, newIndex] # Public: Moves the given item to another pane. moveItemToPane: (item, pane, index) -> @isMovingItem = true pane.addItem(item, index) - @removeItem(item, updateState: false) + @removeItem(item) @isMovingItem = false # Public: Finds the first item that matches the given uri. @@ -330,7 +314,7 @@ class Pane extends View else if @isMovingItem and viewToRemove?.setModel viewToRemove.setModel(null) # dont want to destroy the model, so set to null - @parent().view().removeChild(this, updateState: false) + @parent().view().removeChild(this) # Private: viewForItem: (item) -> @@ -348,16 +332,6 @@ class Pane extends View viewForActiveItem: -> @viewForItem(@activeItem) - # Private: - serialize: -> - state = @state.clone() - state.set('items', @items) - state.set('focused', @is(':has(:focus)')) - state - - # Private: - getState: -> @state - # Private: adjustDimensions: -> # do nothing diff --git a/src/project.coffee b/src/project.coffee index 01aea45f9..e435b3008 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -4,7 +4,9 @@ url = require 'url' _ = require 'underscore-plus' fs = require 'fs-plus' Q = require 'q' -{Model} = require 'telepath' +{Model} = require 'reactionary' +{Emitter, Subscriber} = require 'emissary' +Serializable = require 'nostalgia' TextBuffer = require './text-buffer' Editor = require './editor' @@ -18,9 +20,8 @@ Git = require './git' # of directories and files that you can operate on. module.exports = class Project extends Model - - @properties - path: null + atom.deserializers.add(this) + Serializable.includeInto(this) # Public: Find the local path for the given repository URL. @pathForRepositoryUrl: (repoUrl) -> @@ -28,27 +29,23 @@ class Project extends Model repoName = repoName.replace(/\.git$/, '') path.join(atom.config.get('core.projectHome'), repoName) - constructor: -> - super - if @state? - @buffers = @state.get('buffers').map (state) -> atom.deserializers.deserialize(state) - - # Private: Called by telepath. - created: -> + constructor: ({path, @buffers}={}) -> @buffers ?= [] - for buffer in @buffers do (buffer) => - buffer.once 'destroyed', => @removeBuffer(buffer) if @isAlive() + buffer.once 'destroyed', => @removeBuffer(buffer) @openers = [] @editors = [] - @setPath(@path) + @setPath(path) - # Private: Called by telepath. - willBePersisted: -> - @state.set('buffers', @buffers.map (buffer) -> buffer.serialize()) - @destroyUnretainedBuffers() + serializeParams: -> + path: @path + buffers: _.compact(@buffers.map (buffer) -> buffer.serialize() if buffer.isRetained()) + + deserializeParams: (params) -> + params.buffers = params.buffers.map (bufferState) -> atom.deserializers.deserialize(bufferState) + params # Public: Register an opener for project files. # @@ -246,7 +243,7 @@ class Project extends Model # Private: addBufferAtIndex: (buffer, index, options={}) -> @buffers.splice(index, 0, buffer) - buffer.once 'destroyed', => @removeBuffer(buffer) if @isAlive() + buffer.once 'destroyed', => @removeBuffer(buffer) @emit 'buffer-created', buffer buffer @@ -345,7 +342,7 @@ class Project extends Model # Private: buildEditorForBuffer: (buffer, editorOptions) -> - editor = @create(new Editor(_.extend({buffer}, editorOptions))) + editor = new Editor(_.extend({buffer}, editorOptions)) @addEditor(editor) editor diff --git a/src/workspace-view.coffee b/src/workspace-view.coffee index 98d05a91f..975113bb6 100644 --- a/src/workspace-view.coffee +++ b/src/workspace-view.coffee @@ -4,7 +4,7 @@ Q = require 'q' {$, $$, View} = require './space-pen-extensions' _ = require 'underscore-plus' fs = require 'fs-plus' -{TelepathicObject} = require 'telepath' +Serializable = require 'nostalgia' EditorView = require './editor-view' Pane = require './pane' PaneColumn = require './pane-column' @@ -38,9 +38,10 @@ Editor = require './editor' # module.exports = class WorkspaceView extends View + Serializable.includeInto(this) atom.deserializers.add(this, Pane, PaneRow, PaneColumn, EditorView) - @version: 1 + @version: 2 @configDefaults: ignoredNames: [".git", ".svn", ".DS_Store"] @@ -50,31 +51,16 @@ class WorkspaceView extends View projectHome: path.join(fs.getHomeDirectory(), 'github') audioBeep: true - @acceptsDocuments: true - # Private: - @content: (state) -> + @content: -> @div class: 'workspace', tabindex: -1, => @div class: 'horizontal', outlet: 'horizontal', => @div class: 'vertical', outlet: 'vertical', => @div class: 'panes', outlet: 'panes' # Private: - @deserialize: (state) -> - new WorkspaceView(state) - - # Private: - initialize: (state={}) -> - if state instanceof TelepathicObject - @state = state - panes = atom.deserializers.deserialize(state.get('panes')) - else - panes = new PaneContainer - @state = atom.create - deserializer: @constructor.name - version: @constructor.version - panes: panes.getState() - + initialize: ({panes}={}) -> + panes ?= new PaneContainer @panes.replaceWith(panes) @panes = panes @@ -131,14 +117,14 @@ class WorkspaceView extends View @command 'core:save-as', => @saveActivePaneItemAs() # Private: - serialize: -> - state = @state.clone() - state.set('panes', @panes.serialize()) - state.set('fullScreen', atom.isFullScreen()) - state + deserializeParams: (params) -> + params.panes = atom.deserializers.deserialize(params.panes) + params # Private: - getState: -> @state + serializeParams: -> + panes: @panes.serialize() + fullScreen: atom.isFullScreen() # Private: handleFocus: (e) ->