jqtree-rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +62 -0
- data/LICENSE +21 -0
- data/README.md +60 -0
- data/Rakefile +10 -0
- data/jqtree-rails.gemspec +22 -0
- data/lib/generators/jqtree/install/install_generator.rb +40 -0
- data/lib/jqtree-rails.rb +1 -0
- data/lib/jqtree/rails.rb +2 -0
- data/lib/jqtree/rails/engine.rb +6 -0
- data/lib/jqtree/rails/version.rb +6 -0
- data/vendor/assets/images/treeDownTriangleBlack.png +0 -0
- data/vendor/assets/images/treeRightTriangleBlack.png +0 -0
- data/vendor/assets/javascripts/tree.jquery.js +1551 -0
- data/vendor/assets/stylesheets/jqtree.css +135 -0
- metadata +87 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
inflection-js-rails (0.1.0)
|
5
|
+
railties (>= 3.2.0, < 5.0)
|
6
|
+
thor (~> 0.14)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
actionpack (3.2.3)
|
12
|
+
activemodel (= 3.2.3)
|
13
|
+
activesupport (= 3.2.3)
|
14
|
+
builder (~> 3.0.0)
|
15
|
+
erubis (~> 2.7.0)
|
16
|
+
journey (~> 1.0.1)
|
17
|
+
rack (~> 1.4.0)
|
18
|
+
rack-cache (~> 1.2)
|
19
|
+
rack-test (~> 0.6.1)
|
20
|
+
sprockets (~> 2.1.2)
|
21
|
+
activemodel (3.2.3)
|
22
|
+
activesupport (= 3.2.3)
|
23
|
+
builder (~> 3.0.0)
|
24
|
+
activesupport (3.2.3)
|
25
|
+
i18n (~> 0.6)
|
26
|
+
multi_json (~> 1.0)
|
27
|
+
builder (3.0.0)
|
28
|
+
erubis (2.7.0)
|
29
|
+
hike (1.2.1)
|
30
|
+
i18n (0.6.0)
|
31
|
+
journey (1.0.3)
|
32
|
+
json (1.6.6)
|
33
|
+
multi_json (1.2.0)
|
34
|
+
rack (1.4.1)
|
35
|
+
rack-cache (1.2)
|
36
|
+
rack (>= 0.4)
|
37
|
+
rack-ssl (1.3.2)
|
38
|
+
rack
|
39
|
+
rack-test (0.6.1)
|
40
|
+
rack (>= 1.0)
|
41
|
+
railties (3.2.3)
|
42
|
+
actionpack (= 3.2.3)
|
43
|
+
activesupport (= 3.2.3)
|
44
|
+
rack-ssl (~> 1.3.2)
|
45
|
+
rake (>= 0.8.7)
|
46
|
+
rdoc (~> 3.4)
|
47
|
+
thor (~> 0.14.6)
|
48
|
+
rake (0.9.2.2)
|
49
|
+
rdoc (3.12)
|
50
|
+
json (~> 1.4)
|
51
|
+
sprockets (2.1.2)
|
52
|
+
hike (~> 1.2)
|
53
|
+
rack (~> 1.0)
|
54
|
+
tilt (~> 1.1, != 1.3.0)
|
55
|
+
thor (0.14.6)
|
56
|
+
tilt (1.3.3)
|
57
|
+
|
58
|
+
PLATFORMS
|
59
|
+
ruby
|
60
|
+
|
61
|
+
DEPENDENCIES
|
62
|
+
inflection-js-rails!
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2010 Andre Arko
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# jqtree-rails
|
2
|
+
|
3
|
+
Adds [jqTree](https://github.com/mbraak/jqTree) to the Rails 3 asset pipeline.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
In your Gemfile, add this line:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem :assets do
|
11
|
+
gem 'jqtree-rails'
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
Now run `bundle install`.
|
16
|
+
|
17
|
+
### Rails 3.0
|
18
|
+
|
19
|
+
This gem adds a single generator to Rails 3, `jqtree:install`.
|
20
|
+
|
21
|
+
Running the generator will copy over the assets to your assets to your public directory.
|
22
|
+
|
23
|
+
### Rails 3.1 or greater
|
24
|
+
|
25
|
+
For Rails 3.1 and greater, the files will be added to the asset pipeline and available for you to use.
|
26
|
+
|
27
|
+
Simply the following to `app/assets/javascripts/application.js`:
|
28
|
+
|
29
|
+
//= require tree.jquery
|
30
|
+
|
31
|
+
And the following to `app/assets/stylesheets/application.css`:
|
32
|
+
|
33
|
+
/*
|
34
|
+
* require jqtree
|
35
|
+
*/
|
36
|
+
|
37
|
+
## saveState
|
38
|
+
|
39
|
+
To enable `saveState`, simply follow the installation instructions for [http://github.com/c00lryguy/jquery-cookie-rails](jquery-cookie-rails).
|
40
|
+
|
41
|
+
jqTree will detect `jquery.cookie.js` and will enable `saveState`.
|
42
|
+
|
43
|
+
## Props
|
44
|
+
|
45
|
+
I didn't write any of the Javascript included within jqTree.
|
46
|
+
All props goto [mbraak](https://github.com/mbraak).
|
47
|
+
|
48
|
+
## Contributing
|
49
|
+
|
50
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
51
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
52
|
+
* Fork the project
|
53
|
+
* Start a feature/bugfix branch
|
54
|
+
* Commit and push until you are happy with your contribution
|
55
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
56
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
57
|
+
|
58
|
+
## Copyright
|
59
|
+
|
60
|
+
Copyright (c) 2012 Ryan Lewis. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/jqtree/rails/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = File.basename(__FILE__, '.gemspec')
|
6
|
+
s.version = JqTree::Rails::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Ryan Scott Lewis"]
|
9
|
+
s.email = ["c00lryguy@gmail.com"]
|
10
|
+
s.homepage = "http://rubygems.org/gems/#{s.name}"
|
11
|
+
s.summary = "Use jqTree with Rails 3"
|
12
|
+
s.description = "This gem provides jqTree assets for your Rails 3 application."
|
13
|
+
|
14
|
+
s.required_rubygems_version = ">= 1.3.6"
|
15
|
+
|
16
|
+
s.add_dependency "railties", ">= 3.2.0", "< 5.0"
|
17
|
+
s.add_dependency "thor", "~> 0.14"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
21
|
+
s.require_path = 'lib'
|
22
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
# Supply generator for Rails 3.0.x or if asset pipeline is not enabled
|
4
|
+
if ::Rails.version < "3.1" || !::Rails.application.config.assets.enabled
|
5
|
+
module JqTree
|
6
|
+
module Generators
|
7
|
+
class InstallGenerator < ::Rails::Generators::Base
|
8
|
+
|
9
|
+
desc "This generator installs jqtree #{JqTree::Rails::JQTREE_VERSION}"
|
10
|
+
source_root File.expand_path('../../../../../vendor/assets', __FILE__)
|
11
|
+
|
12
|
+
def copy_jqtree
|
13
|
+
say_status("copying", "jqtree (#{JqTree::Rails::JQTREE_VERSION})", :green)
|
14
|
+
copy_file "javascripts/tree.jquery.js", "public/javascripts/tree.jquery.js"
|
15
|
+
copy_file "stylesheets/jqtree.css", "public/javascripts/jqtree.css"
|
16
|
+
copy_file "images/treeDownTriangleBlack.png", "public/images/treeDownTriangleBlack.png"
|
17
|
+
copy_file "images/treeRightTriangleBlack.png", "public/images/treeRightTriangleBlack.png"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
else
|
24
|
+
module JqTree
|
25
|
+
module Generators
|
26
|
+
class InstallGenerator < ::Rails::Generators::Base
|
27
|
+
desc "Just show instructions so people will know what to do when mistakenly using generator for Rails 3.1 apps"
|
28
|
+
|
29
|
+
def do_nothing
|
30
|
+
say_status("deprecated", "You are using Rails 3.1 or the asset pipeline enabled, so this generator is not needed.")
|
31
|
+
say_status("", "The necessary files are already in your asset pipeline.")
|
32
|
+
say_status("", "Just add `//= require tree.jquery` to your app/assets/javascripts/application.js")
|
33
|
+
say_status("", "and add `/* require jqtree */` to your app/assets/stylesheets/application.css")
|
34
|
+
say_status("", "If you do not want the asset pipeline enabled, you may turn it off in application.rb and re-run this generator.")
|
35
|
+
# ok, nothing
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/jqtree-rails.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'jqtree/rails'
|
data/lib/jqtree/rails.rb
ADDED
Binary file
|
Binary file
|
@@ -0,0 +1,1551 @@
|
|
1
|
+
// Generated by CoffeeScript 1.3.1
|
2
|
+
|
3
|
+
/*
|
4
|
+
Copyright 2012 Marco Braak
|
5
|
+
|
6
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
you may not use this file except in compliance with the License.
|
8
|
+
You may obtain a copy of the License at
|
9
|
+
|
10
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
|
12
|
+
Unless required by applicable law or agreed to in writing, software
|
13
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
See the License for the specific language governing permissions and
|
16
|
+
limitations under the License.
|
17
|
+
*/
|
18
|
+
|
19
|
+
|
20
|
+
(function() {
|
21
|
+
var $, BorderDropHint, DragElement, FolderElement, GhostDropHint, JqueryWidget, Json, MouseWidget, Node, NodeElement, Position, SimpleWidget, indexOf, toJson,
|
22
|
+
__slice = [].slice,
|
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
|
+
$ = this.jQuery;
|
27
|
+
|
28
|
+
SimpleWidget = (function() {
|
29
|
+
|
30
|
+
SimpleWidget.name = 'SimpleWidget';
|
31
|
+
|
32
|
+
SimpleWidget.prototype.defaults = {};
|
33
|
+
|
34
|
+
function SimpleWidget(el, options) {
|
35
|
+
this.$el = $(el);
|
36
|
+
this.options = $.extend({}, this.defaults, options);
|
37
|
+
this._init();
|
38
|
+
}
|
39
|
+
|
40
|
+
SimpleWidget.prototype.destroy = function() {
|
41
|
+
return this._deinit();
|
42
|
+
};
|
43
|
+
|
44
|
+
SimpleWidget.prototype._init = function() {
|
45
|
+
return null;
|
46
|
+
};
|
47
|
+
|
48
|
+
SimpleWidget.prototype._deinit = function() {
|
49
|
+
return null;
|
50
|
+
};
|
51
|
+
|
52
|
+
return SimpleWidget;
|
53
|
+
|
54
|
+
})();
|
55
|
+
|
56
|
+
SimpleWidget.register = function(widget_class, widget_name) {
|
57
|
+
var callFunction, createWidget, destroyWidget, getDataKey;
|
58
|
+
getDataKey = function() {
|
59
|
+
return "simple_widget_" + widget_name;
|
60
|
+
};
|
61
|
+
createWidget = function($el, options) {
|
62
|
+
var data_key;
|
63
|
+
data_key = getDataKey();
|
64
|
+
$el.each(function() {
|
65
|
+
var widget;
|
66
|
+
widget = new widget_class(this, options);
|
67
|
+
if (!$.data(this, data_key)) {
|
68
|
+
return $.data(this, data_key, widget);
|
69
|
+
}
|
70
|
+
});
|
71
|
+
return $el;
|
72
|
+
};
|
73
|
+
destroyWidget = function($el) {
|
74
|
+
var data_key;
|
75
|
+
data_key = getDataKey();
|
76
|
+
return $el.each(function() {
|
77
|
+
var widget;
|
78
|
+
widget = $.data(this, data_key);
|
79
|
+
if (widget && (widget instanceof SimpleWidget)) {
|
80
|
+
widget.destroy();
|
81
|
+
}
|
82
|
+
return $.removeData(this, data_key);
|
83
|
+
});
|
84
|
+
};
|
85
|
+
callFunction = function($el, function_name, args) {
|
86
|
+
var result;
|
87
|
+
result = null;
|
88
|
+
$el.each(function() {
|
89
|
+
var widget, widget_function;
|
90
|
+
widget = $.data(this, getDataKey());
|
91
|
+
if (widget && (widget instanceof SimpleWidget)) {
|
92
|
+
widget_function = widget[function_name];
|
93
|
+
if (widget_function && (typeof widget_function === 'function')) {
|
94
|
+
return result = widget_function.apply(widget, args);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
});
|
98
|
+
return result;
|
99
|
+
};
|
100
|
+
return $.fn[widget_name] = function() {
|
101
|
+
var $el, args, argument1, function_name, options;
|
102
|
+
argument1 = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
103
|
+
$el = this;
|
104
|
+
if (argument1 === void 0 || typeof argument1 === 'object') {
|
105
|
+
options = argument1;
|
106
|
+
return createWidget($el, options);
|
107
|
+
} else if (typeof argument1 === 'string' && argument1[0] !== '_') {
|
108
|
+
function_name = argument1;
|
109
|
+
if (function_name === 'destroy') {
|
110
|
+
return destroyWidget($el);
|
111
|
+
} else {
|
112
|
+
return callFunction($el, function_name, args);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
};
|
116
|
+
};
|
117
|
+
|
118
|
+
this.SimpleWidget = SimpleWidget;
|
119
|
+
|
120
|
+
/*
|
121
|
+
This widget does the same a the mouse widget in jqueryui.
|
122
|
+
*/
|
123
|
+
|
124
|
+
|
125
|
+
MouseWidget = (function(_super) {
|
126
|
+
|
127
|
+
__extends(MouseWidget, _super);
|
128
|
+
|
129
|
+
MouseWidget.name = 'MouseWidget';
|
130
|
+
|
131
|
+
function MouseWidget() {
|
132
|
+
return MouseWidget.__super__.constructor.apply(this, arguments);
|
133
|
+
}
|
134
|
+
|
135
|
+
MouseWidget.is_mouse_handled = false;
|
136
|
+
|
137
|
+
MouseWidget.prototype._init = function() {
|
138
|
+
this.$el.bind('mousedown', $.proxy(this._mouseDown, this));
|
139
|
+
return this.is_mouse_started = false;
|
140
|
+
};
|
141
|
+
|
142
|
+
MouseWidget.prototype._deinit = function() {
|
143
|
+
var $document;
|
144
|
+
this.$el.unbind('mousedown');
|
145
|
+
$document = $(document);
|
146
|
+
$document.unbind('mousemove');
|
147
|
+
return $document.unbind('mouseup');
|
148
|
+
};
|
149
|
+
|
150
|
+
MouseWidget.prototype._mouseDown = function(e) {
|
151
|
+
var $document;
|
152
|
+
if (MouseWidget.is_mouse_handled) {
|
153
|
+
return;
|
154
|
+
}
|
155
|
+
if (!this.is_mouse_started) {
|
156
|
+
this._mouseUp(e);
|
157
|
+
}
|
158
|
+
if (e.which !== 1) {
|
159
|
+
return;
|
160
|
+
}
|
161
|
+
if (!this._mouseCapture(e)) {
|
162
|
+
return;
|
163
|
+
}
|
164
|
+
this.mouse_down_event = e;
|
165
|
+
$document = $(document);
|
166
|
+
$document.bind('mousemove', $.proxy(this._mouseMove, this));
|
167
|
+
$document.bind('mouseup', $.proxy(this._mouseUp, this));
|
168
|
+
e.preventDefault();
|
169
|
+
this.is_mouse_handled = true;
|
170
|
+
return true;
|
171
|
+
};
|
172
|
+
|
173
|
+
MouseWidget.prototype._mouseMove = function(e) {
|
174
|
+
if (this.is_mouse_started) {
|
175
|
+
this._mouseDrag(e);
|
176
|
+
return e.preventDefault();
|
177
|
+
}
|
178
|
+
this.is_mouse_started = this._mouseStart(this.mouse_down_event) !== false;
|
179
|
+
if (this.is_mouse_started) {
|
180
|
+
this._mouseDrag(e);
|
181
|
+
} else {
|
182
|
+
this._mouseUp(e);
|
183
|
+
}
|
184
|
+
return !this.is_mouse_started;
|
185
|
+
};
|
186
|
+
|
187
|
+
MouseWidget.prototype._mouseUp = function(e) {
|
188
|
+
var $document;
|
189
|
+
$document = $(document);
|
190
|
+
$document.unbind('mousemove');
|
191
|
+
$document.unbind('mouseup');
|
192
|
+
if (this.is_mouse_started) {
|
193
|
+
this.is_mouse_started = false;
|
194
|
+
this._mouseStop(e);
|
195
|
+
}
|
196
|
+
return false;
|
197
|
+
};
|
198
|
+
|
199
|
+
MouseWidget.prototype._mouseCapture = function(e) {
|
200
|
+
return true;
|
201
|
+
};
|
202
|
+
|
203
|
+
MouseWidget.prototype._mouseStart = function(e) {
|
204
|
+
return null;
|
205
|
+
};
|
206
|
+
|
207
|
+
MouseWidget.prototype._mouseDrag = function(e) {
|
208
|
+
return null;
|
209
|
+
};
|
210
|
+
|
211
|
+
MouseWidget.prototype._mouseStop = function(e) {
|
212
|
+
return null;
|
213
|
+
};
|
214
|
+
|
215
|
+
return MouseWidget;
|
216
|
+
|
217
|
+
})(SimpleWidget);
|
218
|
+
|
219
|
+
/*
|
220
|
+
Copyright 2012 Marco Braak
|
221
|
+
|
222
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
223
|
+
you may not use this file except in compliance with the License.
|
224
|
+
You may obtain a copy of the License at
|
225
|
+
|
226
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
227
|
+
|
228
|
+
Unless required by applicable law or agreed to in writing, software
|
229
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
230
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
231
|
+
See the License for the specific language governing permissions and
|
232
|
+
limitations under the License.
|
233
|
+
*/
|
234
|
+
|
235
|
+
|
236
|
+
this.Tree = {};
|
237
|
+
|
238
|
+
$ = this.jQuery;
|
239
|
+
|
240
|
+
indexOf = function(array, item) {
|
241
|
+
var i, value, _i, _len;
|
242
|
+
if (array.indexOf) {
|
243
|
+
return array.indexOf(item);
|
244
|
+
} else {
|
245
|
+
for (i = _i = 0, _len = array.length; _i < _len; i = ++_i) {
|
246
|
+
value = array[i];
|
247
|
+
if (value === item) {
|
248
|
+
return i;
|
249
|
+
}
|
250
|
+
}
|
251
|
+
return -1;
|
252
|
+
}
|
253
|
+
};
|
254
|
+
|
255
|
+
this.Tree.indexOf = indexOf;
|
256
|
+
|
257
|
+
Json = {};
|
258
|
+
|
259
|
+
Json.escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
|
260
|
+
|
261
|
+
Json.meta = {
|
262
|
+
'\b': '\\b',
|
263
|
+
'\t': '\\t',
|
264
|
+
'\n': '\\n',
|
265
|
+
'\f': '\\f',
|
266
|
+
'\r': '\\r',
|
267
|
+
'"': '\\"',
|
268
|
+
'\\': '\\\\'
|
269
|
+
};
|
270
|
+
|
271
|
+
Json.quote = function(string) {
|
272
|
+
Json.escapable.lastIndex = 0;
|
273
|
+
if (Json.escapable.test(string)) {
|
274
|
+
return '"' + string.replace(Json.escapable, function(a) {
|
275
|
+
var c;
|
276
|
+
c = Json.meta[a];
|
277
|
+
return (typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4));
|
278
|
+
}) + '"';
|
279
|
+
} else {
|
280
|
+
return '"' + string + '"';
|
281
|
+
}
|
282
|
+
};
|
283
|
+
|
284
|
+
Json.str = function(key, holder) {
|
285
|
+
var i, k, partial, v, value, _i, _len;
|
286
|
+
value = holder[key];
|
287
|
+
if (value && typeof value === 'object' && typeof value.toJSON === 'function') {
|
288
|
+
value = value.toJSON(key);
|
289
|
+
}
|
290
|
+
switch (typeof value) {
|
291
|
+
case 'string':
|
292
|
+
return Json.quote(value);
|
293
|
+
case 'number':
|
294
|
+
if (isFinite(value)) {
|
295
|
+
return String(value);
|
296
|
+
} else {
|
297
|
+
return 'null';
|
298
|
+
}
|
299
|
+
case 'boolean':
|
300
|
+
case 'null':
|
301
|
+
return String(value);
|
302
|
+
case 'object':
|
303
|
+
if (!value) {
|
304
|
+
return 'null';
|
305
|
+
}
|
306
|
+
partial = [];
|
307
|
+
if (Object.prototype.toString.apply(value) === '[object Array]') {
|
308
|
+
for (i = _i = 0, _len = value.length; _i < _len; i = ++_i) {
|
309
|
+
v = value[i];
|
310
|
+
partial[i] = Json.str(i, value) || 'null';
|
311
|
+
}
|
312
|
+
return (partial.length === 0 ? '[]' : '[' + partial.join(',') + ']');
|
313
|
+
}
|
314
|
+
for (k in value) {
|
315
|
+
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
316
|
+
v = Json.str(k, value);
|
317
|
+
if (v) {
|
318
|
+
partial.push(Json.quote(k) + ':' + v);
|
319
|
+
}
|
320
|
+
}
|
321
|
+
}
|
322
|
+
return (partial.length === 0 ? '{}' : '{' + partial.join(',') + '}');
|
323
|
+
}
|
324
|
+
};
|
325
|
+
|
326
|
+
toJson = function(value) {
|
327
|
+
return Json.str('', {
|
328
|
+
'': value
|
329
|
+
});
|
330
|
+
};
|
331
|
+
|
332
|
+
this.Tree.toJson = toJson;
|
333
|
+
|
334
|
+
Position = {
|
335
|
+
getName: function(position) {
|
336
|
+
if (position === Position.BEFORE) {
|
337
|
+
return 'before';
|
338
|
+
} else if (position === Position.AFTER) {
|
339
|
+
return 'after';
|
340
|
+
} else if (position === Position.INSIDE) {
|
341
|
+
return 'inside';
|
342
|
+
} else {
|
343
|
+
return 'none';
|
344
|
+
}
|
345
|
+
}
|
346
|
+
};
|
347
|
+
|
348
|
+
Position.BEFORE = 1;
|
349
|
+
|
350
|
+
Position.AFTER = 2;
|
351
|
+
|
352
|
+
Position.INSIDE = 3;
|
353
|
+
|
354
|
+
Position.NONE = 4;
|
355
|
+
|
356
|
+
this.Tree.Position = Position;
|
357
|
+
|
358
|
+
Node = (function() {
|
359
|
+
|
360
|
+
Node.name = 'Node';
|
361
|
+
|
362
|
+
function Node(name) {
|
363
|
+
this.init(name);
|
364
|
+
}
|
365
|
+
|
366
|
+
Node.prototype.init = function(name) {
|
367
|
+
this.name = name;
|
368
|
+
this.children = [];
|
369
|
+
return this.parent = null;
|
370
|
+
};
|
371
|
+
|
372
|
+
Node.prototype.initFromData = function(data) {
|
373
|
+
var addChildren, addNode,
|
374
|
+
_this = this;
|
375
|
+
addNode = function(node_data) {
|
376
|
+
return $.each(node_data, function(key, value) {
|
377
|
+
if (key === 'children') {
|
378
|
+
addChildren(value);
|
379
|
+
} else if (key === 'label') {
|
380
|
+
_this['name'] = value;
|
381
|
+
} else {
|
382
|
+
_this[key] = value;
|
383
|
+
}
|
384
|
+
return true;
|
385
|
+
});
|
386
|
+
};
|
387
|
+
addChildren = function(children_data) {
|
388
|
+
var child, node, _i, _len, _results;
|
389
|
+
_results = [];
|
390
|
+
for (_i = 0, _len = children_data.length; _i < _len; _i++) {
|
391
|
+
child = children_data[_i];
|
392
|
+
node = new Node();
|
393
|
+
node.initFromData(child);
|
394
|
+
_results.push(_this.addChild(node));
|
395
|
+
}
|
396
|
+
return _results;
|
397
|
+
};
|
398
|
+
return addNode(data);
|
399
|
+
};
|
400
|
+
|
401
|
+
/*
|
402
|
+
Create tree from data.
|
403
|
+
|
404
|
+
Structure of data is:
|
405
|
+
[
|
406
|
+
{
|
407
|
+
label: 'node1',
|
408
|
+
children: [
|
409
|
+
{ label: 'child1' },
|
410
|
+
{ label: 'child2' }
|
411
|
+
]
|
412
|
+
},
|
413
|
+
{
|
414
|
+
label: 'node2'
|
415
|
+
}
|
416
|
+
]
|
417
|
+
*/
|
418
|
+
|
419
|
+
|
420
|
+
Node.prototype.loadFromData = function(data) {
|
421
|
+
var node, o, _i, _len, _results,
|
422
|
+
_this = this;
|
423
|
+
this.children = [];
|
424
|
+
_results = [];
|
425
|
+
for (_i = 0, _len = data.length; _i < _len; _i++) {
|
426
|
+
o = data[_i];
|
427
|
+
node = new Node(o.label);
|
428
|
+
$.each(o, function(key, value) {
|
429
|
+
if (key !== 'label') {
|
430
|
+
node[key] = value;
|
431
|
+
}
|
432
|
+
return true;
|
433
|
+
});
|
434
|
+
this.addChild(node);
|
435
|
+
if (o.children) {
|
436
|
+
_results.push(node.loadFromData(o.children));
|
437
|
+
} else {
|
438
|
+
_results.push(void 0);
|
439
|
+
}
|
440
|
+
}
|
441
|
+
return _results;
|
442
|
+
};
|
443
|
+
|
444
|
+
/*
|
445
|
+
Add child.
|
446
|
+
|
447
|
+
tree.addChild(
|
448
|
+
new Node('child1')
|
449
|
+
);
|
450
|
+
*/
|
451
|
+
|
452
|
+
|
453
|
+
Node.prototype.addChild = function(node) {
|
454
|
+
this.children.push(node);
|
455
|
+
return node.parent = this;
|
456
|
+
};
|
457
|
+
|
458
|
+
/*
|
459
|
+
Add child at position. Index starts at 0.
|
460
|
+
|
461
|
+
tree.addChildAtPosition(
|
462
|
+
new Node('abc'),
|
463
|
+
1
|
464
|
+
);
|
465
|
+
*/
|
466
|
+
|
467
|
+
|
468
|
+
Node.prototype.addChildAtPosition = function(node, index) {
|
469
|
+
this.children.splice(index, 0, node);
|
470
|
+
return node.parent = this;
|
471
|
+
};
|
472
|
+
|
473
|
+
/*
|
474
|
+
Remove child.
|
475
|
+
|
476
|
+
tree.removeChile(tree.children[0]);
|
477
|
+
*/
|
478
|
+
|
479
|
+
|
480
|
+
Node.prototype.removeChild = function(node) {
|
481
|
+
return this.children.splice(this.getChildIndex(node), 1);
|
482
|
+
};
|
483
|
+
|
484
|
+
/*
|
485
|
+
Get child index.
|
486
|
+
|
487
|
+
var index = getChildIndex(node);
|
488
|
+
*/
|
489
|
+
|
490
|
+
|
491
|
+
Node.prototype.getChildIndex = function(node) {
|
492
|
+
return $.inArray(node, this.children);
|
493
|
+
};
|
494
|
+
|
495
|
+
/*
|
496
|
+
Does the tree have children?
|
497
|
+
|
498
|
+
if (tree.hasChildren()) {
|
499
|
+
//
|
500
|
+
}
|
501
|
+
*/
|
502
|
+
|
503
|
+
|
504
|
+
Node.prototype.hasChildren = function() {
|
505
|
+
return this.children.length !== 0;
|
506
|
+
};
|
507
|
+
|
508
|
+
/*
|
509
|
+
Iterate over all the nodes in the tree.
|
510
|
+
|
511
|
+
Calls callback with (node, level).
|
512
|
+
|
513
|
+
The callback must return true to continue the iteration on current node.
|
514
|
+
|
515
|
+
tree.iterate(
|
516
|
+
function(node, level) {
|
517
|
+
console.log(node.name);
|
518
|
+
|
519
|
+
// stop iteration after level 2
|
520
|
+
return (level <= 2);
|
521
|
+
}
|
522
|
+
);
|
523
|
+
*/
|
524
|
+
|
525
|
+
|
526
|
+
Node.prototype.iterate = function(callback) {
|
527
|
+
var _iterate,
|
528
|
+
_this = this;
|
529
|
+
_iterate = function(level) {
|
530
|
+
var child, result, _i, _len, _ref, _results;
|
531
|
+
_ref = _this.children;
|
532
|
+
_results = [];
|
533
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
534
|
+
child = _ref[_i];
|
535
|
+
result = callback(child, level);
|
536
|
+
if (_this.hasChildren() && result) {
|
537
|
+
_results.push(child.iterate(callback, level + 1));
|
538
|
+
} else {
|
539
|
+
_results.push(void 0);
|
540
|
+
}
|
541
|
+
}
|
542
|
+
return _results;
|
543
|
+
};
|
544
|
+
return _iterate(0);
|
545
|
+
};
|
546
|
+
|
547
|
+
/*
|
548
|
+
Move node relative to another node.
|
549
|
+
|
550
|
+
Argument position: Position.BEFORE, Position.AFTER or Position.Inside
|
551
|
+
|
552
|
+
// move node1 after node2
|
553
|
+
tree.moveNode(node1, node2, Position.AFTER);
|
554
|
+
*/
|
555
|
+
|
556
|
+
|
557
|
+
Node.prototype.moveNode = function(moved_node, target_node, position) {
|
558
|
+
moved_node.parent.removeChild(moved_node);
|
559
|
+
if (position === Position.AFTER) {
|
560
|
+
return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node) + 1);
|
561
|
+
} else if (position === Position.BEFORE) {
|
562
|
+
return target_node.parent.addChildAtPosition(moved_node, target_node.parent.getChildIndex(target_node));
|
563
|
+
} else if (position === Position.INSIDE) {
|
564
|
+
return target_node.addChildAtPosition(moved_node, 0);
|
565
|
+
}
|
566
|
+
};
|
567
|
+
|
568
|
+
/*
|
569
|
+
Get the tree as data.
|
570
|
+
*/
|
571
|
+
|
572
|
+
|
573
|
+
Node.prototype.getData = function() {
|
574
|
+
var getDataFromNodes,
|
575
|
+
_this = this;
|
576
|
+
getDataFromNodes = function(nodes) {
|
577
|
+
var data, k, node, tmp_node, v, _i, _len;
|
578
|
+
data = [];
|
579
|
+
for (_i = 0, _len = nodes.length; _i < _len; _i++) {
|
580
|
+
node = nodes[_i];
|
581
|
+
tmp_node = {};
|
582
|
+
for (k in node) {
|
583
|
+
v = node[k];
|
584
|
+
if ((k !== 'parent' && k !== 'children' && k !== 'element') && Object.prototype.hasOwnProperty.call(node, k)) {
|
585
|
+
tmp_node[k] = v;
|
586
|
+
}
|
587
|
+
}
|
588
|
+
if (node.hasChildren()) {
|
589
|
+
tmp_node.children = getDataFromNodes(node.children);
|
590
|
+
}
|
591
|
+
data.push(tmp_node);
|
592
|
+
}
|
593
|
+
return data;
|
594
|
+
};
|
595
|
+
return getDataFromNodes(this.children);
|
596
|
+
};
|
597
|
+
|
598
|
+
return Node;
|
599
|
+
|
600
|
+
})();
|
601
|
+
|
602
|
+
this.Tree.Tree = Node;
|
603
|
+
|
604
|
+
JqueryWidget = (function(_super) {
|
605
|
+
|
606
|
+
__extends(JqueryWidget, _super);
|
607
|
+
|
608
|
+
JqueryWidget.name = 'JqueryWidget';
|
609
|
+
|
610
|
+
function JqueryWidget() {
|
611
|
+
return JqueryWidget.__super__.constructor.apply(this, arguments);
|
612
|
+
}
|
613
|
+
|
614
|
+
JqueryWidget.prototype.defaults = {
|
615
|
+
autoOpen: false,
|
616
|
+
saveState: false,
|
617
|
+
dragAndDrop: false,
|
618
|
+
selectable: false,
|
619
|
+
onCanSelectNode: null,
|
620
|
+
onSetStateFromStorage: null,
|
621
|
+
onGetStateFromStorage: null,
|
622
|
+
onCreateLi: null,
|
623
|
+
onIsMoveHandle: null,
|
624
|
+
onCanMove: null,
|
625
|
+
onCanMoveTo: null
|
626
|
+
};
|
627
|
+
|
628
|
+
JqueryWidget.prototype.toggle = function(node, on_finished) {
|
629
|
+
if (node.hasChildren()) {
|
630
|
+
new FolderElement(node).toggle(on_finished);
|
631
|
+
}
|
632
|
+
if (this.options.saveState) {
|
633
|
+
return this._saveState();
|
634
|
+
}
|
635
|
+
};
|
636
|
+
|
637
|
+
JqueryWidget.prototype.getTree = function() {
|
638
|
+
return this.tree;
|
639
|
+
};
|
640
|
+
|
641
|
+
JqueryWidget.prototype.selectNode = function(node, must_open_parents) {
|
642
|
+
var parent;
|
643
|
+
if (this.options.selectable) {
|
644
|
+
if (this.selected_node) {
|
645
|
+
this._getNodeElementForNode(this.selected_node).deselect();
|
646
|
+
}
|
647
|
+
this._getNodeElementForNode(node).select();
|
648
|
+
this.selected_node = node;
|
649
|
+
if (must_open_parents) {
|
650
|
+
parent = this.selected_node.parent;
|
651
|
+
while (parent) {
|
652
|
+
if (!parent.is_open) {
|
653
|
+
this.openNode(parent, null, true);
|
654
|
+
}
|
655
|
+
parent = parent.parent;
|
656
|
+
}
|
657
|
+
}
|
658
|
+
if (this.options.saveState) {
|
659
|
+
return this._saveState();
|
660
|
+
}
|
661
|
+
}
|
662
|
+
};
|
663
|
+
|
664
|
+
JqueryWidget.prototype.getSelectedNode = function() {
|
665
|
+
return this.selected_node || false;
|
666
|
+
};
|
667
|
+
|
668
|
+
JqueryWidget.prototype.toJson = function() {
|
669
|
+
return toJson(this.tree.getData());
|
670
|
+
};
|
671
|
+
|
672
|
+
JqueryWidget.prototype.loadData = function(data, parent_node) {
|
673
|
+
var $div, $element, child, subtree, _i, _len, _ref;
|
674
|
+
if (!parent_node) {
|
675
|
+
return this._initTree(data);
|
676
|
+
} else {
|
677
|
+
subtree = new Node();
|
678
|
+
subtree.loadFromData(data);
|
679
|
+
_ref = subtree.children;
|
680
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
681
|
+
child = _ref[_i];
|
682
|
+
parent_node.addChild(child);
|
683
|
+
}
|
684
|
+
$element = $(parent_node.element);
|
685
|
+
$element.children('ul').detach();
|
686
|
+
this._createDomElements(parent_node, $element);
|
687
|
+
$div = $element.children('div');
|
688
|
+
if (!$div.find('.toggler').length) {
|
689
|
+
return $div.prepend('<a class="toggler">»</a>');
|
690
|
+
}
|
691
|
+
}
|
692
|
+
};
|
693
|
+
|
694
|
+
JqueryWidget.prototype.getNodeById = function(node_id) {
|
695
|
+
var result;
|
696
|
+
result = null;
|
697
|
+
this.tree.iterate(function(node) {
|
698
|
+
if (node.id === node_id) {
|
699
|
+
result = node;
|
700
|
+
return false;
|
701
|
+
} else {
|
702
|
+
return true;
|
703
|
+
}
|
704
|
+
});
|
705
|
+
return result;
|
706
|
+
};
|
707
|
+
|
708
|
+
JqueryWidget.prototype.openNode = function(node, on_finished, skip_slide) {
|
709
|
+
if (node.hasChildren()) {
|
710
|
+
return new FolderElement(node).open(on_finished, skip_slide);
|
711
|
+
}
|
712
|
+
};
|
713
|
+
|
714
|
+
JqueryWidget.prototype._init = function() {
|
715
|
+
JqueryWidget.__super__._init.apply(this, arguments);
|
716
|
+
this.element = this.$el;
|
717
|
+
this._initTree(this.options.data);
|
718
|
+
this.element.click($.proxy(this._click, this));
|
719
|
+
this.element.bind('contextmenu', $.proxy(this._contextmenu, this));
|
720
|
+
this.hovered_area = null;
|
721
|
+
this.$ghost = null;
|
722
|
+
return this.hit_areas = [];
|
723
|
+
};
|
724
|
+
|
725
|
+
JqueryWidget.prototype._deinit = function() {
|
726
|
+
this.element.empty();
|
727
|
+
this.element.unbind();
|
728
|
+
this.tree = null;
|
729
|
+
return JqueryWidget.__super__._deinit.apply(this, arguments);
|
730
|
+
};
|
731
|
+
|
732
|
+
JqueryWidget.prototype._initTree = function(data) {
|
733
|
+
var node_element;
|
734
|
+
this.tree = new Node();
|
735
|
+
this.tree.loadFromData(data);
|
736
|
+
this.selected_node = null;
|
737
|
+
this._openNodes();
|
738
|
+
this._createDomElements(this.tree);
|
739
|
+
if (this.selected_node) {
|
740
|
+
node_element = this._getNodeElementForNode(this.selected_node);
|
741
|
+
if (node_element) {
|
742
|
+
return node_element.select();
|
743
|
+
}
|
744
|
+
}
|
745
|
+
};
|
746
|
+
|
747
|
+
JqueryWidget.prototype._openNodes = function() {
|
748
|
+
var max_level;
|
749
|
+
if (this.options.saveState) {
|
750
|
+
if (this._restoreState()) {
|
751
|
+
return;
|
752
|
+
}
|
753
|
+
}
|
754
|
+
if (this.options.autoOpen === false) {
|
755
|
+
return;
|
756
|
+
} else if (this.options.autoOpen === true) {
|
757
|
+
max_level = -1;
|
758
|
+
} else {
|
759
|
+
max_level = parseInt(this.options.autoOpen);
|
760
|
+
}
|
761
|
+
return this.tree.iterate(function(node, level) {
|
762
|
+
node.is_open = true;
|
763
|
+
return level !== max_level;
|
764
|
+
});
|
765
|
+
};
|
766
|
+
|
767
|
+
JqueryWidget.prototype._createDomElements = function(tree, $element) {
|
768
|
+
var createFolderLi, createLi, createNodeLi, createUl, depth, doCreateDomElements,
|
769
|
+
_this = this;
|
770
|
+
createUl = function(depth, is_open) {
|
771
|
+
var class_string;
|
772
|
+
if (depth) {
|
773
|
+
class_string = '';
|
774
|
+
} else {
|
775
|
+
class_string = ' class="tree"';
|
776
|
+
}
|
777
|
+
return $("<ul" + class_string + "></ul>");
|
778
|
+
};
|
779
|
+
createLi = function(node) {
|
780
|
+
var $li;
|
781
|
+
if (node.hasChildren()) {
|
782
|
+
$li = createFolderLi(node);
|
783
|
+
} else {
|
784
|
+
$li = createNodeLi(node);
|
785
|
+
}
|
786
|
+
if (_this.options.onCreateLi) {
|
787
|
+
_this.options.onCreateLi(node, $li);
|
788
|
+
}
|
789
|
+
return $li;
|
790
|
+
};
|
791
|
+
createNodeLi = function(node) {
|
792
|
+
return $("<li><div><span class=\"title\">" + node.name + "</span></div></li>");
|
793
|
+
};
|
794
|
+
createFolderLi = function(node) {
|
795
|
+
var button_class, folder_class, getButtonClass, getFolderClass;
|
796
|
+
getButtonClass = function() {
|
797
|
+
var classes;
|
798
|
+
classes = ['toggler'];
|
799
|
+
if (!node.is_open) {
|
800
|
+
classes.push('closed');
|
801
|
+
}
|
802
|
+
return classes.join(' ');
|
803
|
+
};
|
804
|
+
getFolderClass = function() {
|
805
|
+
var classes;
|
806
|
+
classes = ['folder'];
|
807
|
+
if (!node.is_open) {
|
808
|
+
classes.push('closed');
|
809
|
+
}
|
810
|
+
return classes.join(' ');
|
811
|
+
};
|
812
|
+
button_class = getButtonClass();
|
813
|
+
folder_class = getFolderClass();
|
814
|
+
return $("<li class=\"" + folder_class + "\"><div><a class=\"" + button_class + "\">»</a><span class=\"title\">" + node.name + "</span></div></li>");
|
815
|
+
};
|
816
|
+
doCreateDomElements = function($element, children, depth, is_open) {
|
817
|
+
var $li, $ul, child, _i, _len, _results;
|
818
|
+
$ul = createUl(depth, is_open);
|
819
|
+
$element.append($ul);
|
820
|
+
_results = [];
|
821
|
+
for (_i = 0, _len = children.length; _i < _len; _i++) {
|
822
|
+
child = children[_i];
|
823
|
+
$li = createLi(child);
|
824
|
+
$ul.append($li);
|
825
|
+
child.element = $li[0];
|
826
|
+
$li.data('node', child);
|
827
|
+
if (child.hasChildren()) {
|
828
|
+
_results.push(doCreateDomElements($li, child.children, depth + 1, child.is_open));
|
829
|
+
} else {
|
830
|
+
_results.push(void 0);
|
831
|
+
}
|
832
|
+
}
|
833
|
+
return _results;
|
834
|
+
};
|
835
|
+
if ($element) {
|
836
|
+
depth = 1;
|
837
|
+
} else {
|
838
|
+
$element = this.element;
|
839
|
+
$element.empty();
|
840
|
+
depth = 0;
|
841
|
+
}
|
842
|
+
return doCreateDomElements($element, tree.children, depth, true);
|
843
|
+
};
|
844
|
+
|
845
|
+
JqueryWidget.prototype._click = function(e) {
|
846
|
+
var $target, event, node, node_element,
|
847
|
+
_this = this;
|
848
|
+
if (e.ctrlKey) {
|
849
|
+
return;
|
850
|
+
}
|
851
|
+
$target = $(e.target);
|
852
|
+
if ($target.is('.toggler')) {
|
853
|
+
node_element = this._getNodeElement($target);
|
854
|
+
if (node_element && node_element.node.hasChildren()) {
|
855
|
+
node_element.toggle(function() {
|
856
|
+
var event, event_name, node;
|
857
|
+
node = node_element.node;
|
858
|
+
if (node.is_open) {
|
859
|
+
event_name = 'tree.open';
|
860
|
+
} else {
|
861
|
+
event_name = 'tree.close';
|
862
|
+
}
|
863
|
+
event = $.Event(event_name);
|
864
|
+
event.node = node;
|
865
|
+
return _this.element.trigger(event);
|
866
|
+
});
|
867
|
+
if (this.options.saveState) {
|
868
|
+
this._saveState();
|
869
|
+
}
|
870
|
+
e.preventDefault();
|
871
|
+
return e.stopPropagation();
|
872
|
+
}
|
873
|
+
} else if ($target.is('div') || $target.is('span')) {
|
874
|
+
node = this._getNode($target);
|
875
|
+
if (node) {
|
876
|
+
if ((!this.options.onCanSelectNode) || this.options.onCanSelectNode(node)) {
|
877
|
+
this.selectNode(node);
|
878
|
+
event = $.Event('tree.click');
|
879
|
+
event.node = node;
|
880
|
+
return this.element.trigger(event);
|
881
|
+
}
|
882
|
+
}
|
883
|
+
}
|
884
|
+
};
|
885
|
+
|
886
|
+
JqueryWidget.prototype._getNode = function($element) {
|
887
|
+
var $li;
|
888
|
+
$li = $element.closest('li');
|
889
|
+
if ($li.length === 0) {
|
890
|
+
return null;
|
891
|
+
} else {
|
892
|
+
return $li.data('node');
|
893
|
+
}
|
894
|
+
};
|
895
|
+
|
896
|
+
JqueryWidget.prototype._restoreState = function() {
|
897
|
+
var state;
|
898
|
+
if (this.options.onGetStateFromStorage) {
|
899
|
+
state = this.options.onGetStateFromStorage();
|
900
|
+
} else {
|
901
|
+
if ($.cookie) {
|
902
|
+
state = $.cookie(this._getCookieName(), {
|
903
|
+
path: '/'
|
904
|
+
});
|
905
|
+
} else {
|
906
|
+
state = null;
|
907
|
+
}
|
908
|
+
}
|
909
|
+
if (!state) {
|
910
|
+
return false;
|
911
|
+
} else {
|
912
|
+
this._setState(state);
|
913
|
+
return true;
|
914
|
+
}
|
915
|
+
};
|
916
|
+
|
917
|
+
JqueryWidget.prototype._saveState = function() {
|
918
|
+
if (this.options.onSetStateFromStorage) {
|
919
|
+
return this.options.onSetStateFromStorage(this._getState());
|
920
|
+
} else {
|
921
|
+
if ($.cookie) {
|
922
|
+
return $.cookie(this._getCookieName(), this._getState(), {
|
923
|
+
path: '/'
|
924
|
+
});
|
925
|
+
}
|
926
|
+
}
|
927
|
+
};
|
928
|
+
|
929
|
+
JqueryWidget.prototype._getState = function() {
|
930
|
+
var open_nodes, selected_node,
|
931
|
+
_this = this;
|
932
|
+
open_nodes = [];
|
933
|
+
this.tree.iterate(function(node) {
|
934
|
+
if (node.is_open && node.id && node.hasChildren()) {
|
935
|
+
open_nodes.push(node.id);
|
936
|
+
}
|
937
|
+
return true;
|
938
|
+
});
|
939
|
+
selected_node = '';
|
940
|
+
if (this.selected_node) {
|
941
|
+
selected_node = this.selected_node.id;
|
942
|
+
}
|
943
|
+
return toJson({
|
944
|
+
open_nodes: open_nodes,
|
945
|
+
selected_node: selected_node
|
946
|
+
});
|
947
|
+
};
|
948
|
+
|
949
|
+
JqueryWidget.prototype._setState = function(state) {
|
950
|
+
var data, open_nodes, selected_node_id,
|
951
|
+
_this = this;
|
952
|
+
data = $.parseJSON(state);
|
953
|
+
open_nodes = data.open_nodes;
|
954
|
+
selected_node_id = data.selected_node;
|
955
|
+
return this.tree.iterate(function(node) {
|
956
|
+
if (node.id && node.hasChildren() && (indexOf(open_nodes, node.id) >= 0)) {
|
957
|
+
node.is_open = true;
|
958
|
+
}
|
959
|
+
if (selected_node_id && (node.id === selected_node_id)) {
|
960
|
+
_this.selected_node = node;
|
961
|
+
}
|
962
|
+
return true;
|
963
|
+
});
|
964
|
+
};
|
965
|
+
|
966
|
+
JqueryWidget.prototype._getCookieName = function() {
|
967
|
+
if (typeof this.options.saveState === 'string') {
|
968
|
+
return this.options.saveState;
|
969
|
+
} else {
|
970
|
+
return 'tree';
|
971
|
+
}
|
972
|
+
};
|
973
|
+
|
974
|
+
JqueryWidget.prototype._getNodeElementForNode = function(node) {
|
975
|
+
if (node.hasChildren()) {
|
976
|
+
return new FolderElement(node);
|
977
|
+
} else {
|
978
|
+
return new NodeElement(node);
|
979
|
+
}
|
980
|
+
};
|
981
|
+
|
982
|
+
JqueryWidget.prototype._getNodeElement = function($element) {
|
983
|
+
var node;
|
984
|
+
node = this._getNode($element);
|
985
|
+
if (node) {
|
986
|
+
return this._getNodeElementForNode(node);
|
987
|
+
} else {
|
988
|
+
return null;
|
989
|
+
}
|
990
|
+
};
|
991
|
+
|
992
|
+
JqueryWidget.prototype._contextmenu = function(e) {
|
993
|
+
var $div, event, node;
|
994
|
+
$div = $(e.target).closest('ul.tree div');
|
995
|
+
if ($div.length) {
|
996
|
+
node = this._getNode($div);
|
997
|
+
if (node) {
|
998
|
+
e.preventDefault();
|
999
|
+
e.stopPropagation();
|
1000
|
+
event = $.Event('tree.contextmenu');
|
1001
|
+
event.node = node;
|
1002
|
+
event.click_event = e;
|
1003
|
+
this.element.trigger(event);
|
1004
|
+
return false;
|
1005
|
+
}
|
1006
|
+
}
|
1007
|
+
};
|
1008
|
+
|
1009
|
+
JqueryWidget.prototype._mouseCapture = function(event) {
|
1010
|
+
var $element, node_element;
|
1011
|
+
if (!this.options.dragAndDrop) {
|
1012
|
+
return;
|
1013
|
+
}
|
1014
|
+
$element = $(event.target);
|
1015
|
+
if (this.options.onIsMoveHandle && !this.options.onIsMoveHandle($element)) {
|
1016
|
+
return null;
|
1017
|
+
}
|
1018
|
+
node_element = this._getNodeElement($(event.target));
|
1019
|
+
if (node_element && this.options.onCanMove) {
|
1020
|
+
if (!this.options.onCanMove(node_element.node)) {
|
1021
|
+
node_element = null;
|
1022
|
+
}
|
1023
|
+
}
|
1024
|
+
this.current_item = node_element;
|
1025
|
+
return this.current_item !== null;
|
1026
|
+
};
|
1027
|
+
|
1028
|
+
JqueryWidget.prototype._mouseStart = function(event) {
|
1029
|
+
var offsetX, offsetY, _ref;
|
1030
|
+
if (!this.options.dragAndDrop) {
|
1031
|
+
return;
|
1032
|
+
}
|
1033
|
+
this._refreshHitAreas();
|
1034
|
+
_ref = this._getOffsetFromEvent(event), offsetX = _ref[0], offsetY = _ref[1];
|
1035
|
+
this.drag_element = new DragElement(this.current_item.node, offsetX, offsetY, this.element);
|
1036
|
+
this.current_item.$element.addClass('moving');
|
1037
|
+
return true;
|
1038
|
+
};
|
1039
|
+
|
1040
|
+
JqueryWidget.prototype._mouseDrag = function(event) {
|
1041
|
+
var area, position_name;
|
1042
|
+
if (!this.options.dragAndDrop) {
|
1043
|
+
return;
|
1044
|
+
}
|
1045
|
+
this.drag_element.move(event.pageX, event.pageY);
|
1046
|
+
area = this._findHoveredArea(event.pageX, event.pageY);
|
1047
|
+
if (area && this.options.onCanMoveTo) {
|
1048
|
+
position_name = Position.getName(area.position);
|
1049
|
+
if (!this.options.onCanMoveTo(this.current_item.node, area.node, position_name)) {
|
1050
|
+
area = null;
|
1051
|
+
}
|
1052
|
+
}
|
1053
|
+
if (!area) {
|
1054
|
+
this._removeDropHint();
|
1055
|
+
this._removeHover();
|
1056
|
+
this._stopOpenFolderTimer();
|
1057
|
+
} else {
|
1058
|
+
if (this.hovered_area !== area) {
|
1059
|
+
this.hovered_area = area;
|
1060
|
+
this._updateDropHint();
|
1061
|
+
}
|
1062
|
+
}
|
1063
|
+
return true;
|
1064
|
+
};
|
1065
|
+
|
1066
|
+
JqueryWidget.prototype._mouseStop = function() {
|
1067
|
+
if (!this.options.dragAndDrop) {
|
1068
|
+
return;
|
1069
|
+
}
|
1070
|
+
this._moveItem();
|
1071
|
+
this._clear();
|
1072
|
+
this._removeHover();
|
1073
|
+
this._removeDropHint();
|
1074
|
+
this._removeHitAreas();
|
1075
|
+
this.current_item.$element.removeClass('moving');
|
1076
|
+
return false;
|
1077
|
+
};
|
1078
|
+
|
1079
|
+
JqueryWidget.prototype._refreshHitAreas = function() {
|
1080
|
+
this._removeHitAreas();
|
1081
|
+
return this._generateHitAreas();
|
1082
|
+
};
|
1083
|
+
|
1084
|
+
JqueryWidget.prototype._generateHitAreas = function() {
|
1085
|
+
var addPosition, getTop, groupPositions, handleAfterOpenFolder, handleClosedFolder, handleFirstNode, handleNode, handleOpenFolder, hit_areas, last_top, positions,
|
1086
|
+
_this = this;
|
1087
|
+
positions = [];
|
1088
|
+
last_top = 0;
|
1089
|
+
getTop = function($element) {
|
1090
|
+
return $element.offset().top;
|
1091
|
+
};
|
1092
|
+
addPosition = function(node, position, top) {
|
1093
|
+
positions.push({
|
1094
|
+
top: top,
|
1095
|
+
node: node,
|
1096
|
+
position: position
|
1097
|
+
});
|
1098
|
+
return last_top = top;
|
1099
|
+
};
|
1100
|
+
groupPositions = function(handle_group) {
|
1101
|
+
var group, position, previous_top, _i, _len;
|
1102
|
+
previous_top = -1;
|
1103
|
+
group = [];
|
1104
|
+
for (_i = 0, _len = positions.length; _i < _len; _i++) {
|
1105
|
+
position = positions[_i];
|
1106
|
+
if (position.top !== previous_top) {
|
1107
|
+
if (group.length) {
|
1108
|
+
handle_group(group, previous_top, position.top);
|
1109
|
+
}
|
1110
|
+
previous_top = position.top;
|
1111
|
+
group = [];
|
1112
|
+
}
|
1113
|
+
group.push(position);
|
1114
|
+
}
|
1115
|
+
return handle_group(group, previous_top, _this.element.offset().top + _this.element.height());
|
1116
|
+
};
|
1117
|
+
handleNode = function(node, next_node, $element) {
|
1118
|
+
var top;
|
1119
|
+
top = getTop($element);
|
1120
|
+
if (node === _this.current_item.node) {
|
1121
|
+
addPosition(node, Position.NONE, top);
|
1122
|
+
} else {
|
1123
|
+
addPosition(node, Position.INSIDE, top);
|
1124
|
+
}
|
1125
|
+
if (next_node === _this.current_item.node || node === _this.current_item.node) {
|
1126
|
+
return addPosition(node, Position.NONE, top);
|
1127
|
+
} else {
|
1128
|
+
return addPosition(node, Position.AFTER, top);
|
1129
|
+
}
|
1130
|
+
};
|
1131
|
+
handleOpenFolder = function(node, $element) {
|
1132
|
+
if (node === _this.current_item.node) {
|
1133
|
+
return false;
|
1134
|
+
}
|
1135
|
+
if (node.children[0] !== _this.current_item.node) {
|
1136
|
+
addPosition(node, Position.INSIDE, getTop($element));
|
1137
|
+
}
|
1138
|
+
return true;
|
1139
|
+
};
|
1140
|
+
handleAfterOpenFolder = function(node, next_node, $element) {
|
1141
|
+
if (node === _this.current_item.node || next_node === _this.current_item.node) {
|
1142
|
+
return addPosition(node, Position.NONE, last_top);
|
1143
|
+
} else {
|
1144
|
+
return addPosition(node, Position.AFTER, last_top);
|
1145
|
+
}
|
1146
|
+
};
|
1147
|
+
handleClosedFolder = function(node, next_node, $element) {
|
1148
|
+
var top;
|
1149
|
+
top = getTop($element);
|
1150
|
+
if (node === _this.current_item.node) {
|
1151
|
+
return addPosition(node, Position.NONE, top);
|
1152
|
+
} else {
|
1153
|
+
addPosition(node, Position.INSIDE, top);
|
1154
|
+
if (next_node !== _this.current_item.node) {
|
1155
|
+
return addPosition(node, Position.AFTER, top);
|
1156
|
+
}
|
1157
|
+
}
|
1158
|
+
};
|
1159
|
+
handleFirstNode = function(node, $element) {
|
1160
|
+
if (node !== _this.current_item.node) {
|
1161
|
+
return addPosition(node, Position.BEFORE, getTop($(node.element)));
|
1162
|
+
}
|
1163
|
+
};
|
1164
|
+
this._iterateVisibleNodes(handleNode, handleOpenFolder, handleClosedFolder, handleAfterOpenFolder, handleFirstNode);
|
1165
|
+
hit_areas = [];
|
1166
|
+
groupPositions(function(positions_in_group, top, bottom) {
|
1167
|
+
var area_height, area_top, position, _i, _len, _results;
|
1168
|
+
area_height = (bottom - top) / positions_in_group.length;
|
1169
|
+
area_top = top;
|
1170
|
+
_results = [];
|
1171
|
+
for (_i = 0, _len = positions_in_group.length; _i < _len; _i++) {
|
1172
|
+
position = positions_in_group[_i];
|
1173
|
+
hit_areas.push({
|
1174
|
+
top: area_top,
|
1175
|
+
bottom: area_top + area_height,
|
1176
|
+
node: position.node,
|
1177
|
+
position: position.position
|
1178
|
+
});
|
1179
|
+
_results.push(area_top += area_height);
|
1180
|
+
}
|
1181
|
+
return _results;
|
1182
|
+
});
|
1183
|
+
return this.hit_areas = hit_areas;
|
1184
|
+
};
|
1185
|
+
|
1186
|
+
JqueryWidget.prototype._removeHitAreas = function() {
|
1187
|
+
return this.hit_areas = [];
|
1188
|
+
};
|
1189
|
+
|
1190
|
+
JqueryWidget.prototype._iterateVisibleNodes = function(handle_node, handle_open_folder, handle_closed_folder, handle_after_open_folder, handle_first_node) {
|
1191
|
+
var is_first_node, iterate,
|
1192
|
+
_this = this;
|
1193
|
+
is_first_node = true;
|
1194
|
+
iterate = function(node, next_node) {
|
1195
|
+
var $element, child, children_length, i, must_iterate_inside, _i, _len, _ref;
|
1196
|
+
must_iterate_inside = (node.is_open || !node.element) && node.hasChildren();
|
1197
|
+
if (node.element) {
|
1198
|
+
$element = $(node.element);
|
1199
|
+
if (!$element.is(':visible')) {
|
1200
|
+
return;
|
1201
|
+
}
|
1202
|
+
if (is_first_node) {
|
1203
|
+
handle_first_node(node, $element);
|
1204
|
+
is_first_node = false;
|
1205
|
+
}
|
1206
|
+
if (!node.hasChildren()) {
|
1207
|
+
handle_node(node, next_node, $element);
|
1208
|
+
} else if (node.is_open) {
|
1209
|
+
if (!handle_open_folder(node, $element)) {
|
1210
|
+
must_iterate_inside = false;
|
1211
|
+
}
|
1212
|
+
} else {
|
1213
|
+
handle_closed_folder(node, next_node, $element);
|
1214
|
+
}
|
1215
|
+
}
|
1216
|
+
if (must_iterate_inside) {
|
1217
|
+
children_length = node.children.length;
|
1218
|
+
_ref = node.children;
|
1219
|
+
for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
|
1220
|
+
child = _ref[i];
|
1221
|
+
if (i === (children_length - 1)) {
|
1222
|
+
iterate(node.children[i], null);
|
1223
|
+
} else {
|
1224
|
+
iterate(node.children[i], node.children[i + 1]);
|
1225
|
+
}
|
1226
|
+
}
|
1227
|
+
if (node.is_open) {
|
1228
|
+
return handle_after_open_folder(node, next_node, $element);
|
1229
|
+
}
|
1230
|
+
}
|
1231
|
+
};
|
1232
|
+
return iterate(this.tree);
|
1233
|
+
};
|
1234
|
+
|
1235
|
+
JqueryWidget.prototype._getOffsetFromEvent = function(event) {
|
1236
|
+
var element_offset;
|
1237
|
+
element_offset = $(event.target).offset();
|
1238
|
+
return [event.pageX - element_offset.left, event.pageY - element_offset.top];
|
1239
|
+
};
|
1240
|
+
|
1241
|
+
JqueryWidget.prototype._findHoveredArea = function(x, y) {
|
1242
|
+
var area, high, low, mid, tree_offset;
|
1243
|
+
tree_offset = this.element.offset();
|
1244
|
+
if (x < tree_offset.left || y < tree_offset.top || x > (tree_offset.left + this.element.width()) || y > (tree_offset.top + this.element.height())) {
|
1245
|
+
return null;
|
1246
|
+
}
|
1247
|
+
low = 0;
|
1248
|
+
high = this.hit_areas.length;
|
1249
|
+
while (low < high) {
|
1250
|
+
mid = (low + high) >> 1;
|
1251
|
+
area = this.hit_areas[mid];
|
1252
|
+
if (y < area.top) {
|
1253
|
+
high = mid;
|
1254
|
+
} else if (y > area.bottom) {
|
1255
|
+
low = mid + 1;
|
1256
|
+
} else {
|
1257
|
+
return area;
|
1258
|
+
}
|
1259
|
+
}
|
1260
|
+
return null;
|
1261
|
+
};
|
1262
|
+
|
1263
|
+
JqueryWidget.prototype._updateDropHint = function() {
|
1264
|
+
var node, node_element;
|
1265
|
+
this._stopOpenFolderTimer();
|
1266
|
+
if (!this.hovered_area) {
|
1267
|
+
return;
|
1268
|
+
}
|
1269
|
+
node = this.hovered_area.node;
|
1270
|
+
if (node.hasChildren() && !node.is_open && this.hovered_area.position === Position.INSIDE) {
|
1271
|
+
this._startOpenFolderTimer(node);
|
1272
|
+
}
|
1273
|
+
this._removeDropHint();
|
1274
|
+
node_element = this._getNodeElementForNode(this.hovered_area.node);
|
1275
|
+
return this.previous_ghost = node_element.addDropHint(this.hovered_area.position);
|
1276
|
+
};
|
1277
|
+
|
1278
|
+
JqueryWidget.prototype._startOpenFolderTimer = function(folder) {
|
1279
|
+
var openFolder,
|
1280
|
+
_this = this;
|
1281
|
+
openFolder = function() {
|
1282
|
+
return _this._getNodeElementForNode(folder).open(function() {
|
1283
|
+
_this._refreshHitAreas();
|
1284
|
+
return _this._updateDropHint();
|
1285
|
+
});
|
1286
|
+
};
|
1287
|
+
return this.open_folder_timer = setTimeout(openFolder, 500);
|
1288
|
+
};
|
1289
|
+
|
1290
|
+
JqueryWidget.prototype._stopOpenFolderTimer = function() {
|
1291
|
+
if (this.open_folder_timer) {
|
1292
|
+
clearTimeout(this.open_folder_timer);
|
1293
|
+
return this.open_folder_timer = null;
|
1294
|
+
}
|
1295
|
+
};
|
1296
|
+
|
1297
|
+
JqueryWidget.prototype._removeDropHint = function() {
|
1298
|
+
if (this.previous_ghost) {
|
1299
|
+
return this.previous_ghost.remove();
|
1300
|
+
}
|
1301
|
+
};
|
1302
|
+
|
1303
|
+
JqueryWidget.prototype._removeHover = function() {
|
1304
|
+
return this.hovered_area = null;
|
1305
|
+
};
|
1306
|
+
|
1307
|
+
JqueryWidget.prototype._moveItem = function() {
|
1308
|
+
var event, moved_node, position, previous_parent, target_node;
|
1309
|
+
if (this.hovered_area && this.hovered_area.position !== Position.NONE) {
|
1310
|
+
moved_node = this.current_item.node;
|
1311
|
+
target_node = this.hovered_area.node;
|
1312
|
+
position = this.hovered_area.position;
|
1313
|
+
previous_parent = moved_node.parent;
|
1314
|
+
this.tree.moveNode(moved_node, target_node, position);
|
1315
|
+
if (position === Position.INSIDE) {
|
1316
|
+
this.hovered_area.node.is_open = true;
|
1317
|
+
}
|
1318
|
+
event = $.Event('tree.move');
|
1319
|
+
event.move_info = {
|
1320
|
+
moved_node: moved_node,
|
1321
|
+
target_node: target_node,
|
1322
|
+
position: Position.getName(position),
|
1323
|
+
previous_parent: previous_parent
|
1324
|
+
};
|
1325
|
+
this.element.trigger(event);
|
1326
|
+
this.element.empty();
|
1327
|
+
return this._createDomElements(this.tree);
|
1328
|
+
}
|
1329
|
+
};
|
1330
|
+
|
1331
|
+
JqueryWidget.prototype._clear = function() {
|
1332
|
+
this.drag_element.remove();
|
1333
|
+
return this.drag_element = null;
|
1334
|
+
};
|
1335
|
+
|
1336
|
+
return JqueryWidget;
|
1337
|
+
|
1338
|
+
})(MouseWidget);
|
1339
|
+
|
1340
|
+
SimpleWidget.register(JqueryWidget, 'tree');
|
1341
|
+
|
1342
|
+
GhostDropHint = (function() {
|
1343
|
+
|
1344
|
+
GhostDropHint.name = 'GhostDropHint';
|
1345
|
+
|
1346
|
+
function GhostDropHint(node, $element, position) {
|
1347
|
+
this.$element = $element;
|
1348
|
+
this.node = node;
|
1349
|
+
this.$ghost = $('<li class="ghost"><span class="circle"></span><span class="line"></span></li>');
|
1350
|
+
if (position === Position.AFTER) {
|
1351
|
+
this.moveAfter();
|
1352
|
+
} else if (position === Position.BEFORE) {
|
1353
|
+
this.moveBefore();
|
1354
|
+
} else if (position === Position.INSIDE) {
|
1355
|
+
if (node.hasChildren() && node.is_open) {
|
1356
|
+
this.moveInsideOpenFolder();
|
1357
|
+
} else {
|
1358
|
+
this.moveInside();
|
1359
|
+
}
|
1360
|
+
}
|
1361
|
+
}
|
1362
|
+
|
1363
|
+
GhostDropHint.prototype.remove = function() {
|
1364
|
+
return this.$ghost.remove();
|
1365
|
+
};
|
1366
|
+
|
1367
|
+
GhostDropHint.prototype.moveAfter = function() {
|
1368
|
+
return this.$element.after(this.$ghost);
|
1369
|
+
};
|
1370
|
+
|
1371
|
+
GhostDropHint.prototype.moveBefore = function() {
|
1372
|
+
return this.$element.before(this.$ghost);
|
1373
|
+
};
|
1374
|
+
|
1375
|
+
GhostDropHint.prototype.moveInsideOpenFolder = function() {
|
1376
|
+
return $(this.node.children[0].element).before(this.$ghost);
|
1377
|
+
};
|
1378
|
+
|
1379
|
+
GhostDropHint.prototype.moveInside = function() {
|
1380
|
+
this.$element.after(this.$ghost);
|
1381
|
+
return this.$ghost.addClass('inside');
|
1382
|
+
};
|
1383
|
+
|
1384
|
+
return GhostDropHint;
|
1385
|
+
|
1386
|
+
})();
|
1387
|
+
|
1388
|
+
BorderDropHint = (function() {
|
1389
|
+
|
1390
|
+
BorderDropHint.name = 'BorderDropHint';
|
1391
|
+
|
1392
|
+
function BorderDropHint($element) {
|
1393
|
+
var $div, width;
|
1394
|
+
$div = $element.children('div');
|
1395
|
+
width = $element.width() - 4;
|
1396
|
+
this.$hint = $('<span class="border"></span>');
|
1397
|
+
$div.append(this.$hint);
|
1398
|
+
this.$hint.css({
|
1399
|
+
width: width,
|
1400
|
+
height: $div.height() - 4
|
1401
|
+
});
|
1402
|
+
}
|
1403
|
+
|
1404
|
+
BorderDropHint.prototype.remove = function() {
|
1405
|
+
return this.$hint.remove();
|
1406
|
+
};
|
1407
|
+
|
1408
|
+
return BorderDropHint;
|
1409
|
+
|
1410
|
+
})();
|
1411
|
+
|
1412
|
+
NodeElement = (function() {
|
1413
|
+
|
1414
|
+
NodeElement.name = 'NodeElement';
|
1415
|
+
|
1416
|
+
function NodeElement(node) {
|
1417
|
+
this.init(node);
|
1418
|
+
}
|
1419
|
+
|
1420
|
+
NodeElement.prototype.init = function(node) {
|
1421
|
+
this.node = node;
|
1422
|
+
return this.$element = $(node.element);
|
1423
|
+
};
|
1424
|
+
|
1425
|
+
NodeElement.prototype.getUl = function() {
|
1426
|
+
return this.$element.children('ul:first');
|
1427
|
+
};
|
1428
|
+
|
1429
|
+
NodeElement.prototype.getSpan = function() {
|
1430
|
+
return this.$element.children('div').find('span.title');
|
1431
|
+
};
|
1432
|
+
|
1433
|
+
NodeElement.prototype.getLi = function() {
|
1434
|
+
return this.$element;
|
1435
|
+
};
|
1436
|
+
|
1437
|
+
NodeElement.prototype.addDropHint = function(position) {
|
1438
|
+
if (position === Position.INSIDE) {
|
1439
|
+
return new BorderDropHint(this.$element);
|
1440
|
+
} else {
|
1441
|
+
return new GhostDropHint(this.node, this.$element, position);
|
1442
|
+
}
|
1443
|
+
};
|
1444
|
+
|
1445
|
+
NodeElement.prototype.select = function() {
|
1446
|
+
return this.getLi().addClass('selected');
|
1447
|
+
};
|
1448
|
+
|
1449
|
+
NodeElement.prototype.deselect = function() {
|
1450
|
+
return this.getLi().removeClass('selected');
|
1451
|
+
};
|
1452
|
+
|
1453
|
+
return NodeElement;
|
1454
|
+
|
1455
|
+
})();
|
1456
|
+
|
1457
|
+
FolderElement = (function(_super) {
|
1458
|
+
|
1459
|
+
__extends(FolderElement, _super);
|
1460
|
+
|
1461
|
+
FolderElement.name = 'FolderElement';
|
1462
|
+
|
1463
|
+
function FolderElement() {
|
1464
|
+
return FolderElement.__super__.constructor.apply(this, arguments);
|
1465
|
+
}
|
1466
|
+
|
1467
|
+
FolderElement.prototype.toggle = function(on_finished) {
|
1468
|
+
if (this.node.is_open) {
|
1469
|
+
return this.close(on_finished);
|
1470
|
+
} else {
|
1471
|
+
return this.open(on_finished);
|
1472
|
+
}
|
1473
|
+
};
|
1474
|
+
|
1475
|
+
FolderElement.prototype.open = function(on_finished, skip_slide) {
|
1476
|
+
var doOpen,
|
1477
|
+
_this = this;
|
1478
|
+
this.node.is_open = true;
|
1479
|
+
this.getButton().removeClass('closed');
|
1480
|
+
doOpen = function() {
|
1481
|
+
_this.getLi().removeClass('closed');
|
1482
|
+
if (on_finished) {
|
1483
|
+
return on_finished();
|
1484
|
+
}
|
1485
|
+
};
|
1486
|
+
if (skip_slide) {
|
1487
|
+
this.getUl().show();
|
1488
|
+
return doOpen();
|
1489
|
+
} else {
|
1490
|
+
return this.getUl().slideDown('fast', doOpen);
|
1491
|
+
}
|
1492
|
+
};
|
1493
|
+
|
1494
|
+
FolderElement.prototype.close = function(on_finished) {
|
1495
|
+
var _this = this;
|
1496
|
+
this.node.is_open = false;
|
1497
|
+
this.getButton().addClass('closed');
|
1498
|
+
return this.getUl().slideUp('fast', function() {
|
1499
|
+
_this.getLi().addClass('closed');
|
1500
|
+
if (on_finished) {
|
1501
|
+
return on_finished();
|
1502
|
+
}
|
1503
|
+
});
|
1504
|
+
};
|
1505
|
+
|
1506
|
+
FolderElement.prototype.getButton = function() {
|
1507
|
+
return this.$element.children('div').find('a.toggler');
|
1508
|
+
};
|
1509
|
+
|
1510
|
+
FolderElement.prototype.addDropHint = function(position) {
|
1511
|
+
if (!this.node.is_open && position === Position.INSIDE) {
|
1512
|
+
return new BorderDropHint(this.$element);
|
1513
|
+
} else {
|
1514
|
+
return new GhostDropHint(this.node, this.$element, position);
|
1515
|
+
}
|
1516
|
+
};
|
1517
|
+
|
1518
|
+
return FolderElement;
|
1519
|
+
|
1520
|
+
})(NodeElement);
|
1521
|
+
|
1522
|
+
DragElement = (function() {
|
1523
|
+
|
1524
|
+
DragElement.name = 'DragElement';
|
1525
|
+
|
1526
|
+
function DragElement(node, offset_x, offset_y, $tree) {
|
1527
|
+
this.offset_x = offset_x;
|
1528
|
+
this.offset_y = offset_y;
|
1529
|
+
this.$element = $("<span class=\"title tree-dragging\">" + node.name + "</span>");
|
1530
|
+
this.$element.css("position", "absolute");
|
1531
|
+
$tree.append(this.$element);
|
1532
|
+
}
|
1533
|
+
|
1534
|
+
DragElement.prototype.move = function(page_x, page_y) {
|
1535
|
+
return this.$element.offset({
|
1536
|
+
left: page_x - this.offset_x,
|
1537
|
+
top: page_y - this.offset_y
|
1538
|
+
});
|
1539
|
+
};
|
1540
|
+
|
1541
|
+
DragElement.prototype.remove = function() {
|
1542
|
+
return this.$element.remove();
|
1543
|
+
};
|
1544
|
+
|
1545
|
+
return DragElement;
|
1546
|
+
|
1547
|
+
})();
|
1548
|
+
|
1549
|
+
this.Tree.Node = Node;
|
1550
|
+
|
1551
|
+
}).call(this);
|