Fix pane focus and active item serialization

Also: Un-x root view serialization specs
This commit is contained in:
Corey Johnson & Nathan Sobo
2013-03-06 16:05:26 -08:00
committed by probablycorey
parent d4fc718e8e
commit 4f0bf9020b
3 changed files with 62 additions and 35 deletions

View File

@@ -664,3 +664,30 @@ describe "Pane", ->
it "can serialize and deserialize the pane and all its serializable items", ->
newPane = deserialize(pane.serialize())
expect(newPane.getItems()).toEqual [editSession1, editSession2]
it "restores the active item on deserialization if it serializable", ->
pane.showItem(editSession2)
newPane = deserialize(pane.serialize())
expect(newPane.activeItem).toEqual editSession2
it "defaults to the first item on deserialization if the active item was not serializable", ->
expect(view2.serialize?()).toBeFalsy()
pane.showItem(view2)
newPane = deserialize(pane.serialize())
expect(newPane.activeItem).toEqual editSession1
it "focuses the pane after attach only if had focus when serialized", ->
container.attachToDom()
pane.focus()
state = pane.serialize()
pane.remove()
newPane = deserialize(state)
container.append(newPane)
expect(newPane).toMatchSelector(':has(:focus)')
$(document.activeElement).blur()
state = newPane.serialize()
newPane.remove()
newerPane = deserialize(state)
expect(newerPane).not.toMatchSelector(':has(:focus)')

View File

@@ -18,39 +18,40 @@ describe "RootView", ->
rootView.open(pathToOpen)
rootView.focus()
xdescribe "@deserialize()", ->
describe "@deserialize()", ->
viewState = null
describe "when the serialized RootView has an unsaved buffer", ->
it "constructs the view with the same panes", ->
rootView.attachToDom()
rootView.open()
editor1 = rootView.getActiveEditor()
editor1 = rootView.getActiveView()
buffer = editor1.getBuffer()
editor1.splitRight()
viewState = rootView.serialize()
rootView.deactivate()
window.rootView = RootView.deserialize(viewState)
rootView.focus()
window.rootView = RootView.deserialize(viewState)
rootView.attachToDom()
expect(rootView.getEditors().length).toBe 2
expect(rootView.getActiveEditor().getText()).toBe buffer.getText()
expect(rootView.getTitle()).toBe "untitled #{project.getPath()}"
expect(rootView.getActiveView().getText()).toBe buffer.getText()
expect(rootView.title).toBe "untitled - #{project.getPath()}"
describe "when the serialized RootView has a project", ->
describe "when there are open editors", ->
it "constructs the view with the same panes", ->
editor1 = rootView.getActiveEditor()
editor2 = editor1.splitRight()
editor3 = editor2.splitRight()
editor4 = editor2.splitDown()
editor2.edit(project.buildEditSession('b'))
editor3.edit(project.buildEditSession('../sample.js'))
editor3.setCursorScreenPosition([2, 4])
editor4.edit(project.buildEditSession('../sample.txt'))
editor4.setCursorScreenPosition([0, 2])
rootView.attachToDom()
editor2.focus()
pane1 = rootView.getActivePane()
pane2 = pane1.splitRight()
pane3 = pane2.splitRight()
pane4 = pane2.splitDown()
pane2.showItem(project.buildEditSession('b'))
pane3.showItem(project.buildEditSession('../sample.js'))
pane3.activeItem.setCursorScreenPosition([2, 4])
pane4.showItem(project.buildEditSession('../sample.txt'))
pane4.activeItem.setCursorScreenPosition([0, 2])
pane2.focus()
viewState = rootView.serialize()
rootView.deactivate()
@@ -82,11 +83,11 @@ describe "RootView", ->
expect(editor3.isFocused).toBeFalsy()
expect(editor4.isFocused).toBeFalsy()
expect(rootView.getTitle()).toBe "#{fs.base(editor2.getPath())} #{project.getPath()}"
expect(rootView.title).toBe "#{fs.base(editor2.getPath())} - #{project.getPath()}"
describe "where there are no open editors", ->
it "constructs the view with no open editors", ->
rootView.getActiveEditor().remove()
rootView.getActivePane().remove()
expect(rootView.getEditors().length).toBe 0
viewState = rootView.serialize()
@@ -96,19 +97,6 @@ describe "RootView", ->
rootView.attachToDom()
expect(rootView.getEditors().length).toBe 0
describe "when a pane's wrapped view cannot be deserialized", ->
it "renders an empty pane", ->
viewState =
panesViewState:
deserializer: "Pane",
wrappedView:
deserializer: "BogusView"
rootView.deactivate()
window.rootView = RootView.deserialize(viewState)
expect(rootView.find('.pane').length).toBe 1
expect(rootView.find('.pane').children().length).toBe 0
describe "focus", ->
describe "when there is an active view", ->
it "hands off focus to the active view", ->

View File

@@ -10,8 +10,11 @@ class Pane extends View
@div class: 'pane', =>
@div class: 'item-views', outlet: 'itemViews'
@deserialize: ({items}) ->
new Pane(items.map((item) -> deserialize(item))...)
@deserialize: ({items, focused, activeItemUri}) ->
pane = new Pane(items.map((item) -> deserialize(item))...)
pane.showItemForUri(activeItemUri) if activeItemUri
pane.focusOnAttach = true if focused
pane
activeItem: null
items: null
@@ -47,7 +50,11 @@ class Pane extends View
@on 'focusin', => @makeActive()
@on 'focusout', => @autosaveActiveItem()
afterAttach: ->
afterAttach: (onDom) ->
if @focusOnAttach and onDom
@focusOnAttach = null
@focus()
return if @attached
@attached = true
@trigger 'pane:attached'
@@ -206,6 +213,9 @@ class Pane extends View
itemForUri: (uri) ->
_.detect @items, (item) -> item.getUri?() is uri
showItemForUri: (uri) ->
@showItem(@itemForUri(uri))
cleanupItemView: (item) ->
if item instanceof $
viewToRemove = item
@@ -238,6 +248,8 @@ class Pane extends View
serialize: ->
deserializer: "Pane"
focused: @is(':has(:focus)')
activeItemUri: @activeItem.getUri?() if typeof @activeItem.serialize is 'function'
items: _.compact(@getItems().map (item) -> item.serialize?())
adjustDimensions: -> # do nothing