Expanded/collapsed state of directories is preserved when an ancestor is collapsed

This commit is contained in:
Nathan Sobo
2012-04-23 16:23:57 -06:00
parent 607dfb4987
commit ea6930af54
3 changed files with 56 additions and 12 deletions

View File

@@ -32,11 +32,32 @@ describe "TreeView", ->
it "expands / collapses the associated directory", ->
subdir = rootDirectoryView.find('.entries > li:contains(dir/)')
expect(subdir.find('.disclosure-arrow')).toHaveText('')
disclosureArrow = subdir.find('.disclosure-arrow')
expect(disclosureArrow).toHaveText('')
expect(subdir.find('.entries')).not.toExist()
subdir.find('.disclosure-arrow').click()
disclosureArrow.click()
expect(subdir.find('> .disclosure-arrow')).toHaveText('')
expect(disclosureArrow).toHaveText('')
expect(subdir.find('.entries')).toExist()
disclosureArrow.click()
expect(disclosureArrow).toHaveText('')
expect(subdir.find('.entries')).not.toExist()
it "restores the expansion state of descendant directories", ->
child = rootDirectoryView.find('.entries > li:contains(dir/)')
child.find('> .disclosure-arrow').click()
grandchild = child.find('.entries > li:contains(a-dir/)')
grandchild.find('> .disclosure-arrow').click()
rootDirectoryView.find('> .disclosure-arrow').click()
rootDirectoryView.find('> .disclosure-arrow').click()
# previously expanded descendants remain expanded
expect(rootDirectoryView.find('> .entries > li:contains(dir/) > .entries > li:contains(a-dir/) > .entries').length).toBe 1
# collapsed descendants remain collapsed
expect(rootDirectoryView.find('> .entries > li.contains(zed/) > .entries')).not.toExist()

View File

@@ -6,7 +6,7 @@ class Directory
constructor: (@path) ->
getName: ->
fs.base(@path)
fs.base(@path) + '/'
getEntries: ->
directories = []

View File

@@ -1,5 +1,6 @@
{View, $$} = require 'space-pen'
Directory = require 'directory'
$ = require 'jquery'
module.exports =
class TreeView extends View
@@ -17,33 +18,55 @@ class DirectoryView extends View
@content: ({directory, isExpanded}) ->
@li class: 'directory', =>
@span '', class: 'disclosure-arrow', outlet: 'disclosureArrow', click: 'toggleExpansion'
@span directory.getName() + '/', class: 'name'
@span directory.getName(), class: 'name'
initialize: ({@directory, @isExpanded}) ->
@expand() if @isExpanded
entries: null
initialize: ({@directory, isExpanded}) ->
@expand() if isExpanded
buildEntries: ->
contents = $$ -> @ol class: 'entries'
@entries = $$ -> @ol class: 'entries'
for entry in @directory.getEntries()
if entry instanceof Directory
contents.append(new DirectoryView(directory: entry, isExpanded: false))
@entries.append(new DirectoryView(directory: entry, isExpanded: false))
else
contents.append $$ -> @li entry.getName(), class: 'file'
@append(contents)
@entries.append $$ -> @li entry.getName(), class: 'file'
@append(@entries)
toggleExpansion: ->
if @isExpanded then @collapse() else @expand()
expand: ->
return if @isExpanded
@addClass('expanded')
@disclosureArrow.text('')
@buildEntries()
@deserializeEntries(@entryStates) if @entryStates?
@isExpanded = true
collapse: ->
@entryStates = @serializeEntries()
@removeClass('expanded')
@disclosureArrow.text('')
@find('.entries').remove()
@entries.remove()
@entries = null
@isExpanded = false
serializeEntries: ->
entryStates = {}
@entries.find('> .directory.expanded').each ->
view = $(this).view()
entryStates[view.directory.getName()] = view.serializeEntries()
entryStates
deserializeEntries: (entryStates) ->
for directoryName, childEntryStates of entryStates
@entries.find("> .directory:contains(#{directoryName})").each ->
view = $(this).view()
view.entryStates = childEntryStates
view.expand()