bone_tree 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +17 -0
  3. data/Gemfile.lock +190 -0
  4. data/Guardfile +14 -0
  5. data/README +1 -0
  6. data/Rakefile +21 -0
  7. data/app/assets/images/bonetree.png +0 -0
  8. data/app/assets/images/crushed_bone.png +0 -0
  9. data/app/assets/index.html +439 -0
  10. data/app/assets/javascripts/bone_tree.js +1292 -0
  11. data/app/assets/stylesheets/bone_tree.css +186 -0
  12. data/app/assets/stylesheets/bone_tree_repo.css +73 -0
  13. data/bone_tree-0.0.1.gem +0 -0
  14. data/bone_tree.gemspec +20 -0
  15. data/config.rb +26 -0
  16. data/config.ru +4 -0
  17. data/docs/index.html +222 -0
  18. data/docs/resources/base.css +70 -0
  19. data/docs/resources/index.css +20 -0
  20. data/docs/resources/module.css +24 -0
  21. data/docs/source/javascripts/bone_tree/_namespace.js.html +45 -0
  22. data/docs/source/javascripts/bone_tree/models/_directory.js.html +126 -0
  23. data/docs/source/javascripts/bone_tree/models/_file.js.html +112 -0
  24. data/docs/source/javascripts/bone_tree/models/_nodes.js.html +174 -0
  25. data/docs/source/javascripts/bone_tree/models/_settings.js.html +75 -0
  26. data/docs/source/javascripts/bone_tree/views/_directory.js.html +94 -0
  27. data/docs/source/javascripts/bone_tree/views/_file.js.html +82 -0
  28. data/docs/source/javascripts/bone_tree/views/_menu.js.html +110 -0
  29. data/docs/source/javascripts/bone_tree/views/_tree.js.html +432 -0
  30. data/lib/version.rb +4 -0
  31. data/source/images/bonetree.png +0 -0
  32. data/source/images/crushed_bone.png +0 -0
  33. data/source/index.html.haml +438 -0
  34. data/source/javascripts/_backbone.js +1293 -0
  35. data/source/javascripts/_jquery.min.js +5 -0
  36. data/source/javascripts/_underscore.js +999 -0
  37. data/source/javascripts/bone_tree/_namespace.js.coffee +7 -0
  38. data/source/javascripts/bone_tree/models/_directory.js.coffee +63 -0
  39. data/source/javascripts/bone_tree/models/_file.js.coffee +55 -0
  40. data/source/javascripts/bone_tree/models/_nodes.js.coffee +117 -0
  41. data/source/javascripts/bone_tree/models/_settings.js.coffee +25 -0
  42. data/source/javascripts/bone_tree/views/_directory.js.coffee +73 -0
  43. data/source/javascripts/bone_tree/views/_file.js.coffee +49 -0
  44. data/source/javascripts/bone_tree/views/_menu.js.coffee +97 -0
  45. data/source/javascripts/bone_tree/views/_tree.js.coffee +498 -0
  46. data/source/javascripts/bone_tree.js.coffee +1 -0
  47. data/source/layout.haml +13 -0
  48. data/source/stylesheets/bone_tree.css.sass +107 -0
  49. data/source/stylesheets/bone_tree_repo.css.sass +65 -0
  50. data/spec/javascripts/directory_view_spec.coffee +91 -0
  51. data/spec/javascripts/file_view_spec.coffee +70 -0
  52. data/spec/javascripts/helpers/spec_helper.coffee +7 -0
  53. data/spec/javascripts/menu_view_spec.coffee +42 -0
  54. data/spec/javascripts/nodes_spec.coffee +37 -0
  55. data/spec/javascripts/support/jasmine.yml +8 -0
  56. data/spec/javascripts/support/jasmine_config.rb +23 -0
  57. data/spec/javascripts/support/jasmine_runner.rb +32 -0
  58. data/spec/javascripts/tree_view_spec.coffee +39 -0
  59. metadata +123 -0
@@ -0,0 +1,7 @@
1
+ window.BoneTree = {}
2
+
3
+ BoneTree.namespace = (target, name, block) ->
4
+ [target, name, block] = [(if typeof exports isnt 'undefined' then exports else window), arguments...] if arguments.length < 3
5
+ top = target
6
+ target = target[item] or= {} for item in name.split '.'
7
+ block target, top
@@ -0,0 +1,63 @@
1
+ #= require ./_nodes
2
+
3
+ BoneTree.namespace "BoneTree.Models", (Models) ->
4
+ class Models.Directory extends Models.Node
5
+ ###
6
+ Public: Object representing a directory.
7
+
8
+ * defaults
9
+ * name - A String naming the directory (default: "New Directory").
10
+ * sortPriority - A String representing the priority with which the
11
+ node is sorted. Directories have sortPriority "0"
12
+ allowing them to be sorted before Files which have
13
+ sortPriority "1".
14
+ * nodeType - A String denoting what type of node this object is.
15
+ The two types are "file" and "directory".
16
+ * open - The state of the directory. Controls whether or not
17
+ to display files and directories contained within this
18
+ Directory (default: false).
19
+
20
+ ###
21
+ defaults:
22
+ name: "New Directory"
23
+ open: false
24
+ sortPriority: "0"
25
+ nodeType: "directory"
26
+
27
+ toggleOpen: =>
28
+ ###
29
+ Public: Toggle the open state of this Directory.
30
+
31
+ Examples
32
+
33
+ dir = new BoneTree.Models.Directory
34
+
35
+ dir.get('open')
36
+ # => false
37
+
38
+ dir.toggleOpen()
39
+ dir.get('open')
40
+ # => true
41
+
42
+ Returns this Directory.
43
+ ###
44
+ currentState = @get 'open'
45
+
46
+ @set {open: not currentState}
47
+
48
+ Models.Directory.find = (currentDirectory, name) ->
49
+ ###
50
+ Internal: Check to see if there is a directory with the matching name
51
+ contained within currentDirectory.
52
+
53
+ * currentDirectory - A Directory object to search for the matching directory name.
54
+
55
+ * name - A String name used to check for matching directory
56
+ names in currentDirectory.
57
+
58
+ Returns The Directory object with the matching name if it exists and undefined otherwise.
59
+ ###
60
+ currentDirectory.collection.find (dir) ->
61
+ dir.get('name') is name
62
+
63
+
@@ -0,0 +1,55 @@
1
+ #= require ./_nodes
2
+
3
+ BoneTree.namespace "BoneTree.Models", (Models) ->
4
+ class Models.File extends Models.Node
5
+ ###
6
+ Public: Object representing file data in the tree.
7
+
8
+ * defaults
9
+ * name - A String naming the file (default: "New File").
10
+ * sortPriority - A String representing the priority with which the
11
+ node is sorted. Directories have sortPriority "0"
12
+ allowing them to be sorted before Files which have
13
+ sortPriority "1".
14
+ * nodeType - A String denoting what type of node this object is.
15
+ The two types are "file" and "directory".
16
+
17
+ ###
18
+ defaults:
19
+ name: "New File"
20
+ sortPriority: "1"
21
+ nodeType: "file"
22
+
23
+ Models.File.createFromFileName = (fileName, fileData) ->
24
+ ###
25
+ Public: Class method to create a new File object based on the fileName
26
+ and fileData passed in.
27
+
28
+ * fileName - A String representing the name of the file to be created.
29
+ files with '.' in the name will be parsed out and only the
30
+ string after the final '.' will be considered the extension.
31
+
32
+ * fileData - An Object of attributes to associate with the file.
33
+
34
+ Examples
35
+
36
+ data = {
37
+ contents: alert 'this is the code in the file'
38
+ createdAt: 1330846900589
39
+ language: 'CoffeeScript'
40
+ }
41
+
42
+ BoneTree.Models.File.createFromFileName('example.coffee', data)
43
+ # => <File>
44
+
45
+ Returns the File object just created.
46
+ ###
47
+
48
+ # Make sure that files like jquery.min.js work
49
+ [names..., extension] = fileName.split "."
50
+ name = names.join('.')
51
+
52
+ data = _.extend({}, fileData, {name: name, extension: extension})
53
+
54
+ return new Models.File(data)
55
+
@@ -0,0 +1,117 @@
1
+ BoneTree.namespace "BoneTree.Models", (Models) ->
2
+ class Models.Node extends Backbone.Model
3
+ ###
4
+ Internal: An abstract super class for File and Directory objects to inherit from.
5
+
6
+ ###
7
+ initialize: ->
8
+ ###
9
+ Internal: Initialize a new Node object. Set it up to contain a collection of
10
+ children nodes.
11
+
12
+ ###
13
+ @collection = new Models.Nodes
14
+
15
+ constantize: =>
16
+ ###
17
+ Public: Returns a String with the nodeType capitalized so that it may be used
18
+ to instatiate the appropriate view type
19
+
20
+ Examples
21
+
22
+ file = new BoneTree.Models.File
23
+ directory = new BoneTree.Models.Directory
24
+
25
+ file.constantize()
26
+ # => 'File'
27
+
28
+ directory.constantize()
29
+ # => 'Directory'
30
+
31
+ # use it to create a new view of the appropriate type
32
+ view = new BoneTree.Views[file.constantize()]
33
+
34
+ Returns a String of the nodeType with the first letter capitalized.
35
+ ###
36
+ nodeType = @get('nodeType')
37
+
38
+ nodeType[0].toUpperCase() + nodeType.substring(1)
39
+
40
+ nameWithExtension: =>
41
+ ###
42
+ Public: Returns the node name with the extension if it has
43
+ one and just the node name if there is no extension.
44
+
45
+ Examples
46
+
47
+ file = new BoneTree.Models.File
48
+ name: "file"
49
+ extension: "coffee"
50
+
51
+ noExt = new BoneTree.Models.File
52
+ name: "file2"
53
+
54
+ directory = new BoneTree.Model.Directory
55
+ name: "source"
56
+
57
+ file.nameWithExtension()
58
+ # => "file.coffee"
59
+
60
+ noExt.nameWithExtension()
61
+ # => "file2"
62
+
63
+ directory.nameWithExtension()
64
+ # => "source"
65
+
66
+ Returns a String. If the extension exists then the node name plus the extension
67
+ are returned. If there is no extension, then just the node name is returned.
68
+ ###
69
+ {extension, name} = @attributes
70
+
71
+ extension ||= ""
72
+
73
+ if extension isnt ""
74
+ extension = "." + extension
75
+
76
+ return name + extension
77
+
78
+ class Models.Nodes extends Backbone.Collection
79
+ ###
80
+ Internal: A collection of node models. Since Node is an abstract super
81
+ class, in practice this collection will hold File objects
82
+ and Directory objects.
83
+
84
+ ###
85
+ comparator: (node) ->
86
+ ###
87
+ Internal: Function that determines how the file tree is sorted. Directories
88
+ are sorted before files. After node type sort
89
+ priority, nodes are sorted by name.
90
+
91
+ Examples
92
+
93
+ tree.addFile('/source/file1.coffee')
94
+ tree.addFile('/source/file2.coffee')
95
+ tree.addFile('main.coffee')
96
+
97
+ tree.render()
98
+
99
+ # even though 'main' comes before 'source' alphabetically it is placed
100
+ # after the 'source' directory due to the sortPriority of the Directory object.
101
+ tree.toAscii()
102
+ # => "
103
+ -source
104
+ -file1.coffee
105
+ -file2.coffee
106
+ -main.coffee
107
+ "
108
+
109
+ ###
110
+ {name, sortPriority} = node.attributes
111
+
112
+ return sortPriority + name
113
+
114
+ model: Models.Node
115
+
116
+
117
+
@@ -0,0 +1,25 @@
1
+ BoneTree.namespace "BoneTree.Models", (Models) ->
2
+ class Models.Settings extends Backbone.Model
3
+ ###
4
+ Internal: A configuration object. Consumers of the API don't need to
5
+ worry about this. It is used internally to manage the options
6
+ passed into the file tree.
7
+
8
+ * defaults
9
+ * beforeAdd - A Function that is invoked before each file is added to the tree.
10
+ It is passed the raw file attributes and should return true if
11
+ that file should be added to the tree and false if not. The
12
+ default implementation is to return true.
13
+ * confirmDeletes - A Boolean. If true, the tree will prompt the user, making
14
+ sure they want to delete the file (default: false).
15
+ * showExtensions - A Boolean. If true, files display their extensions. Internally,
16
+ extensions are always kept track of but by default they are
17
+ hidden (default: false).
18
+ * viewCache - An Object that stores views when they are created and is used
19
+ to look them up to prevent extra views from being created.
20
+ ###
21
+ defaults:
22
+ confirmDeletes: false
23
+ showExtensions: false
24
+ viewCache: {}
25
+
@@ -0,0 +1,73 @@
1
+ BoneTree.namespace "BoneTree.Views", (Views) ->
2
+ class Views.Directory extends Backbone.View
3
+ ###
4
+ Internal: View that renders a Directory node and controls its behavior (class: 'directory', tag: 'ul').
5
+
6
+ ###
7
+ className: 'directory'
8
+ tagName: 'ul'
9
+
10
+ initialize: (options) ->
11
+ ###
12
+ Internal: Initialize a new directory node. Adds associated model cid to the
13
+ view element. Binds change handler to the `change:open` event that
14
+ toggles the display of directory contents. Binds change handler to
15
+ the `change:name` event that re-renders a sorted file tree.
16
+
17
+ * options - Passes in settings object, which is used for access to the
18
+ tree view root in order to proxy events to it.
19
+
20
+ ###
21
+ @settings = options.settings
22
+
23
+ @$el.attr 'data-cid', @model.cid
24
+
25
+ @model.bind 'change:open', (model, open) =>
26
+ @displayChildren(open)
27
+
28
+ @model.bind 'change:name', (model, name) =>
29
+ treeView = @settings.get 'treeView'
30
+ treeView.render().trigger 'rename', model, name
31
+
32
+ @model.collection.bind 'add', @render
33
+
34
+ @model.collection.bind 'remove', (model, collection) =>
35
+ @settings.get('treeView').trigger 'remove', model
36
+ @render()
37
+
38
+ @displayChildren(@model.get('open'))
39
+
40
+ appendView: (node) =>
41
+ ###
42
+ Internal: Appends a view based on the underlying node model to this view.
43
+
44
+ node - A Node model. Either a File or a Directory. This is the model the
45
+ created view will be associated with.
46
+
47
+ ###
48
+ view = @settings.get('treeView').findOrCreateView(node)
49
+
50
+ @$el.append view.render().$el
51
+
52
+ render: =>
53
+ ###
54
+ Internal: Set the text of the view element based on the underlying model name.
55
+
56
+ Returns `this` view.
57
+ ###
58
+ @$el.text @model.get('name')
59
+
60
+ @model.collection.sort().each @appendView
61
+
62
+ return @
63
+
64
+ displayChildren: (open) =>
65
+ ###
66
+ Internal: Toggles display of the children Files or Diretories of this view.
67
+
68
+ ###
69
+ fileDirChildren = @$el.children('.directory, .file')
70
+
71
+ @$el.toggleClass('open', open)
72
+ fileDirChildren.toggle(open)
73
+
@@ -0,0 +1,49 @@
1
+ BoneTree.namespace "BoneTree.Views", (Views) ->
2
+ class Views.File extends Backbone.View
3
+ ###
4
+ Internal: View that renders a File node and controls its behavior (class: 'file', tag: 'li').
5
+
6
+ ###
7
+ className: 'file'
8
+ tagName: 'li'
9
+
10
+ initialize: (options) ->
11
+ ###
12
+ Internal: Initialize a new file node. Adds associated model cid to the
13
+ view element. Binds change handlers to the `change:name` and
14
+ `change:extension` events. These take care of resorting the file
15
+ nodes.
16
+
17
+ * options - Passes in settings object, which is used to control
18
+ whether or not file extensions are shown.
19
+
20
+ ###
21
+ @settings = options.settings
22
+
23
+ @$el.attr('data-cid', @model.cid).addClass(@model.get('extension'))
24
+
25
+ @model.bind 'change:name', (model, name) =>
26
+ treeView = @settings.get('treeView')
27
+ treeView.render().trigger 'rename', model, model.nameWithExtension()
28
+
29
+ @model.bind 'change:extension', (model, extension) =>
30
+ @$el.attr('class', "file #{extension}")
31
+
32
+ treeView = @settings.get('treeView')
33
+ treeView.render().trigger 'rename', model, model.nameWithExtension()
34
+
35
+ render: =>
36
+ ###
37
+ Internal: Sets the text of the file node according to the underlying model
38
+ name. If the 'showExtensions' setting is set, renders the
39
+ full file name with extension, otherwise renders just the file
40
+ name attribute.
41
+
42
+ ###
43
+ if @settings.get('showExtensions')
44
+ @$el.text @model.nameWithExtension()
45
+ else
46
+ @$el.text @model.get('name')
47
+
48
+ return @
49
+
@@ -0,0 +1,97 @@
1
+ BoneTree.namespace "BoneTree.Views", (Views) ->
2
+ class Views.Menu extends Backbone.View
3
+ ###
4
+ Internal: View that controls the context menu (class: 'filetree\_context\_menu').
5
+
6
+ Events
7
+
8
+ * contextMenu - Prevents the standard browser context menu from appearing
9
+ when right clicking within the file tree context menu.
10
+
11
+ * click .rename - Prompts the user to rename a file.
12
+
13
+ * click .delete - Deletes a node from the file tree.
14
+
15
+ ###
16
+ className: 'filetree_context_menu'
17
+
18
+ events:
19
+ 'contextmenu': 'contextMenu'
20
+ 'click .rename': 'rename'
21
+ 'click .delete': 'delete'
22
+
23
+ initialize: (options) ->
24
+ ###
25
+ Internal: Initialize a new menu widget.
26
+
27
+ * options - An Object. Internally used to pass the settings configuration
28
+ into the menu. This controls whether or not the user is
29
+ prompted to confirm deleting a file.
30
+
31
+ ###
32
+ @settings = options.settings
33
+
34
+ contextMenu: (e) =>
35
+ ###
36
+ Internal: Kill the default browser behavior for the contextmenu event.
37
+
38
+ ###
39
+ e.preventDefault()
40
+ e.stopPropagation()
41
+
42
+ delete: (e) =>
43
+ ###
44
+ Internal: Deletes a node from the file tree. If the confirmDeletes setting
45
+ is set, prompts the user for delete confirmation.
46
+
47
+ ###
48
+ if @settings.get('confirmDeletes')
49
+ if confirm "Are you sure you want to delete '#{@model.nameWithExtension()}'?"
50
+ @model.destroy()
51
+ else
52
+ @model.destroy()
53
+
54
+ @$el.hide()
55
+
56
+ rename: (e) =>
57
+ ###
58
+ Internal: Prompts the user to rename a File or Directory.
59
+
60
+ ###
61
+ if newName = prompt "New Name", @model.nameWithExtension()
62
+ [fileName, extension] = newName.split "."
63
+
64
+ extension ?= ""
65
+
66
+ @model.set
67
+ name: fileName
68
+ extension: extension
69
+
70
+ @$el.hide()
71
+
72
+ render: =>
73
+ ###
74
+ Internal: Renders the <ul> that contains the context menu choices
75
+ 'Rename' and 'Delete'.
76
+
77
+ Returns `this`, the menu view.
78
+ ###
79
+
80
+ @$el.html @template()
81
+
82
+ return @
83
+
84
+ template: ->
85
+ ###
86
+ Internal: html template for the context menu.
87
+
88
+ ###
89
+ """
90
+ <ul>
91
+ <li class='rename'>Rename</li>
92
+ <hr/>
93
+ <li class='delete'>Delete</li>
94
+ </ul>
95
+ """
96
+
97
+