bone_tree 0.5.2 → 0.5.3

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.
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ task :build => [:spec] do
7
7
  # Build static assets
8
8
  `middleman build`
9
9
 
10
- `cp build/javascripts/bone_tree.js lib/assets/bone_tree.js`
10
+ `cp build/javascripts/bone_tree.js lib/assets/src/bone_tree.js`
11
11
  `gem build bone_tree.gemspec`
12
12
  end
13
13
 
@@ -0,0 +1 @@
1
+ #= require ./src/bone_tree
data/lib/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module BoneTree
2
- VERSION = "0.5.2"
2
+ VERSION = "0.5.3"
3
3
  end
4
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bone_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -41,8 +41,7 @@ files:
41
41
  - docs/source/javascripts/bone_tree/views/_file.js.html
42
42
  - docs/source/javascripts/bone_tree/views/_menu.js.html
43
43
  - docs/source/javascripts/bone_tree/views/_tree.js.html
44
- - lib/assets/bone_tree.js
45
- - lib/assets/manifest.coffee
44
+ - lib/assets/bone_tree.js.coffee
46
45
  - lib/version.rb
47
46
  - source/images/bonetree.png
48
47
  - source/images/crushed_bone.png
@@ -86,7 +85,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
86
85
  version: '0'
87
86
  segments:
88
87
  - 0
89
- hash: 2306725095725393049
88
+ hash: -95181981014547945
90
89
  required_rubygems_version: !ruby/object:Gem::Requirement
91
90
  none: false
92
91
  requirements:
@@ -1,1292 +0,0 @@
1
- (function() {
2
- var __slice = [].slice;
3
-
4
- window.BoneTree = {};
5
-
6
- BoneTree.namespace = function(target, name, block) {
7
- var item, top, _i, _len, _ref, _ref1;
8
- if (arguments.length < 3) {
9
- _ref = [(typeof exports !== 'undefined' ? exports : window)].concat(__slice.call(arguments)), target = _ref[0], name = _ref[1], block = _ref[2];
10
- }
11
- top = target;
12
- _ref1 = name.split('.');
13
- for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
14
- item = _ref1[_i];
15
- target = target[item] || (target[item] = {});
16
- }
17
- return block(target, top);
18
- };
19
-
20
- }).call(this);
21
- (function() {
22
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
23
- __hasProp = {}.hasOwnProperty,
24
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
25
-
26
- BoneTree.namespace("BoneTree.Models", function(Models) {
27
- Models.Node = (function(_super) {
28
-
29
- __extends(Node, _super);
30
-
31
- Node.name = 'Node';
32
-
33
- function Node() {
34
- this.nameWithExtension = __bind(this.nameWithExtension, this);
35
-
36
- this.constantize = __bind(this.constantize, this);
37
- return Node.__super__.constructor.apply(this, arguments);
38
- }
39
-
40
- /*
41
- Internal: An abstract super class for File and Directory objects to inherit from.
42
- */
43
-
44
-
45
- Node.prototype.initialize = function() {
46
- /*
47
- Internal: Initialize a new Node object. Set it up to contain a collection of
48
- children nodes.
49
- */
50
- return this.collection = new Models.Nodes;
51
- };
52
-
53
- Node.prototype.constantize = function() {
54
- /*
55
- Public: Returns a String with the nodeType capitalized so that it may be used
56
- to instatiate the appropriate view type
57
-
58
- Examples
59
-
60
- file = new BoneTree.Models.File
61
- directory = new BoneTree.Models.Directory
62
-
63
- file.constantize()
64
- # => 'File'
65
-
66
- directory.constantize()
67
- # => 'Directory'
68
-
69
- # use it to create a new view of the appropriate type
70
- view = new BoneTree.Views[file.constantize()]
71
-
72
- Returns a String of the nodeType with the first letter capitalized.
73
- */
74
-
75
- var nodeType;
76
- nodeType = this.get('nodeType');
77
- return nodeType[0].toUpperCase() + nodeType.substring(1);
78
- };
79
-
80
- Node.prototype.nameWithExtension = function() {
81
- /*
82
- Public: Returns the node name with the extension if it has
83
- one and just the node name if there is no extension.
84
-
85
- Examples
86
-
87
- file = new BoneTree.Models.File
88
- name: "file"
89
- extension: "coffee"
90
-
91
- noExt = new BoneTree.Models.File
92
- name: "file2"
93
-
94
- directory = new BoneTree.Model.Directory
95
- name: "source"
96
-
97
- file.nameWithExtension()
98
- # => "file.coffee"
99
-
100
- noExt.nameWithExtension()
101
- # => "file2"
102
-
103
- directory.nameWithExtension()
104
- # => "source"
105
-
106
- Returns a String. If the extension exists then the node name plus the extension
107
- are returned. If there is no extension, then just the node name is returned.
108
- */
109
-
110
- var extension, name, _ref;
111
- _ref = this.attributes, extension = _ref.extension, name = _ref.name;
112
- extension || (extension = "");
113
- if (extension !== "") {
114
- extension = "." + extension;
115
- }
116
- return name + extension;
117
- };
118
-
119
- return Node;
120
-
121
- })(Backbone.Model);
122
- return Models.Nodes = (function(_super) {
123
-
124
- __extends(Nodes, _super);
125
-
126
- Nodes.name = 'Nodes';
127
-
128
- function Nodes() {
129
- return Nodes.__super__.constructor.apply(this, arguments);
130
- }
131
-
132
- /*
133
- Internal: A collection of node models. Since Node is an abstract super
134
- class, in practice this collection will hold File objects
135
- and Directory objects.
136
- */
137
-
138
-
139
- Nodes.prototype.comparator = function(node) {
140
- /*
141
- Internal: Function that determines how the file tree is sorted. Directories
142
- are sorted before files. After node type sort
143
- priority, nodes are sorted by name.
144
-
145
- Examples
146
-
147
- tree.addFile('/source/file1.coffee')
148
- tree.addFile('/source/file2.coffee')
149
- tree.addFile('main.coffee')
150
-
151
- tree.render()
152
-
153
- # even though 'main' comes before 'source' alphabetically it is placed
154
- # after the 'source' directory due to the sortPriority of the Directory object.
155
- tree.toAscii()
156
- # => "
157
- -source
158
- -file1.coffee
159
- -file2.coffee
160
- -main.coffee
161
- "
162
- */
163
-
164
- var name, sortPriority, _ref;
165
- _ref = node.attributes, name = _ref.name, sortPriority = _ref.sortPriority;
166
- return sortPriority + name;
167
- };
168
-
169
- Nodes.prototype.model = Models.Node;
170
-
171
- return Nodes;
172
-
173
- })(Backbone.Collection);
174
- });
175
-
176
- }).call(this);
177
- (function() {
178
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
179
- __hasProp = {}.hasOwnProperty,
180
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
181
-
182
- BoneTree.namespace("BoneTree.Models", function(Models) {
183
- Models.Directory = (function(_super) {
184
-
185
- __extends(Directory, _super);
186
-
187
- Directory.name = 'Directory';
188
-
189
- function Directory() {
190
- this.toggleOpen = __bind(this.toggleOpen, this);
191
- return Directory.__super__.constructor.apply(this, arguments);
192
- }
193
-
194
- /*
195
- Public: Object representing a directory.
196
-
197
- * defaults
198
- * name - A String naming the directory (default: "New Directory").
199
- * sortPriority - A String representing the priority with which the
200
- node is sorted. Directories have sortPriority "0"
201
- allowing them to be sorted before Files which have
202
- sortPriority "1".
203
- * nodeType - A String denoting what type of node this object is.
204
- The two types are "file" and "directory".
205
- * open - The state of the directory. Controls whether or not
206
- to display files and directories contained within this
207
- Directory (default: false).
208
- */
209
-
210
-
211
- Directory.prototype.defaults = {
212
- name: "New Directory",
213
- open: false,
214
- sortPriority: "0",
215
- nodeType: "directory"
216
- };
217
-
218
- Directory.prototype.toggleOpen = function() {
219
- /*
220
- Public: Toggle the open state of this Directory.
221
-
222
- Examples
223
-
224
- dir = new BoneTree.Models.Directory
225
-
226
- dir.get('open')
227
- # => false
228
-
229
- dir.toggleOpen()
230
- dir.get('open')
231
- # => true
232
-
233
- Returns this Directory.
234
- */
235
-
236
- var currentState;
237
- currentState = this.get('open');
238
- return this.set({
239
- open: !currentState
240
- });
241
- };
242
-
243
- return Directory;
244
-
245
- })(Models.Node);
246
- return Models.Directory.find = function(currentDirectory, name) {
247
- /*
248
- Internal: Check to see if there is a directory with the matching name
249
- contained within currentDirectory.
250
-
251
- * currentDirectory - A Directory object to search for the matching directory name.
252
-
253
- * name - A String name used to check for matching directory
254
- names in currentDirectory.
255
-
256
- Returns The Directory object with the matching name if it exists and undefined otherwise.
257
- */
258
- return currentDirectory.collection.find(function(dir) {
259
- return dir.get('name') === name;
260
- });
261
- };
262
- });
263
-
264
- }).call(this);
265
- (function() {
266
- var __hasProp = {}.hasOwnProperty,
267
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; },
268
- __slice = [].slice;
269
-
270
- BoneTree.namespace("BoneTree.Models", function(Models) {
271
- Models.File = (function(_super) {
272
-
273
- __extends(File, _super);
274
-
275
- File.name = 'File';
276
-
277
- function File() {
278
- return File.__super__.constructor.apply(this, arguments);
279
- }
280
-
281
- /*
282
- Public: Object representing file data in the tree.
283
-
284
- * defaults
285
- * name - A String naming the file (default: "New File").
286
- * sortPriority - A String representing the priority with which the
287
- node is sorted. Directories have sortPriority "0"
288
- allowing them to be sorted before Files which have
289
- sortPriority "1".
290
- * nodeType - A String denoting what type of node this object is.
291
- The two types are "file" and "directory".
292
- */
293
-
294
-
295
- File.prototype.defaults = {
296
- name: "New File",
297
- sortPriority: "1",
298
- nodeType: "file"
299
- };
300
-
301
- return File;
302
-
303
- })(Models.Node);
304
- return Models.File.createFromFileName = function(fileName, fileData) {
305
- /*
306
- Public: Class method to create a new File object based on the fileName
307
- and fileData passed in.
308
-
309
- * fileName - A String representing the name of the file to be created.
310
- files with '.' in the name will be parsed out and only the
311
- string after the final '.' will be considered the extension.
312
-
313
- * fileData - An Object of attributes to associate with the file.
314
-
315
- Examples
316
-
317
- data = {
318
- contents: alert 'this is the code in the file'
319
- createdAt: 1330846900589
320
- language: 'CoffeeScript'
321
- }
322
-
323
- BoneTree.Models.File.createFromFileName('example.coffee', data)
324
- # => <File>
325
-
326
- Returns the File object just created.
327
- */
328
-
329
- var data, extension, name, names, _i, _ref;
330
- _ref = fileName.split("."), names = 2 <= _ref.length ? __slice.call(_ref, 0, _i = _ref.length - 1) : (_i = 0, []), extension = _ref[_i++];
331
- name = names.join('.');
332
- data = _.extend({}, fileData, {
333
- name: name,
334
- extension: extension
335
- });
336
- return new Models.File(data);
337
- };
338
- });
339
-
340
- }).call(this);
341
- (function() {
342
- var __hasProp = {}.hasOwnProperty,
343
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
344
-
345
- BoneTree.namespace("BoneTree.Models", function(Models) {
346
- return Models.Settings = (function(_super) {
347
-
348
- __extends(Settings, _super);
349
-
350
- Settings.name = 'Settings';
351
-
352
- function Settings() {
353
- return Settings.__super__.constructor.apply(this, arguments);
354
- }
355
-
356
- /*
357
- Internal: A configuration object. Consumers of the API don't need to
358
- worry about this. It is used internally to manage the options
359
- passed into the file tree.
360
-
361
- * defaults
362
- * beforeAdd - A Function that is invoked before each file is added to the tree.
363
- It is passed the raw file attributes and should return true if
364
- that file should be added to the tree and false if not. The
365
- default implementation is to return true.
366
- * confirmDeletes - A Boolean. If true, the tree will prompt the user, making
367
- sure they want to delete the file (default: false).
368
- * showExtensions - A Boolean. If true, files display their extensions. Internally,
369
- extensions are always kept track of but by default they are
370
- hidden (default: false).
371
- * viewCache - An Object that stores views when they are created and is used
372
- to look them up to prevent extra views from being created.
373
- */
374
-
375
-
376
- Settings.prototype.defaults = {
377
- confirmDeletes: false,
378
- showExtensions: false,
379
- viewCache: {}
380
- };
381
-
382
- return Settings;
383
-
384
- })(Backbone.Model);
385
- });
386
-
387
- }).call(this);
388
- (function() {
389
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
390
- __hasProp = {}.hasOwnProperty,
391
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
392
-
393
- BoneTree.namespace("BoneTree.Views", function(Views) {
394
- return Views.Directory = (function(_super) {
395
-
396
- __extends(Directory, _super);
397
-
398
- Directory.name = 'Directory';
399
-
400
- function Directory() {
401
- this.displayChildren = __bind(this.displayChildren, this);
402
-
403
- this.render = __bind(this.render, this);
404
-
405
- this.appendView = __bind(this.appendView, this);
406
- return Directory.__super__.constructor.apply(this, arguments);
407
- }
408
-
409
- /*
410
- Internal: View that renders a Directory node and controls its behavior (class: 'directory', tag: 'ul').
411
- */
412
-
413
-
414
- Directory.prototype.className = 'directory';
415
-
416
- Directory.prototype.tagName = 'ul';
417
-
418
- Directory.prototype.initialize = function(options) {
419
- /*
420
- Internal: Initialize a new directory node. Adds associated model cid to the
421
- view element. Binds change handler to the `change:open` event that
422
- toggles the display of directory contents. Binds change handler to
423
- the `change:name` event that re-renders a sorted file tree.
424
-
425
- * options - Passes in settings object, which is used for access to the
426
- tree view root in order to proxy events to it.
427
- */
428
-
429
- var _this = this;
430
- this.settings = options.settings;
431
- this.$el.attr('data-cid', this.model.cid);
432
- this.model.bind('change:open', function(model, open) {
433
- return _this.displayChildren(open);
434
- });
435
- this.model.bind('change:name', function(model, name) {
436
- var treeView;
437
- treeView = _this.settings.get('treeView');
438
- return treeView.render().trigger('rename', model, name);
439
- });
440
- this.model.collection.bind('add', this.render);
441
- this.model.collection.bind('remove', function(model, collection) {
442
- _this.settings.get('treeView').trigger('remove', model);
443
- return _this.render();
444
- });
445
- return this.displayChildren(this.model.get('open'));
446
- };
447
-
448
- Directory.prototype.appendView = function(node) {
449
- /*
450
- Internal: Appends a view based on the underlying node model to this view.
451
-
452
- node - A Node model. Either a File or a Directory. This is the model the
453
- created view will be associated with.
454
- */
455
-
456
- var view;
457
- view = this.settings.get('treeView').findOrCreateView(node);
458
- return this.$el.append(view.render().$el);
459
- };
460
-
461
- Directory.prototype.render = function() {
462
- /*
463
- Internal: Set the text of the view element based on the underlying model name.
464
-
465
- Returns `this` view.
466
- */
467
- this.$el.text(this.model.get('name'));
468
- this.model.collection.sort().each(this.appendView);
469
- return this;
470
- };
471
-
472
- Directory.prototype.displayChildren = function(open) {
473
- /*
474
- Internal: Toggles display of the children Files or Diretories of this view.
475
- */
476
-
477
- var fileDirChildren;
478
- fileDirChildren = this.$el.children('.directory, .file');
479
- this.$el.toggleClass('open', open);
480
- return fileDirChildren.toggle(open);
481
- };
482
-
483
- return Directory;
484
-
485
- })(Backbone.View);
486
- });
487
-
488
- }).call(this);
489
- (function() {
490
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
491
- __hasProp = {}.hasOwnProperty,
492
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
493
-
494
- BoneTree.namespace("BoneTree.Views", function(Views) {
495
- return Views.File = (function(_super) {
496
-
497
- __extends(File, _super);
498
-
499
- File.name = 'File';
500
-
501
- function File() {
502
- this.render = __bind(this.render, this);
503
- return File.__super__.constructor.apply(this, arguments);
504
- }
505
-
506
- /*
507
- Internal: View that renders a File node and controls its behavior (class: 'file', tag: 'li').
508
- */
509
-
510
-
511
- File.prototype.className = 'file';
512
-
513
- File.prototype.tagName = 'li';
514
-
515
- File.prototype.initialize = function(options) {
516
- /*
517
- Internal: Initialize a new file node. Adds associated model cid to the
518
- view element. Binds change handlers to the `change:name` and
519
- `change:extension` events. These take care of resorting the file
520
- nodes.
521
-
522
- * options - Passes in settings object, which is used to control
523
- whether or not file extensions are shown.
524
- */
525
-
526
- var _this = this;
527
- this.settings = options.settings;
528
- this.$el.attr('data-cid', this.model.cid).addClass(this.model.get('extension'));
529
- this.model.bind('change:name', function(model, name) {
530
- var treeView;
531
- treeView = _this.settings.get('treeView');
532
- return treeView.render().trigger('rename', model, model.nameWithExtension());
533
- });
534
- return this.model.bind('change:extension', function(model, extension) {
535
- var treeView;
536
- _this.$el.attr('class', "file " + extension);
537
- treeView = _this.settings.get('treeView');
538
- return treeView.render().trigger('rename', model, model.nameWithExtension());
539
- });
540
- };
541
-
542
- File.prototype.render = function() {
543
- /*
544
- Internal: Sets the text of the file node according to the underlying model
545
- name. If the 'showExtensions' setting is set, renders the
546
- full file name with extension, otherwise renders just the file
547
- name attribute.
548
- */
549
- if (this.settings.get('showExtensions')) {
550
- this.$el.text(this.model.nameWithExtension());
551
- } else {
552
- this.$el.text(this.model.get('name'));
553
- }
554
- return this;
555
- };
556
-
557
- return File;
558
-
559
- })(Backbone.View);
560
- });
561
-
562
- }).call(this);
563
- (function() {
564
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
565
- __hasProp = {}.hasOwnProperty,
566
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
567
-
568
- BoneTree.namespace("BoneTree.Views", function(Views) {
569
- return Views.Menu = (function(_super) {
570
-
571
- __extends(Menu, _super);
572
-
573
- Menu.name = 'Menu';
574
-
575
- function Menu() {
576
- this.render = __bind(this.render, this);
577
-
578
- this.rename = __bind(this.rename, this);
579
-
580
- this["delete"] = __bind(this["delete"], this);
581
-
582
- this.contextMenu = __bind(this.contextMenu, this);
583
- return Menu.__super__.constructor.apply(this, arguments);
584
- }
585
-
586
- /*
587
- Internal: View that controls the context menu (class: 'filetree\_context\_menu').
588
-
589
- Events
590
-
591
- * contextMenu - Prevents the standard browser context menu from appearing
592
- when right clicking within the file tree context menu.
593
-
594
- * click .rename - Prompts the user to rename a file.
595
-
596
- * click .delete - Deletes a node from the file tree.
597
- */
598
-
599
-
600
- Menu.prototype.className = 'filetree_context_menu';
601
-
602
- Menu.prototype.events = {
603
- 'contextmenu': 'contextMenu',
604
- 'click .rename': 'rename',
605
- 'click .delete': 'delete'
606
- };
607
-
608
- Menu.prototype.initialize = function(options) {
609
- /*
610
- Internal: Initialize a new menu widget.
611
-
612
- * options - An Object. Internally used to pass the settings configuration
613
- into the menu. This controls whether or not the user is
614
- prompted to confirm deleting a file.
615
- */
616
- return this.settings = options.settings;
617
- };
618
-
619
- Menu.prototype.contextMenu = function(e) {
620
- /*
621
- Internal: Kill the default browser behavior for the contextmenu event.
622
- */
623
- e.preventDefault();
624
- return e.stopPropagation();
625
- };
626
-
627
- Menu.prototype["delete"] = function(e) {
628
- /*
629
- Internal: Deletes a node from the file tree. If the confirmDeletes setting
630
- is set, prompts the user for delete confirmation.
631
- */
632
- if (this.settings.get('confirmDeletes')) {
633
- if (confirm("Are you sure you want to delete '" + (this.model.nameWithExtension()) + "'?")) {
634
- this.model.destroy();
635
- }
636
- } else {
637
- this.model.destroy();
638
- }
639
- return this.$el.hide();
640
- };
641
-
642
- Menu.prototype.rename = function(e) {
643
- /*
644
- Internal: Prompts the user to rename a File or Directory.
645
- */
646
-
647
- var extension, fileName, newName, _ref;
648
- if (newName = prompt("New Name", this.model.nameWithExtension())) {
649
- _ref = newName.split("."), fileName = _ref[0], extension = _ref[1];
650
- if (extension == null) {
651
- extension = "";
652
- }
653
- this.model.set({
654
- name: fileName,
655
- extension: extension
656
- });
657
- }
658
- return this.$el.hide();
659
- };
660
-
661
- Menu.prototype.render = function() {
662
- /*
663
- Internal: Renders the <ul> that contains the context menu choices
664
- 'Rename' and 'Delete'.
665
-
666
- Returns `this`, the menu view.
667
- */
668
- this.$el.html(this.template());
669
- return this;
670
- };
671
-
672
- Menu.prototype.template = function() {
673
- /*
674
- Internal: html template for the context menu.
675
- */
676
- return "<ul>\n <li class='rename'>Rename</li>\n <hr/>\n <li class='delete'>Delete</li>\n</ul>";
677
- };
678
-
679
- return Menu;
680
-
681
- })(Backbone.View);
682
- });
683
-
684
- }).call(this);
685
- (function() {
686
- var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
687
- __hasProp = {}.hasOwnProperty,
688
- __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; },
689
- __slice = [].slice;
690
-
691
- BoneTree.namespace("BoneTree.Views", function(Views) {
692
- var Models;
693
- Models = BoneTree.Models;
694
- return Views.Tree = (function(_super) {
695
-
696
- __extends(Tree, _super);
697
-
698
- Tree.name = 'Tree';
699
-
700
- function Tree() {
701
- this.render = __bind(this.render, this);
702
-
703
- this._openFile = __bind(this._openFile, this);
704
-
705
- this._openDirectory = __bind(this._openDirectory, this);
706
-
707
- this.getModelFromClick = __bind(this.getModelFromClick, this);
708
-
709
- this.toAscii = __bind(this.toAscii, this);
710
-
711
- this.files = __bind(this.files, this);
712
-
713
- this._getFile = __bind(this._getFile, this);
714
-
715
- this.getDirectory = __bind(this.getDirectory, this);
716
-
717
- this.flatten = __bind(this.flatten, this);
718
-
719
- this.filterNodes = __bind(this.filterNodes, this);
720
-
721
- this._contextMenu = __bind(this._contextMenu, this);
722
-
723
- this._closeMenu = __bind(this._closeMenu, this);
724
-
725
- this.closeDirectories = __bind(this.closeDirectories, this);
726
-
727
- this.getModelByCid = __bind(this.getModelByCid, this);
728
-
729
- this.findOrCreateView = __bind(this.findOrCreateView, this);
730
-
731
- this.addToTree = __bind(this.addToTree, this);
732
-
733
- this.addFromJSON = __bind(this.addFromJSON, this);
734
-
735
- this.file = __bind(this.file, this);
736
- return Tree.__super__.constructor.apply(this, arguments);
737
- }
738
-
739
- /*
740
- Public: The base tree object. Events from other objects are proxied to the tree
741
- so API consumers only need to know about this top level object.
742
- */
743
-
744
-
745
- Tree.prototype.className = 'tree';
746
-
747
- Tree.prototype.events = {
748
- 'contextmenu .file': '_contextMenu',
749
- 'contextmenu .directory': '_contextMenu',
750
- 'click .directory': '_openDirectory',
751
- 'click .file': '_openFile'
752
- };
753
-
754
- Tree.prototype.initialize = function() {
755
- /*
756
- Public: Initialize a new filetree widget
757
-
758
- * options - An Object of global configuration options for the file tree.
759
- * confirmDeletes - A Boolean. If true, the tree will prompt the user, making
760
- sure they want to delete the file (default: false).
761
- * showExtensions - A Boolean. If true, files display their extensions. Internally,
762
- extensions are always kept track of but by default they are
763
- hidden (default: false).
764
- */
765
-
766
- var settingsConfig,
767
- _this = this;
768
- $(document).click(this._closeMenu);
769
- this._currentFileData = null;
770
- settingsConfig = _.extend({}, this.options, {
771
- treeView: this
772
- });
773
- this.settings = new Models.Settings(settingsConfig);
774
- this.menuView = new Views.Menu({
775
- settings: this.settings
776
- });
777
- this.menuView.render().$el.appendTo($('body'));
778
- this.root = new Models.Node;
779
- this.root.collection.bind('add', this.render);
780
- return this.root.collection.bind('remove', function(model, collection) {
781
- _this.$("[data-cid='" + model.cid + "']").remove();
782
- _this.render();
783
- return _this.trigger('remove', model);
784
- });
785
- };
786
-
787
- Tree.prototype.file = function(filePath, fileData) {
788
- var dirs, file, fileName, _i, _ref;
789
- if (filePath[0] === '/') {
790
- filePath = filePath.replace('/', '');
791
- }
792
- if (fileData != null) {
793
- this._currentFileData = _.extend(fileData, {
794
- path: filePath
795
- });
796
- if (this._currentFileData.autoOpen == null) {
797
- this._currentFileData.autoOpen = true;
798
- }
799
- if (this._currentFileData.hidden == null) {
800
- this._currentFileData.hidden = false;
801
- }
802
- } else {
803
- return this._getFile(filePath);
804
- }
805
- _ref = filePath.split('/'), dirs = 2 <= _ref.length ? __slice.call(_ref, 0, _i = _ref.length - 1) : (_i = 0, []), fileName = _ref[_i++];
806
- if (file = this._getFile(filePath)) {
807
- return file.set(this._currentFileData);
808
- } else {
809
- return this.addToTree(this.root, dirs, fileName);
810
- }
811
- };
812
-
813
- Tree.prototype.addFromJSON = function(data, currentPath) {
814
- var file, name, _i, _len, _ref;
815
- if (currentPath == null) {
816
- currentPath = "";
817
- }
818
- /*
819
- Public: Creates a file tree from a JSON representation. Expects the
820
- JSON object to have a `name` property at each level, specifying
821
- the name of the file or directory, and a files array if the
822
- current node has child directories or files.
823
-
824
- * data - An Object that represents hierarchical file data.
825
-
826
- * currentPath - A String representing the current location in the tree.
827
- Defaults to the file tree root. (default: "")
828
-
829
- Examples
830
-
831
- data = {
832
- name: "My Project"
833
- files: [
834
- { name: "Empty Folder" }
835
- { name: "SomeFile.coffee" }
836
- { name: "AnotherFile.coffee" }
837
- {
838
- name: "Folder with Files inside"
839
- files: [
840
- { name: "NestedFile.coffee" }
841
- ]
842
- }
843
- ]
844
- }
845
-
846
- tree.addFromJSON(data)
847
- # => <Tree>
848
-
849
- Returns the Tree view object.
850
- */
851
-
852
- name = "";
853
- if (data.name != null) {
854
- name = data.name + '/';
855
- delete data.name;
856
- }
857
- if (data.extension != null) {
858
- name = name.replace('/', '.' + data.extension);
859
- delete data.extension;
860
- }
861
- currentPath += name;
862
- if (data.files != null) {
863
- _ref = data.files;
864
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
865
- file = _ref[_i];
866
- this.addFromJSON(file, currentPath);
867
- }
868
- } else {
869
- this.file(currentPath, data);
870
- }
871
- return this;
872
- };
873
-
874
- Tree.prototype.addToTree = function(currentDirectory, remainingDirectories, fileName) {
875
- /*
876
- Internal: Recursive method that traverses nodes, creating
877
- Files and Directories.
878
-
879
- * currentDirectory - A Node object representing which directory we are
880
- adding the current Directory or File to.
881
- * remainingDirectories - A '/' separated String representing the remaining
882
- directories to add.
883
- * fileName - The String name of the file to be added. This can
884
- include the extension name separated by a '.'.
885
-
886
- Examples
887
-
888
- tree.addToTree(@root, '/source/subdirectory/', 'main.coffee')
889
- # => <File>
890
-
891
- Returns the File object if it was created and null if no file was given.
892
- */
893
-
894
- var file, matchingDirectory, newDirectory, newNode, nextDirectoryName;
895
- if (remainingDirectories.length) {
896
- nextDirectoryName = remainingDirectories.shift();
897
- if (matchingDirectory = Models.Directory.find(currentDirectory, nextDirectoryName)) {
898
- matchingDirectory.set({
899
- open: true
900
- });
901
- return this.addToTree(matchingDirectory, remainingDirectories, fileName);
902
- } else {
903
- newNode = new Models.Directory({
904
- name: nextDirectoryName,
905
- open: true
906
- });
907
- newDirectory = currentDirectory.collection.add(newNode);
908
- return this.addToTree(newNode, remainingDirectories, fileName);
909
- }
910
- } else {
911
- if (fileName === "") {
912
- return null;
913
- }
914
- file = Models.File.createFromFileName(fileName, this._currentFileData);
915
- this._currentFileData = null;
916
- currentDirectory.collection.add(file);
917
- if (file.get('autoOpen')) {
918
- this.trigger('openFile', file);
919
- }
920
- return file;
921
- }
922
- };
923
-
924
- Tree.prototype.findOrCreateView = function(node) {
925
- /*
926
- Internal: Look up existing view in the view cache or Create a new view
927
- of the correct type (either File or Directory).
928
-
929
- * node - A Node object. Either a File object or a Directory object.
930
- This is the model that the view will be associated with.
931
-
932
- Examples
933
-
934
- file = new BoneTree.Models.File
935
-
936
- # This will create a new view since we just created the File
937
- tree.findOrCreateView(file)
938
- # => <FileView>
939
-
940
- Returns the view corresponding to the model passed in.
941
- */
942
-
943
- var type, view, viewCache;
944
- type = node.constantize();
945
- viewCache = this.settings.get('viewCache');
946
- if (!(view = viewCache[node.cid])) {
947
- view = viewCache[node.cid] = new Views[type]({
948
- model: node,
949
- settings: this.settings
950
- });
951
- }
952
- return view;
953
- };
954
-
955
- Tree.prototype.getModelByCid = function(cid) {
956
- var modelCid, view, viewCache;
957
- viewCache = this.settings.get('viewCache');
958
- for (modelCid in viewCache) {
959
- view = viewCache[modelCid];
960
- if (modelCid === cid) {
961
- return view.model;
962
- }
963
- }
964
- };
965
-
966
- Tree.prototype.closeDirectories = function() {
967
- /*
968
- Public: Close all the directories in the file tree.
969
-
970
- Examples
971
-
972
- tree.closeDirectories()
973
- # => <Tree>
974
-
975
- Returns the Tree view object.
976
- */
977
-
978
- var directories;
979
- directories = _.filter(this.flatten(), function(node) {
980
- return node.get('nodeType') === 'directory';
981
- });
982
- _.invoke(directories, 'set', {
983
- open: false
984
- });
985
- return this;
986
- };
987
-
988
- Tree.prototype._closeMenu = function(e) {
989
- /*
990
- Internal: Close the context menu. This is called every click on
991
- the document and closes the menu unless you are clicking
992
- within it. This shouldn't be called directly, it is called
993
- automatically by Backbone from user interactions.
994
-
995
- Returns the Menu view object.
996
- */
997
- if (!$(e.currentTarget).is('.menu')) {
998
- this.menuView.$el.hide();
999
- }
1000
- return this.menuView;
1001
- };
1002
-
1003
- Tree.prototype._contextMenu = function(e) {
1004
- /*
1005
- Internal: Open the context menu. This prevents the default browser
1006
- context menu event. This shouldn't be called directly, it is
1007
- called automatically by Backbone from user interations.
1008
-
1009
- Returns the Menu view object.
1010
- */
1011
-
1012
- var model;
1013
- e.preventDefault();
1014
- model = this.getModelFromClick(e);
1015
- this.menuView.model = model;
1016
- this.menuView.$el.css({
1017
- left: e.pageX,
1018
- top: e.pageY
1019
- }).show();
1020
- return this.menuView;
1021
- };
1022
-
1023
- Tree.prototype.filterNodes = function(nodeType, nodeName) {
1024
- /*
1025
- Internal: Returns file tree nodes that match the nodeType and nodeName.
1026
-
1027
- * nodeType - A String that represents the nodeType to match. Choices are
1028
- 'file' or 'directory'.
1029
- * nodeName - A String that represents the name of the node to match.
1030
-
1031
- Examples
1032
-
1033
- # Add some files to the tree
1034
- tree.file('/source/main.coffee')
1035
- tree.file('/source/player.coffee')
1036
-
1037
- # returns an array containing the File 'main.coffee'
1038
- tree.filterNodes('file', 'main')
1039
- # => [<File>]
1040
-
1041
- Returns an Array of nodes that match the filter criteria.
1042
- */
1043
-
1044
- var results,
1045
- _this = this;
1046
- results = _.filter(this.flatten(), function(node) {
1047
- return node.get('nodeType') === nodeType && node.get('name') === nodeName;
1048
- });
1049
- return results;
1050
- };
1051
-
1052
- Tree.prototype.flatten = function(currentNode, results) {
1053
- var _this = this;
1054
- if (currentNode == null) {
1055
- currentNode = this.root;
1056
- }
1057
- if (results == null) {
1058
- results = [];
1059
- }
1060
- /*
1061
- Internal: Returns a one dimensional ordered array representing the
1062
- Directory and File nodes in the tree.
1063
-
1064
- * currentNode - The node to start at when flattening
1065
- * nodeName - A String that represents the name of the node to match.
1066
-
1067
- Examples
1068
-
1069
- # Add some files to the tree
1070
- tree.file('/source/main.coffee', {aFile: true})
1071
- tree.file('/source/player.coffee', {playerData: {x: 50, y: 30}})
1072
-
1073
- # returns an array containing the File 'main.coffee'
1074
- tree.filterNodes('file', 'main')
1075
- # => [<File>]
1076
-
1077
- Returns an Array of nodes that match the filter criteria.
1078
- */
1079
-
1080
- currentNode.collection.each(function(node) {
1081
- results.push(node);
1082
- if (node.collection.length) {
1083
- return _this.flatten(node, results);
1084
- }
1085
- });
1086
- return results;
1087
- };
1088
-
1089
- Tree.prototype.getDirectory = function(directoryName) {
1090
- /*
1091
- Public: Returns an array of directories matching the given directoryName.
1092
-
1093
- * directoryName - A String naming the directory to match.
1094
-
1095
- Examples
1096
-
1097
- # Add some files to the tree
1098
- tree.file('/source/main.coffee', {size: 4039})
1099
- tree.file('/source/player.coffee', {size: 399})
1100
- tree.file('/directory2/file.coffee', {size: 23})
1101
-
1102
- # returns an array containing the Directory 'source'
1103
- tree.getDirectory('source')
1104
- # => [<Directory>]
1105
-
1106
- Returns an Array of Directory nodes that match directoryName.
1107
- */
1108
- return this.filterNodes('directory', directoryName);
1109
- };
1110
-
1111
- Tree.prototype._getFile = function(filePath) {
1112
- /*
1113
- Internal: Returns a file at the specified location.
1114
-
1115
- * fileName - A String describing the file path.
1116
-
1117
- Examples
1118
-
1119
- # Add some files to the tree
1120
- tree.file('/source/main.coffee', {size: 30459})
1121
- tree.file('/source/player.coffee', {size: 943})
1122
- tree.file('/directory2/main.coffee', {size: 4945})
1123
-
1124
- # returns an array containing both the files named main.
1125
- tree._getFile('source/main.coffee')
1126
- # => <File>
1127
-
1128
- Returns a File at the given location.
1129
- */
1130
-
1131
- var filtered, nodes;
1132
- if (filePath[0] === '/') {
1133
- filePath = filePath.replace('/', '');
1134
- }
1135
- nodes = this.flatten();
1136
- filtered = _.filter(nodes, function(node) {
1137
- return node.get('nodeType') === 'file' && node.get('path') === filePath;
1138
- });
1139
- return filtered[0];
1140
- };
1141
-
1142
- Tree.prototype.files = function(directoryName) {
1143
- /*
1144
- Public: Returns an array of files contained within the directory
1145
- matching directoryName.
1146
-
1147
- * directoryName - A String naming the directory to look inside.
1148
-
1149
- Examples
1150
-
1151
- # Add some files to the tree
1152
- tree.file('/source/main.coffee', {main: true})
1153
- tree.file('/source/player.coffee', {active: true})
1154
- tree.file('/directory2/main.coffee', {active: true})
1155
-
1156
- # returns an array containing the files 'player.coffee' and 'main.coffee'
1157
- tree.files('source')
1158
- # => [<File>, <File>]
1159
-
1160
- Returns an Array of File nodes that are contained in the
1161
- Directory matching directoryName.
1162
- */
1163
-
1164
- var directory, nodesInDirectory;
1165
- if (directoryName == null) {
1166
- return _.filter(this.flatten(), function(node) {
1167
- return node.get('nodeType') === 'file';
1168
- });
1169
- }
1170
- directory = this.getDirectory(directoryName)[0];
1171
- if (!directory) {
1172
- return [];
1173
- }
1174
- nodesInDirectory = this.flatten(directory);
1175
- return _.filter(nodesInDirectory, function(node) {
1176
- return node.get('nodeType') === 'file';
1177
- });
1178
- };
1179
-
1180
- Tree.prototype.toAscii = function(collection, indentation, output) {
1181
- var n, rootCollection, spaces, _i,
1182
- _this = this;
1183
- if (indentation == null) {
1184
- indentation = 0;
1185
- }
1186
- if (output == null) {
1187
- output = "\n";
1188
- }
1189
- /*
1190
- Internal: A String representation of the filetree.
1191
-
1192
- * collection - A NodeCollection object describing which folder to start at.
1193
- * indentation - A Number describing how many spaces to indent the next filetree element (default: 0).
1194
- * output - A String representing the current filetree output (default: "\n").
1195
-
1196
- Examples
1197
-
1198
- # Add some files to the tree
1199
- tree.file('/source/main.coffee', {main: true})
1200
- tree.file('/source/player.coffee', {active: true})
1201
- tree.file('/directory2/main.coffee', {active: false})
1202
-
1203
- tree.toAscii()
1204
- # => "
1205
- -directory2
1206
- -main.coffee
1207
- -source
1208
- -main.coffee
1209
- -player.coffee
1210
- "
1211
-
1212
- Returns a String representation of the sorted nodes of the file tree.
1213
- */
1214
-
1215
- rootCollection = collection || this.root.collection;
1216
- spaces = "";
1217
- for (n = _i = 0; 0 <= indentation ? _i <= indentation : _i >= indentation; n = 0 <= indentation ? ++_i : --_i) {
1218
- spaces += " ";
1219
- }
1220
- rootCollection.each(function(nodes) {
1221
- var typeChar;
1222
- typeChar = nodes.get('type') === 'directory' ? '+' : '-';
1223
- output += spaces + typeChar + nodes.nameWithExtension() + '\n';
1224
- return output = _this.toAscii(nodes.collection, indentation + 1, output);
1225
- });
1226
- return output;
1227
- };
1228
-
1229
- Tree.prototype.getModelFromClick = function(e) {
1230
- /*
1231
- Internal: Look up a model based on the cid of the clicked view element.
1232
-
1233
- Returns the Node corresponding to the view element that the user clicked on.
1234
- */
1235
-
1236
- var cid;
1237
- e.stopPropagation();
1238
- this.menuView.$el.hide();
1239
- cid = $(e.currentTarget).data('cid');
1240
- return this.getModelByCid(cid);
1241
- };
1242
-
1243
- Tree.prototype._openDirectory = function(e) {
1244
- /*
1245
- Internal: Toggle the directory icon and display the contents of the clicked Directory.
1246
- */
1247
-
1248
- var model;
1249
- model = this.getModelFromClick(e);
1250
- return model.toggleOpen();
1251
- };
1252
-
1253
- Tree.prototype._openFile = function(e) {
1254
- /*
1255
- Internal: Trigger the 'openFile' event, passing in the file corresponding
1256
- to the view element that the user clicked.
1257
- */
1258
-
1259
- var model;
1260
- model = this.getModelFromClick(e);
1261
- return this.trigger('openFile', model);
1262
- };
1263
-
1264
- Tree.prototype.render = function() {
1265
- /*
1266
- Internal: Call render on each of the nodes underneath the root node.
1267
- Also calls sort on each of the subcollections.
1268
- */
1269
-
1270
- var _this = this;
1271
- this.root.collection.sort().each(function(node) {
1272
- var view;
1273
- node.collection.sort();
1274
- view = _this.findOrCreateView(node);
1275
- if (!view.model.get('hidden')) {
1276
- return _this.$el.append(view.render().$el);
1277
- }
1278
- });
1279
- return this;
1280
- };
1281
-
1282
- return Tree;
1283
-
1284
- })(Backbone.View);
1285
- });
1286
-
1287
- }).call(this);
1288
- (function() {
1289
-
1290
-
1291
-
1292
- }).call(this);
@@ -1 +0,0 @@
1
- #= require ./bone_tree