From ea6930af541629a3843d44fa866dfc7667f71c68 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 23 Apr 2012 16:23:57 -0600 Subject: [PATCH] Expanded/collapsed state of directories is preserved when an ancestor is collapsed --- spec/extensions/tree-view-spec.coffee | 27 ++++++++++++++++--- src/app/directory.coffee | 2 +- src/extensions/tree-view.coffee | 39 +++++++++++++++++++++------ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/spec/extensions/tree-view-spec.coffee b/spec/extensions/tree-view-spec.coffee index e41b2dc7f..c4b6dc8d2 100644 --- a/spec/extensions/tree-view-spec.coffee +++ b/spec/extensions/tree-view-spec.coffee @@ -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() + diff --git a/src/app/directory.coffee b/src/app/directory.coffee index 47b2b4461..e6e38f280 100644 --- a/src/app/directory.coffee +++ b/src/app/directory.coffee @@ -6,7 +6,7 @@ class Directory constructor: (@path) -> getName: -> - fs.base(@path) + fs.base(@path) + '/' getEntries: -> directories = [] diff --git a/src/extensions/tree-view.coffee b/src/extensions/tree-view.coffee index d59093b1d..8f03c50bc 100644 --- a/src/extensions/tree-view.coffee +++ b/src/extensions/tree-view.coffee @@ -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() +