fancytree-rails 2.0.0.pre.6.pre.1 → 2.0.0.pre.11.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Rakefile +6 -7
- data/lib/fancytree/rails/version.rb +2 -2
- data/vendor/assets/images/fancytree/skin-win8-xxl/icons.gif +0 -0
- data/vendor/assets/images/fancytree/skin-win8-xxl/loading.gif +0 -0
- data/vendor/assets/javascripts/fancytree.js +1 -1
- data/vendor/assets/javascripts/fancytree/MIT-LICENSE.txt +21 -0
- data/vendor/assets/javascripts/fancytree/jquery.fancytree-all.js +1267 -475
- data/vendor/assets/javascripts/fancytree/jquery.fancytree-custom.min.js +41 -0
- data/vendor/assets/javascripts/fancytree/jquery.fancytree.js +582 -310
- data/vendor/assets/javascripts/fancytree/jquery.fancytree.min.js +14 -7
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.childcounter.js +185 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.clones.js +417 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.columnview.js +149 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.debug.js +142 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.dnd.js +539 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.edit.js +318 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.filter.js +173 -0
- data/vendor/assets/javascripts/fancytree/{jquery.fancytree.awesome.js → src/jquery.fancytree.glyph.js} +28 -26
- data/vendor/assets/javascripts/fancytree/{jquery.fancytree.gridnav.js → src/jquery.fancytree.gridnav.js} +77 -41
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.js +4027 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.menu.js +155 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.persist.js +345 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.table.js +345 -0
- data/vendor/assets/javascripts/fancytree/src/jquery.fancytree.themeroller.js +82 -0
- data/vendor/assets/stylesheets/fancytree/skin-awesome/ui.fancytree.css +29 -15
- data/vendor/assets/stylesheets/fancytree/skin-awesome/ui.fancytree.min.css +1 -1
- data/vendor/assets/stylesheets/fancytree/skin-bootstrap/ui.fancytree.css +366 -0
- data/vendor/assets/stylesheets/fancytree/skin-bootstrap/ui.fancytree.min.css +6 -0
- data/vendor/assets/stylesheets/fancytree/skin-lion/ui.fancytree.css +34 -7
- data/vendor/assets/stylesheets/fancytree/skin-lion/ui.fancytree.min.css +1 -1
- data/vendor/assets/stylesheets/fancytree/skin-vista/ui.fancytree.css +34 -7
- data/vendor/assets/stylesheets/fancytree/skin-vista/ui.fancytree.min.css +1 -1
- data/vendor/assets/stylesheets/fancytree/skin-win7/ui.fancytree.css +34 -7
- data/vendor/assets/stylesheets/fancytree/skin-win7/ui.fancytree.min.css +1 -1
- data/vendor/assets/stylesheets/fancytree/skin-win8-xxl/ui.fancytree.css +507 -0
- data/vendor/assets/stylesheets/fancytree/skin-win8-xxl/ui.fancytree.min.css +11 -0
- data/vendor/assets/stylesheets/fancytree/skin-win8/ui.fancytree.css +34 -7
- data/vendor/assets/stylesheets/fancytree/skin-win8/ui.fancytree.min.css +1 -1
- data/vendor/assets/stylesheets/fancytree/skin-xp/ui.fancytree.css +34 -7
- data/vendor/assets/stylesheets/fancytree/skin-xp/ui.fancytree.min.css +1 -1
- metadata +24 -13
- data/vendor/assets/javascripts/fancytree/jquery.fancytree-all.min.js +0 -7
- data/vendor/assets/javascripts/fancytree/jquery.fancytree-all.min.js.map +0 -1
- data/vendor/assets/javascripts/fancytree/jquery.fancytree.min.js.map +0 -1
- data/vendor/assets/stylesheets/fancytree/skin-lion/ui.fancytree-org.css +0 -460
- data/vendor/assets/stylesheets/fancytree/skin-themeroller/ui.fancytree-org.css +0 -505
- data/vendor/assets/stylesheets/fancytree/skin-vista/ui.fancytree-org.css +0 -610
- data/vendor/assets/stylesheets/fancytree/skin-win7/ui.fancytree-org.css +0 -592
- data/vendor/assets/stylesheets/fancytree/skin-win8/ui.fancytree-org.css +0 -602
- data/vendor/assets/stylesheets/fancytree/skin-xp/ui.fancytree-org.css +0 -578
@@ -0,0 +1,149 @@
|
|
1
|
+
/*!
|
2
|
+
* jquery.fancytree.columnview.js
|
3
|
+
*
|
4
|
+
* Render tree like a Mac Finder's column view.
|
5
|
+
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
6
|
+
*
|
7
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
8
|
+
*
|
9
|
+
* Released under the MIT license
|
10
|
+
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
11
|
+
*
|
12
|
+
* @version 2.0.0-11
|
13
|
+
* @date 2014-04-27T22:28
|
14
|
+
*/
|
15
|
+
|
16
|
+
;(function($, window, document, undefined) {
|
17
|
+
|
18
|
+
"use strict";
|
19
|
+
|
20
|
+
// prevent duplicate loading
|
21
|
+
// if ( $.ui.fancytree && $.ui.fancytree.version ) {
|
22
|
+
// $.ui.fancytree.warn("Fancytree: duplicate include");
|
23
|
+
// return;
|
24
|
+
// }
|
25
|
+
|
26
|
+
|
27
|
+
/*******************************************************************************
|
28
|
+
* Private functions and variables
|
29
|
+
*/
|
30
|
+
/*
|
31
|
+
function _assert(cond, msg){
|
32
|
+
msg = msg || "";
|
33
|
+
if(!cond){
|
34
|
+
$.error("Assertion failed " + msg);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
*/
|
38
|
+
|
39
|
+
/*******************************************************************************
|
40
|
+
* Private functions and variables
|
41
|
+
*/
|
42
|
+
$.ui.fancytree.registerExtension({
|
43
|
+
name: "columnview",
|
44
|
+
version: "0.0.1",
|
45
|
+
// Default options for this extension.
|
46
|
+
options: {
|
47
|
+
},
|
48
|
+
// Overide virtual methods for this extension.
|
49
|
+
// `this` : is this extension object
|
50
|
+
// `this._base` : the Fancytree instance
|
51
|
+
// `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree)
|
52
|
+
treeInit: function(ctx){
|
53
|
+
var $tdFirst, $ul,
|
54
|
+
tree = ctx.tree,
|
55
|
+
$table = tree.widget.element;
|
56
|
+
|
57
|
+
tree.tr = $("tbody tr", $table)[0];
|
58
|
+
tree.columnCount = $(">td", tree.tr).length;
|
59
|
+
// Perform default behavior
|
60
|
+
this._super(ctx);
|
61
|
+
// Standard Fancytree created a root <ul>. Now move this into first table cell
|
62
|
+
$ul = $(tree.rootNode.ul);
|
63
|
+
$tdFirst = $(">td", tree.tr).eq(0);
|
64
|
+
|
65
|
+
$ul.removeClass("fancytree-container");
|
66
|
+
$ul.removeAttr("tabindex");
|
67
|
+
tree.$container = $table;
|
68
|
+
$table.addClass("fancytree-container fancytree-ext-columnview");
|
69
|
+
$table.attr("tabindex", "0");
|
70
|
+
|
71
|
+
$tdFirst.empty();
|
72
|
+
$ul.detach().appendTo($tdFirst);
|
73
|
+
|
74
|
+
// Force some required options
|
75
|
+
tree.widget.options.autoCollapse = true;
|
76
|
+
// tree.widget.options.autoActivate = true;
|
77
|
+
tree.widget.options.fx = false;
|
78
|
+
tree.widget.options.clickFolderMode = 1;
|
79
|
+
|
80
|
+
// Make sure that only active path is expanded when a node is activated:
|
81
|
+
$table.bind("fancytreeactivate", function(event, data){
|
82
|
+
var i, tdList,
|
83
|
+
node = data.node,
|
84
|
+
tree = data.tree,
|
85
|
+
level = node.getLevel();
|
86
|
+
|
87
|
+
tree._callHook("nodeCollapseSiblings", node);
|
88
|
+
// Clear right neighbours
|
89
|
+
if(level <= tree.columnCount){
|
90
|
+
tdList = $(">td", tree.tr);
|
91
|
+
for(i=level; i<tree.columnCount; i++){
|
92
|
+
tdList.eq(i).empty();
|
93
|
+
}
|
94
|
+
}
|
95
|
+
// Expand nodes on activate, so we populate the right neighbor cell
|
96
|
+
if(!node.expanded && (node.children || node.lazy)) {
|
97
|
+
node.setExpanded();
|
98
|
+
}
|
99
|
+
// Adjust keyboard behaviour:
|
100
|
+
}).bind("fancytreekeydown", function(event, data){
|
101
|
+
var next = null;
|
102
|
+
switch(event.which){
|
103
|
+
case $.ui.keyCode.DOWN:
|
104
|
+
next = data.node.getNextSibling();
|
105
|
+
if( next ){
|
106
|
+
next.setFocus();
|
107
|
+
}
|
108
|
+
return false;
|
109
|
+
case $.ui.keyCode.LEFT:
|
110
|
+
next = data.node.getParent();
|
111
|
+
if( next ){
|
112
|
+
next.setFocus();
|
113
|
+
}
|
114
|
+
return false;
|
115
|
+
case $.ui.keyCode.UP:
|
116
|
+
next = data.node.getPrevSibling();
|
117
|
+
if( next ){
|
118
|
+
next.setFocus();
|
119
|
+
}
|
120
|
+
return false;
|
121
|
+
}
|
122
|
+
});
|
123
|
+
},
|
124
|
+
nodeRender: function(ctx, force, deep, collapsed, _recursive) {
|
125
|
+
// Render standard nested <ul> - <li> hierarchy
|
126
|
+
this._super(ctx, force, deep, collapsed, _recursive);
|
127
|
+
// Remove expander and add a trailing triangle instead
|
128
|
+
var level, $tdChild, $ul,
|
129
|
+
tree = ctx.tree,
|
130
|
+
node = ctx.node,
|
131
|
+
$span = $(node.span);
|
132
|
+
|
133
|
+
$span.find("span.fancytree-expander").remove();
|
134
|
+
if(node.hasChildren() !== false && !$span.find("span.fancytree-cv-right").length){
|
135
|
+
$span.append($("<span class='fancytree-icon fancytree-cv-right'>"));
|
136
|
+
}
|
137
|
+
// Move <ul> with children into the appropriate <td>
|
138
|
+
if(node.ul){
|
139
|
+
node.ul.style.display = ""; // might be hidden if RIGHT was pressed
|
140
|
+
level = node.getLevel();
|
141
|
+
if(level < tree.columnCount){
|
142
|
+
$tdChild = $(">td", tree.tr).eq(level);
|
143
|
+
$ul = $(node.ul).detach();
|
144
|
+
$tdChild.empty().append($ul);
|
145
|
+
}
|
146
|
+
}
|
147
|
+
}
|
148
|
+
});
|
149
|
+
}(jQuery, window, document));
|
@@ -0,0 +1,142 @@
|
|
1
|
+
/*!
|
2
|
+
* jquery.fancytree.debug.js
|
3
|
+
*
|
4
|
+
* Miscellaneous debug extensions.
|
5
|
+
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
6
|
+
*
|
7
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
8
|
+
*
|
9
|
+
* Released under the MIT license
|
10
|
+
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
11
|
+
*
|
12
|
+
* @version 2.0.0-11
|
13
|
+
* @date 2014-04-27T22:28
|
14
|
+
*/
|
15
|
+
|
16
|
+
;(function($, window, document, undefined) {
|
17
|
+
|
18
|
+
"use strict";
|
19
|
+
|
20
|
+
// prevent duplicate loading
|
21
|
+
// if ( $.ui.fancytree && $.ui.fancytree.version ) {
|
22
|
+
// $.ui.fancytree.warn("Fancytree: duplicate include");
|
23
|
+
// return;
|
24
|
+
// }
|
25
|
+
|
26
|
+
|
27
|
+
/* *****************************************************************************
|
28
|
+
* Private functions and variables
|
29
|
+
*/
|
30
|
+
var i,
|
31
|
+
HOOK_NAMES = "nodeClick nodeCollapseSiblings".split(" "),
|
32
|
+
EVENT_NAMES = "activate beforeActivate".split(" "),
|
33
|
+
HOOK_NAME_MAP = {},
|
34
|
+
EVENT_NAME_MAP = {};
|
35
|
+
|
36
|
+
for(i=0; i<HOOK_NAMES.length; i++){ HOOK_NAME_MAP[HOOK_NAMES[i]] = true; }
|
37
|
+
for(i=0; i<EVENT_NAMES.length; i++){ EVENT_NAME_MAP[EVENT_NAMES[i]] = true; }
|
38
|
+
|
39
|
+
/* *****************************************************************************
|
40
|
+
* Extension code
|
41
|
+
*/
|
42
|
+
$.ui.fancytree.registerExtension({
|
43
|
+
name: "tracecalls",
|
44
|
+
version: "0.0.1",
|
45
|
+
// Default options for this extension.
|
46
|
+
options: {
|
47
|
+
logTarget: null, // optional redirect logging to this <div> tag
|
48
|
+
traceEvents: false, // `true`or list of hook names
|
49
|
+
traceHooks: false // `true`or list of event names
|
50
|
+
},
|
51
|
+
// Overide virtual methods for this extension.
|
52
|
+
// `this` : is this Fancytree object
|
53
|
+
// `this._super`: the virtual function that was overridden (member of prev. extension or Fancytree)
|
54
|
+
treeInit: function(ctx){
|
55
|
+
var tree = ctx.tree;
|
56
|
+
|
57
|
+
// Bind init-handler to apply cookie state
|
58
|
+
tree.$div.bind("fancytreeinit", function(event){
|
59
|
+
tree.debug("COOKIE " + document.cookie);
|
60
|
+
});
|
61
|
+
// Init the tree
|
62
|
+
this._super(ctx);
|
63
|
+
},
|
64
|
+
nodeClick: function(ctx) {
|
65
|
+
if(this.options.tracecalls.traceHooks){
|
66
|
+
this.debug();
|
67
|
+
}
|
68
|
+
},
|
69
|
+
nodeCollapseSiblings: function(ctx) {
|
70
|
+
},
|
71
|
+
nodeDblclick: function(ctx) {
|
72
|
+
},
|
73
|
+
nodeKeydown: function(ctx) {
|
74
|
+
},
|
75
|
+
nodeLoadChildren: function(ctx, source) {
|
76
|
+
},
|
77
|
+
nodeOnFocusInOut: function(ctx) {
|
78
|
+
},
|
79
|
+
nodeRemoveChildMarkup: function(ctx) {
|
80
|
+
},
|
81
|
+
nodeRemoveMarkup: function(ctx) {
|
82
|
+
},
|
83
|
+
nodeRender: function(ctx, force, deep, collapsed, _recursive) {
|
84
|
+
},
|
85
|
+
nodeRenderStatus: function(ctx) {
|
86
|
+
},
|
87
|
+
nodeRenderTitle: function(ctx, title) {
|
88
|
+
},
|
89
|
+
nodeSetActive: function(ctx, flag, opts) {
|
90
|
+
},
|
91
|
+
nodeSetExpanded: function(ctx, flag, opts) {
|
92
|
+
},
|
93
|
+
nodeSetFocus: function(ctx) {
|
94
|
+
},
|
95
|
+
nodeSetSelected: function(ctx, flag) {
|
96
|
+
},
|
97
|
+
nodeSetStatus: function(ctx, status, message, details) {
|
98
|
+
},
|
99
|
+
nodeToggleExpanded: function(ctx) {
|
100
|
+
},
|
101
|
+
nodeToggleSelected: function(ctx) {
|
102
|
+
},
|
103
|
+
treeClear: function(ctx) {
|
104
|
+
},
|
105
|
+
treeCreate: function(ctx) {
|
106
|
+
},
|
107
|
+
treeDestroy: function(ctx) {
|
108
|
+
},
|
109
|
+
// treeInit: function(ctx) {
|
110
|
+
// },
|
111
|
+
treeLoad: function(ctx, source) {
|
112
|
+
},
|
113
|
+
treeSetFocus: function(ctx, flag) {
|
114
|
+
}
|
115
|
+
});
|
116
|
+
|
117
|
+
}(jQuery, window, document));
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
/* *****************************************************************************
|
122
|
+
* Fancytree extension: profiler
|
123
|
+
*/
|
124
|
+
;(function($, window, document, undefined) {
|
125
|
+
$.ui.fancytree.registerExtension({
|
126
|
+
name: "profiler",
|
127
|
+
version: "0.0.1",
|
128
|
+
// Default options for this extension
|
129
|
+
options: {
|
130
|
+
prefix: ""
|
131
|
+
},
|
132
|
+
// Overide virtual methods for this extension
|
133
|
+
nodeRender: function(ctx, force, deep, collapsed){
|
134
|
+
// ctx.tree.debug("**** PROFILER nodeRender");
|
135
|
+
var s = this.options.prefix + "render '" + ctx.node + "'";
|
136
|
+
/*jshint expr:true */
|
137
|
+
window.console && window.console.time && window.console.time(s);
|
138
|
+
this._super(ctx, force, deep, collapsed);
|
139
|
+
window.console && window.console.timeEnd && window.console.timeEnd(s);
|
140
|
+
}
|
141
|
+
});
|
142
|
+
}(jQuery, window, document));
|
@@ -0,0 +1,539 @@
|
|
1
|
+
/*!
|
2
|
+
* jquery.fancytree.dnd.js
|
3
|
+
*
|
4
|
+
* Drag-and-drop support.
|
5
|
+
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
6
|
+
*
|
7
|
+
* Copyright (c) 2014, Martin Wendt (http://wwWendt.de)
|
8
|
+
*
|
9
|
+
* Released under the MIT license
|
10
|
+
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
11
|
+
*
|
12
|
+
* @version 2.0.0-11
|
13
|
+
* @date 2014-04-27T22:28
|
14
|
+
*/
|
15
|
+
|
16
|
+
;(function($, window, document, undefined) {
|
17
|
+
|
18
|
+
"use strict";
|
19
|
+
|
20
|
+
/* *****************************************************************************
|
21
|
+
* Private functions and variables
|
22
|
+
*/
|
23
|
+
var logMsg = $.ui.fancytree.debug,
|
24
|
+
didRegisterDnd = false;
|
25
|
+
|
26
|
+
/* Convert number to string and prepend +/-; return empty string for 0.*/
|
27
|
+
function offsetString(n){
|
28
|
+
return n === 0 ? "" : (( n > 0 ) ? ("+" + n) : ("" + n));
|
29
|
+
}
|
30
|
+
|
31
|
+
/* *****************************************************************************
|
32
|
+
* Drag and drop support
|
33
|
+
*/
|
34
|
+
function _initDragAndDrop(tree) {
|
35
|
+
var dnd = tree.options.dnd || null;
|
36
|
+
// Register 'connectToFancytree' option with ui.draggable
|
37
|
+
if( dnd ) {
|
38
|
+
_registerDnd();
|
39
|
+
}
|
40
|
+
// Attach ui.draggable to this Fancytree instance
|
41
|
+
if(dnd && dnd.dragStart ) {
|
42
|
+
tree.widget.element.draggable($.extend({
|
43
|
+
addClasses: false,
|
44
|
+
appendTo: "body",
|
45
|
+
containment: false,
|
46
|
+
delay: 0,
|
47
|
+
distance: 4,
|
48
|
+
// TODO: merge Dynatree issue 419
|
49
|
+
revert: false,
|
50
|
+
scroll: true, // issue 244: enable scrolling (if ul.fancytree-container)
|
51
|
+
scrollSpeed: 7,
|
52
|
+
scrollSensitivity: 10,
|
53
|
+
// Delegate draggable.start, drag, and stop events to our handler
|
54
|
+
connectToFancytree: true,
|
55
|
+
// Let source tree create the helper element
|
56
|
+
helper: function(event) {
|
57
|
+
var sourceNode = $.ui.fancytree.getNode(event.target);
|
58
|
+
if(!sourceNode){ // Dynatree issue 211
|
59
|
+
// might happen, if dragging a table *header*
|
60
|
+
return "<div>ERROR?: helper requested but sourceNode not found</div>";
|
61
|
+
}
|
62
|
+
return sourceNode.tree.ext.dnd._onDragEvent("helper", sourceNode, null, event, null, null);
|
63
|
+
},
|
64
|
+
start: function(event, ui) {
|
65
|
+
var sourceNode = ui.helper.data("ftSourceNode");
|
66
|
+
return !!sourceNode; // Abort dragging if no node could be found
|
67
|
+
}
|
68
|
+
}, tree.options.dnd.draggable));
|
69
|
+
}
|
70
|
+
// Attach ui.droppable to this Fancytree instance
|
71
|
+
if(dnd && dnd.dragDrop) {
|
72
|
+
tree.widget.element.droppable($.extend({
|
73
|
+
addClasses: false,
|
74
|
+
tolerance: "intersect",
|
75
|
+
greedy: false
|
76
|
+
/*
|
77
|
+
,
|
78
|
+
activate: function(event, ui) {
|
79
|
+
logMsg("droppable - activate", event, ui, this);
|
80
|
+
},
|
81
|
+
create: function(event, ui) {
|
82
|
+
logMsg("droppable - create", event, ui);
|
83
|
+
},
|
84
|
+
deactivate: function(event, ui) {
|
85
|
+
logMsg("droppable - deactivate", event, ui);
|
86
|
+
},
|
87
|
+
drop: function(event, ui) {
|
88
|
+
logMsg("droppable - drop", event, ui);
|
89
|
+
},
|
90
|
+
out: function(event, ui) {
|
91
|
+
logMsg("droppable - out", event, ui);
|
92
|
+
},
|
93
|
+
over: function(event, ui) {
|
94
|
+
logMsg("droppable - over", event, ui);
|
95
|
+
}
|
96
|
+
*/
|
97
|
+
}, tree.options.dnd.droppable));
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
//--- Extend ui.draggable event handling --------------------------------------
|
102
|
+
|
103
|
+
function _registerDnd() {
|
104
|
+
if(didRegisterDnd){
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
|
108
|
+
// Register proxy-functions for draggable.start/drag/stop
|
109
|
+
|
110
|
+
$.ui.plugin.add("draggable", "connectToFancytree", {
|
111
|
+
start: function(event, ui) {
|
112
|
+
// 'draggable' was renamed to 'ui-draggable' since jQueryUI 1.10
|
113
|
+
var draggable = $(this).data("ui-draggable") || $(this).data("draggable"),
|
114
|
+
sourceNode = ui.helper.data("ftSourceNode") || null;
|
115
|
+
// logMsg("draggable-connectToFancytree.start, %s", sourceNode);
|
116
|
+
// logMsg(" this: %o", this);
|
117
|
+
// logMsg(" event: %o", event);
|
118
|
+
// logMsg(" draggable: %o", draggable);
|
119
|
+
// logMsg(" ui: %o", ui);
|
120
|
+
|
121
|
+
if(sourceNode) {
|
122
|
+
// Adjust helper offset, so cursor is slightly outside top/left corner
|
123
|
+
draggable.offset.click.top = -2;
|
124
|
+
draggable.offset.click.left = + 16;
|
125
|
+
// logMsg(" draggable2: %o", draggable);
|
126
|
+
// logMsg(" draggable.offset.click FIXED: %s/%s", draggable.offset.click.left, draggable.offset.click.top);
|
127
|
+
// Trigger dragStart event
|
128
|
+
// TODO: when called as connectTo..., the return value is ignored(?)
|
129
|
+
return sourceNode.tree.ext.dnd._onDragEvent("start", sourceNode, null, event, ui, draggable);
|
130
|
+
}
|
131
|
+
},
|
132
|
+
drag: function(event, ui) {
|
133
|
+
// 'draggable' was renamed to 'ui-draggable' since jQueryUI 1.10
|
134
|
+
var isHelper,
|
135
|
+
draggable = $(this).data("ui-draggable") || $(this).data("draggable"),
|
136
|
+
sourceNode = ui.helper.data("ftSourceNode") || null,
|
137
|
+
prevTargetNode = ui.helper.data("ftTargetNode") || null,
|
138
|
+
targetNode = $.ui.fancytree.getNode(event.target);
|
139
|
+
// logMsg("$.ui.fancytree.getNode(%o): %s", event.target, targetNode);
|
140
|
+
// logMsg("connectToFancytree.drag: helper: %o", ui.helper[0]);
|
141
|
+
if(event.target && !targetNode){
|
142
|
+
// We got a drag event, but the targetNode could not be found
|
143
|
+
// at the event location. This may happen,
|
144
|
+
// 1. if the mouse jumped over the drag helper,
|
145
|
+
// 2. or if a non-fancytree element is dragged
|
146
|
+
// We ignore it:
|
147
|
+
isHelper = $(event.target).closest("div.fancytree-drag-helper,#fancytree-drop-marker").length > 0;
|
148
|
+
if(isHelper){
|
149
|
+
logMsg("Drag event over helper: ignored.");
|
150
|
+
return;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
// logMsg("draggable-connectToFancytree.drag: targetNode(from event): %s, ftTargetNode: %s", targetNode, ui.helper.data("ftTargetNode"));
|
154
|
+
ui.helper.data("ftTargetNode", targetNode);
|
155
|
+
// Leaving a tree node
|
156
|
+
if(prevTargetNode && prevTargetNode !== targetNode ) {
|
157
|
+
prevTargetNode.tree.ext.dnd._onDragEvent("leave", prevTargetNode, sourceNode, event, ui, draggable);
|
158
|
+
}
|
159
|
+
if(targetNode){
|
160
|
+
if(!targetNode.tree.options.dnd.dragDrop) {
|
161
|
+
// not enabled as drop target
|
162
|
+
} else if(targetNode === prevTargetNode) {
|
163
|
+
// Moving over same node
|
164
|
+
targetNode.tree.ext.dnd._onDragEvent("over", targetNode, sourceNode, event, ui, draggable);
|
165
|
+
}else{
|
166
|
+
// Entering this node first time
|
167
|
+
targetNode.tree.ext.dnd._onDragEvent("enter", targetNode, sourceNode, event, ui, draggable);
|
168
|
+
}
|
169
|
+
}
|
170
|
+
// else go ahead with standard event handling
|
171
|
+
},
|
172
|
+
stop: function(event, ui) {
|
173
|
+
// 'draggable' was renamed to 'ui-draggable' since jQueryUI 1.10
|
174
|
+
var draggable = $(this).data("ui-draggable") || $(this).data("draggable"),
|
175
|
+
sourceNode = ui.helper.data("ftSourceNode") || null,
|
176
|
+
targetNode = ui.helper.data("ftTargetNode") || null,
|
177
|
+
// mouseDownEvent = draggable._mouseDownEvent,
|
178
|
+
eventType = event.type,
|
179
|
+
dropped = (eventType === "mouseup" && event.which === 1);
|
180
|
+
// logMsg("draggable-connectToFancytree.stop: targetNode(from event): %s, ftTargetNode: %s", targetNode, ui.helper.data("ftTargetNode"));
|
181
|
+
// logMsg("draggable-connectToFancytree.stop, %s", sourceNode);
|
182
|
+
// logMsg(" type: %o, downEvent: %o, upEvent: %o", eventType, mouseDownEvent, event);
|
183
|
+
// logMsg(" targetNode: %o", targetNode);
|
184
|
+
if(!dropped){
|
185
|
+
logMsg("Drag was cancelled");
|
186
|
+
}
|
187
|
+
if(targetNode) {
|
188
|
+
if(dropped){
|
189
|
+
targetNode.tree.ext.dnd._onDragEvent("drop", targetNode, sourceNode, event, ui, draggable);
|
190
|
+
}
|
191
|
+
targetNode.tree.ext.dnd._onDragEvent("leave", targetNode, sourceNode, event, ui, draggable);
|
192
|
+
}
|
193
|
+
if(sourceNode){
|
194
|
+
sourceNode.tree.ext.dnd._onDragEvent("stop", sourceNode, null, event, ui, draggable);
|
195
|
+
}
|
196
|
+
}
|
197
|
+
});
|
198
|
+
|
199
|
+
didRegisterDnd = true;
|
200
|
+
}
|
201
|
+
|
202
|
+
|
203
|
+
/* *****************************************************************************
|
204
|
+
*
|
205
|
+
*/
|
206
|
+
|
207
|
+
$.ui.fancytree.registerExtension(
|
208
|
+
{
|
209
|
+
name: "dnd",
|
210
|
+
version: "0.1.0",
|
211
|
+
// Default options for this extension.
|
212
|
+
options: {
|
213
|
+
// Make tree nodes draggable:
|
214
|
+
dragStart: null, // Callback(sourceNode, data), return true, to enable dnd
|
215
|
+
dragStop: null, // Callback(sourceNode, data)
|
216
|
+
// helper: null,
|
217
|
+
// Make tree nodes accept draggables
|
218
|
+
autoExpandMS: 1000, // Expand nodes after n milliseconds of hovering.
|
219
|
+
preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
|
220
|
+
preventRecursiveMoves: true, // Prevent dropping nodes on own descendants
|
221
|
+
dragEnter: null, // Callback(targetNode, data)
|
222
|
+
dragOver: null, // Callback(targetNode, data)
|
223
|
+
dragDrop: null, // Callback(targetNode, data)
|
224
|
+
dragLeave: null, // Callback(targetNode, data)
|
225
|
+
//
|
226
|
+
draggable: null, // Additional options passed to jQuery draggable
|
227
|
+
droppable: null // Additional options passed to jQuery droppable
|
228
|
+
},
|
229
|
+
// Override virtual methods for this extension.
|
230
|
+
// `this` : Fancytree instance
|
231
|
+
// `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree)
|
232
|
+
treeInit: function(ctx){
|
233
|
+
var tree = ctx.tree;
|
234
|
+
this._super(ctx);
|
235
|
+
_initDragAndDrop(tree);
|
236
|
+
},
|
237
|
+
/* Override key handler in order to cancel dnd on escape.*/
|
238
|
+
nodeKeydown: function(ctx) {
|
239
|
+
var event = ctx.originalEvent;
|
240
|
+
if( event.which === $.ui.keyCode.ESCAPE) {
|
241
|
+
this._local._cancelDrag();
|
242
|
+
}
|
243
|
+
return this._super(ctx);
|
244
|
+
},
|
245
|
+
/* Display drop marker according to hitMode ('after', 'before', 'over', 'out', 'start', 'stop'). */
|
246
|
+
_setDndStatus: function(sourceNode, targetNode, helper, hitMode, accept) {
|
247
|
+
var posOpts,
|
248
|
+
markerOffsetX = 0,
|
249
|
+
markerAt = "center",
|
250
|
+
instData = this._local,
|
251
|
+
$source = sourceNode ? $(sourceNode.span) : null,
|
252
|
+
$target = $(targetNode.span);
|
253
|
+
|
254
|
+
if( !instData.$dropMarker ) {
|
255
|
+
instData.$dropMarker = $("<div id='fancytree-drop-marker'></div>")
|
256
|
+
.hide()
|
257
|
+
.css({"z-index": 1000})
|
258
|
+
.prependTo($(this.$div).parent());
|
259
|
+
// .prependTo("body");
|
260
|
+
// logMsg("Creating marker: %o", this.$dropMarker);
|
261
|
+
}
|
262
|
+
/*
|
263
|
+
if(hitMode === "start"){
|
264
|
+
}
|
265
|
+
if(hitMode === "stop"){
|
266
|
+
// sourceNode.removeClass("fancytree-drop-target");
|
267
|
+
}
|
268
|
+
*/
|
269
|
+
// this.$dropMarker.attr("class", hitMode);
|
270
|
+
if(hitMode === "after" || hitMode === "before" || hitMode === "over"){
|
271
|
+
// $source && $source.addClass("fancytree-drag-source");
|
272
|
+
|
273
|
+
// $target.addClass("fancytree-drop-target");
|
274
|
+
|
275
|
+
switch(hitMode){
|
276
|
+
case "before":
|
277
|
+
instData.$dropMarker.removeClass("fancytree-drop-after fancytree-drop-over");
|
278
|
+
instData.$dropMarker.addClass("fancytree-drop-before");
|
279
|
+
markerAt = "top";
|
280
|
+
break;
|
281
|
+
case "after":
|
282
|
+
instData.$dropMarker.removeClass("fancytree-drop-before fancytree-drop-over");
|
283
|
+
instData.$dropMarker.addClass("fancytree-drop-after");
|
284
|
+
markerAt = "bottom";
|
285
|
+
break;
|
286
|
+
default:
|
287
|
+
instData.$dropMarker.removeClass("fancytree-drop-after fancytree-drop-before");
|
288
|
+
instData.$dropMarker.addClass("fancytree-drop-over");
|
289
|
+
$target.addClass("fancytree-drop-target");
|
290
|
+
markerOffsetX = 8;
|
291
|
+
}
|
292
|
+
|
293
|
+
if( $.ui.fancytree.jquerySupports.positionMyOfs ){
|
294
|
+
posOpts = {
|
295
|
+
my: "left" + offsetString(markerOffsetX) + " center",
|
296
|
+
at: "left " + markerAt,
|
297
|
+
of: $target
|
298
|
+
};
|
299
|
+
} else {
|
300
|
+
posOpts = {
|
301
|
+
my: "left center",
|
302
|
+
at: "left " + markerAt,
|
303
|
+
of: $target,
|
304
|
+
offset: "" + markerOffsetX + " 0"
|
305
|
+
};
|
306
|
+
}
|
307
|
+
instData.$dropMarker
|
308
|
+
.show()
|
309
|
+
.position(posOpts);
|
310
|
+
// helper.addClass("fancytree-drop-hover");
|
311
|
+
} else {
|
312
|
+
// $source && $source.removeClass("fancytree-drag-source");
|
313
|
+
$target.removeClass("fancytree-drop-target");
|
314
|
+
instData.$dropMarker.hide();
|
315
|
+
// helper.removeClass("fancytree-drop-hover");
|
316
|
+
}
|
317
|
+
if(hitMode === "after"){
|
318
|
+
$target.addClass("fancytree-drop-after");
|
319
|
+
} else {
|
320
|
+
$target.removeClass("fancytree-drop-after");
|
321
|
+
}
|
322
|
+
if(hitMode === "before"){
|
323
|
+
$target.addClass("fancytree-drop-before");
|
324
|
+
} else {
|
325
|
+
$target.removeClass("fancytree-drop-before");
|
326
|
+
}
|
327
|
+
if(accept === true){
|
328
|
+
if($source){
|
329
|
+
$source.addClass("fancytree-drop-accept");
|
330
|
+
}
|
331
|
+
$target.addClass("fancytree-drop-accept");
|
332
|
+
helper.addClass("fancytree-drop-accept");
|
333
|
+
}else{
|
334
|
+
if($source){
|
335
|
+
$source.removeClass("fancytree-drop-accept");
|
336
|
+
}
|
337
|
+
$target.removeClass("fancytree-drop-accept");
|
338
|
+
helper.removeClass("fancytree-drop-accept");
|
339
|
+
}
|
340
|
+
if(accept === false){
|
341
|
+
if($source){
|
342
|
+
$source.addClass("fancytree-drop-reject");
|
343
|
+
}
|
344
|
+
$target.addClass("fancytree-drop-reject");
|
345
|
+
helper.addClass("fancytree-drop-reject");
|
346
|
+
}else{
|
347
|
+
if($source){
|
348
|
+
$source.removeClass("fancytree-drop-reject");
|
349
|
+
}
|
350
|
+
$target.removeClass("fancytree-drop-reject");
|
351
|
+
helper.removeClass("fancytree-drop-reject");
|
352
|
+
}
|
353
|
+
},
|
354
|
+
|
355
|
+
/*
|
356
|
+
* Handles drag'n'drop functionality.
|
357
|
+
*
|
358
|
+
* A standard jQuery drag-and-drop process may generate these calls:
|
359
|
+
*
|
360
|
+
* draggable helper():
|
361
|
+
* _onDragEvent("helper", sourceNode, null, event, null, null);
|
362
|
+
* start:
|
363
|
+
* _onDragEvent("start", sourceNode, null, event, ui, draggable);
|
364
|
+
* drag:
|
365
|
+
* _onDragEvent("leave", prevTargetNode, sourceNode, event, ui, draggable);
|
366
|
+
* _onDragEvent("over", targetNode, sourceNode, event, ui, draggable);
|
367
|
+
* _onDragEvent("enter", targetNode, sourceNode, event, ui, draggable);
|
368
|
+
* stop:
|
369
|
+
* _onDragEvent("drop", targetNode, sourceNode, event, ui, draggable);
|
370
|
+
* _onDragEvent("leave", targetNode, sourceNode, event, ui, draggable);
|
371
|
+
* _onDragEvent("stop", sourceNode, null, event, ui, draggable);
|
372
|
+
*/
|
373
|
+
_onDragEvent: function(eventName, node, otherNode, event, ui, draggable) {
|
374
|
+
if(eventName !== "over"){
|
375
|
+
logMsg("tree.ext.dnd._onDragEvent(%s, %o, %o) - %o", eventName, node, otherNode, this);
|
376
|
+
}
|
377
|
+
var $helper, nodeOfs, relPos, relPos2,
|
378
|
+
enterResponse, hitMode, r,
|
379
|
+
opts = this.options,
|
380
|
+
dnd = opts.dnd,
|
381
|
+
ctx = this._makeHookContext(node, event, {otherNode: otherNode, ui: ui, draggable: draggable}),
|
382
|
+
res = null,
|
383
|
+
nodeTag = $(node.span);
|
384
|
+
|
385
|
+
switch (eventName) {
|
386
|
+
case "helper":
|
387
|
+
// Only event and node argument is available
|
388
|
+
$helper = $("<div class='fancytree-drag-helper'><span class='fancytree-drag-helper-img' /></div>")
|
389
|
+
// .append($(event.target).closest("span.fancytree-node").find("span.fancytree-title").clone());
|
390
|
+
.append(nodeTag.find("span.fancytree-title").clone());
|
391
|
+
// issue 244: helper should be child of scrollParent
|
392
|
+
$("ul.fancytree-container", node.tree.$div).append($helper);
|
393
|
+
// Attach node reference to helper object
|
394
|
+
$helper.data("ftSourceNode", node);
|
395
|
+
// logMsg("helper=%o", $helper);
|
396
|
+
// logMsg("helper.sourceNode=%o", $helper.data("ftSourceNode"));
|
397
|
+
res = $helper;
|
398
|
+
break;
|
399
|
+
case "start":
|
400
|
+
if( node.isStatusNode() ) {
|
401
|
+
res = false;
|
402
|
+
} else if(dnd.dragStart) {
|
403
|
+
res = dnd.dragStart(node, ctx);
|
404
|
+
}
|
405
|
+
if(res === false) {
|
406
|
+
this.debug("tree.dragStart() cancelled");
|
407
|
+
//draggable._clear();
|
408
|
+
// NOTE: the return value seems to be ignored (drag is not canceled, when false is returned)
|
409
|
+
// TODO: call this._cancelDrag()?
|
410
|
+
ui.helper.trigger("mouseup");
|
411
|
+
ui.helper.hide();
|
412
|
+
} else {
|
413
|
+
nodeTag.addClass("fancytree-drag-source");
|
414
|
+
}
|
415
|
+
break;
|
416
|
+
case "enter":
|
417
|
+
if(dnd.preventRecursiveMoves && node.isDescendantOf(otherNode)){
|
418
|
+
r = false;
|
419
|
+
}else{
|
420
|
+
r = dnd.dragEnter ? dnd.dragEnter(node, ctx) : null;
|
421
|
+
}
|
422
|
+
if(!r){
|
423
|
+
// convert null, undefined, false to false
|
424
|
+
res = false;
|
425
|
+
}else if ( $.isArray(r) ) {
|
426
|
+
// TODO: also accept passing an object of this format directly
|
427
|
+
res = {
|
428
|
+
over: ($.inArray("over", r) >= 0),
|
429
|
+
before: ($.inArray("before", r) >= 0),
|
430
|
+
after: ($.inArray("after", r) >= 0)
|
431
|
+
};
|
432
|
+
}else{
|
433
|
+
res = {
|
434
|
+
over: ((r === true) || (r === "over")),
|
435
|
+
before: ((r === true) || (r === "before")),
|
436
|
+
after: ((r === true) || (r === "after"))
|
437
|
+
};
|
438
|
+
}
|
439
|
+
ui.helper.data("enterResponse", res);
|
440
|
+
logMsg("helper.enterResponse: %o", res);
|
441
|
+
break;
|
442
|
+
case "over":
|
443
|
+
enterResponse = ui.helper.data("enterResponse");
|
444
|
+
hitMode = null;
|
445
|
+
if(enterResponse === false){
|
446
|
+
// Don't call dragOver if onEnter returned false.
|
447
|
+
// break;
|
448
|
+
} else if(typeof enterResponse === "string") {
|
449
|
+
// Use hitMode from onEnter if provided.
|
450
|
+
hitMode = enterResponse;
|
451
|
+
} else {
|
452
|
+
// Calculate hitMode from relative cursor position.
|
453
|
+
nodeOfs = nodeTag.offset();
|
454
|
+
relPos = { x: event.pageX - nodeOfs.left,
|
455
|
+
y: event.pageY - nodeOfs.top };
|
456
|
+
relPos2 = { x: relPos.x / nodeTag.width(),
|
457
|
+
y: relPos.y / nodeTag.height() };
|
458
|
+
|
459
|
+
if( enterResponse.after && relPos2.y > 0.75 ){
|
460
|
+
hitMode = "after";
|
461
|
+
} else if(!enterResponse.over && enterResponse.after && relPos2.y > 0.5 ){
|
462
|
+
hitMode = "after";
|
463
|
+
} else if(enterResponse.before && relPos2.y <= 0.25) {
|
464
|
+
hitMode = "before";
|
465
|
+
} else if(!enterResponse.over && enterResponse.before && relPos2.y <= 0.5) {
|
466
|
+
hitMode = "before";
|
467
|
+
} else if(enterResponse.over) {
|
468
|
+
hitMode = "over";
|
469
|
+
}
|
470
|
+
// Prevent no-ops like 'before source node'
|
471
|
+
// TODO: these are no-ops when moving nodes, but not in copy mode
|
472
|
+
if( dnd.preventVoidMoves ){
|
473
|
+
if(node === otherNode){
|
474
|
+
logMsg(" drop over source node prevented");
|
475
|
+
hitMode = null;
|
476
|
+
}else if(hitMode === "before" && otherNode && node === otherNode.getNextSibling()){
|
477
|
+
logMsg(" drop after source node prevented");
|
478
|
+
hitMode = null;
|
479
|
+
}else if(hitMode === "after" && otherNode && node === otherNode.getPrevSibling()){
|
480
|
+
logMsg(" drop before source node prevented");
|
481
|
+
hitMode = null;
|
482
|
+
}else if(hitMode === "over" && otherNode && otherNode.parent === node && otherNode.isLastSibling() ){
|
483
|
+
logMsg(" drop last child over own parent prevented");
|
484
|
+
hitMode = null;
|
485
|
+
}
|
486
|
+
}
|
487
|
+
// logMsg("hitMode: %s - %s - %s", hitMode, (node.parent === otherNode), node.isLastSibling());
|
488
|
+
ui.helper.data("hitMode", hitMode);
|
489
|
+
}
|
490
|
+
// Auto-expand node (only when 'over' the node, not 'before', or 'after')
|
491
|
+
if(hitMode === "over" && dnd.autoExpandMS && node.hasChildren() !== false && !node.expanded) {
|
492
|
+
node.scheduleAction("expand", dnd.autoExpandMS);
|
493
|
+
}
|
494
|
+
if(hitMode && dnd.dragOver){
|
495
|
+
// TODO: http://code.google.com/p/dynatree/source/detail?r=625
|
496
|
+
ctx.hitMode = hitMode;
|
497
|
+
res = dnd.dragOver(node, ctx);
|
498
|
+
}
|
499
|
+
// issue 332
|
500
|
+
// this._setDndStatus(otherNode, node, ui.helper, hitMode, res!==false);
|
501
|
+
this._local._setDndStatus(otherNode, node, ui.helper, hitMode, res!==false && hitMode !== null);
|
502
|
+
break;
|
503
|
+
case "drop":
|
504
|
+
hitMode = ui.helper.data("hitMode");
|
505
|
+
if(hitMode && dnd.dragDrop){
|
506
|
+
ctx.hitMode = hitMode;
|
507
|
+
dnd.dragDrop(node, ctx);
|
508
|
+
}
|
509
|
+
break;
|
510
|
+
case "leave":
|
511
|
+
// Cancel pending expand request
|
512
|
+
node.scheduleAction("cancel");
|
513
|
+
ui.helper.data("enterResponse", null);
|
514
|
+
ui.helper.data("hitMode", null);
|
515
|
+
this._local._setDndStatus(otherNode, node, ui.helper, "out", undefined);
|
516
|
+
if(dnd.dragLeave){
|
517
|
+
dnd.dragLeave(node, ctx);
|
518
|
+
}
|
519
|
+
break;
|
520
|
+
case "stop":
|
521
|
+
nodeTag.removeClass("fancytree-drag-source");
|
522
|
+
if(dnd.dragStop){
|
523
|
+
dnd.dragStop(node, ctx);
|
524
|
+
}
|
525
|
+
break;
|
526
|
+
default:
|
527
|
+
throw "Unsupported drag event: " + eventName;
|
528
|
+
}
|
529
|
+
return res;
|
530
|
+
},
|
531
|
+
|
532
|
+
_cancelDrag: function() {
|
533
|
+
var dd = $.ui.ddmanager.current;
|
534
|
+
if(dd){
|
535
|
+
dd.cancel();
|
536
|
+
}
|
537
|
+
}
|
538
|
+
});
|
539
|
+
}(jQuery, window, document));
|