compass-jquery-plugin 0.3.0.beta.10 → 0.3.0.beta.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. data/.loadpath +5 -5
  2. data/.project +18 -17
  3. data/VERSION.yml +1 -1
  4. data/compass-jquery-plugin.gemspec +26 -2
  5. data/gem_tasks/dynatree.rake +1 -1
  6. data/gem_tasks/jqgrid.rake +15 -14
  7. data/gem_tasks/jrails.rake +3 -13
  8. data/lib/compiler.jar +0 -0
  9. data/lib/jquery/gridify/grid_column.rb +16 -9
  10. data/lib/jquery/gridify/grid_finder.rb +36 -17
  11. data/lib/jquery/gridify/grid_options.rb +10 -8
  12. data/lib/jquery/gridify/grid_view.rb +2 -1
  13. data/lib/jquery.ui.rb +5 -27
  14. data/templates/dynatree/jquery.dynatree.js +822 -243
  15. data/templates/dynatree/jquery.dynatree.min.js +71 -58
  16. data/templates/dynatree/jquery.ui/dynatree.aero/copy_here.png +0 -0
  17. data/templates/dynatree/jquery.ui/dynatree.aero/drop_accept.png +0 -0
  18. data/templates/dynatree/jquery.ui/dynatree.aero/drop_here.png +0 -0
  19. data/templates/dynatree/jquery.ui/dynatree.aero/drop_reject.png +0 -0
  20. data/templates/dynatree/jquery.ui/dynatree.aero/move_here.png +0 -0
  21. data/templates/dynatree/jquery.ui/dynatree.aero.scss +136 -52
  22. data/templates/dynatree/jquery.ui/dynatree.aqua/copy_here.png +0 -0
  23. data/templates/dynatree/jquery.ui/dynatree.aqua/drop_accept.png +0 -0
  24. data/templates/dynatree/jquery.ui/dynatree.aqua/drop_here.png +0 -0
  25. data/templates/dynatree/jquery.ui/dynatree.aqua/drop_reject.png +0 -0
  26. data/templates/dynatree/jquery.ui/dynatree.aqua/move_here.png +0 -0
  27. data/templates/dynatree/jquery.ui/dynatree.aqua.scss +136 -52
  28. data/templates/dynatree/jquery.ui/dynatree.crystal/copy_here.png +0 -0
  29. data/templates/dynatree/jquery.ui/dynatree.crystal/drop_accept.png +0 -0
  30. data/templates/dynatree/jquery.ui/dynatree.crystal/drop_here.png +0 -0
  31. data/templates/dynatree/jquery.ui/dynatree.crystal/drop_reject.png +0 -0
  32. data/templates/dynatree/jquery.ui/dynatree.crystal/move_here.png +0 -0
  33. data/templates/dynatree/jquery.ui/dynatree.crystal.scss +136 -52
  34. data/templates/dynatree/jquery.ui/dynatree.xp/copy_here.png +0 -0
  35. data/templates/dynatree/jquery.ui/dynatree.xp/drop_accept.png +0 -0
  36. data/templates/dynatree/jquery.ui/dynatree.xp/drop_here.png +0 -0
  37. data/templates/dynatree/jquery.ui/dynatree.xp/drop_reject.png +0 -0
  38. data/templates/dynatree/jquery.ui/dynatree.xp/move_here.png +0 -0
  39. data/templates/dynatree/jquery.ui/dynatree.xp.scss +229 -127
  40. data/templates/dynatree/manifest.rb +20 -0
  41. data/templates/jqgrid/i18n/jqgrid/locale-da.js +128 -0
  42. data/templates/jqgrid/i18n/jqgrid/locale-da.min.js +6 -0
  43. data/templates/jqgrid/i18n/jqgrid/locale-es.js +128 -0
  44. data/templates/jqgrid/i18n/jqgrid/locale-es.min.js +7 -0
  45. data/templates/jqgrid/jquery.jqGrid.js +6772 -6464
  46. data/templates/jqgrid/jquery.jqGrid.min.js +455 -441
  47. data/templates/jqgrid/jquery.ui/jqGrid.scss +24 -1
  48. data/templates/jqgrid/manifest.rb +4 -0
  49. data/templates/jqical/jquery.jqical.min.js +170 -171
  50. data/templates/jqical/jquery.ui/jqical.scss +2 -2
  51. data/templates/jqtouch/jqtouch/jqtouch.scss +1 -1
  52. data/templates/jrails/jquery-1.4.2.min.js +210 -210
  53. data/templates/jrails/jquery-ui-1.8.2.min.js +761 -759
  54. data/templates/jrails/jquery.compat-1.3.min.js +2 -2
  55. data/templates/jrails/jquery.contextMenu.min.js +1 -1
  56. data/templates/jrails/jquery.farbtastic.min.js +2 -2
  57. data/templates/jrails/jquery.haml.min.js +5 -5
  58. data/templates/jrails/jquery.metadata.min.js +2 -2
  59. data/templates/jrails/jquery.pngFix.min.js +1 -1
  60. data/templates/jrails/jquery.themeswitchertool.min.js +7 -8
  61. data/templates/jrails/jquery.ui/_theme.scss +6 -1
  62. data/templates/jrails/jquery.ui/base.scss +38 -43
  63. data/templates/jrails/jquery.ui/black-tie/ui-bg_highlight-hard_100_f9f9f9_1x100.png +0 -0
  64. data/templates/jrails/jquery.ui/black-tie/ui-bg_inset-hard_55_ffeb80_1x100.png +0 -0
  65. data/templates/jrails/jquery.ui/black-tie/ui-icons_4ca300_256x240.png +0 -0
  66. data/templates/jrails/jquery.ui/black-tie/ui-icons_bbbbbb_256x240.png +0 -0
  67. data/templates/jrails/jquery.ui/black-tie/ui-icons_ffcf29_256x240.png +0 -0
  68. data/templates/jrails/jquery.ui/black-tie.scss +38 -43
  69. data/templates/jrails/jquery.ui/blitzer/ui-bg_dots-small_65_a6a6a6_2x2.png +0 -0
  70. data/templates/jrails/jquery.ui/blitzer/ui-bg_glass_55_fbf8ee_1x400.png +0 -0
  71. data/templates/jrails/jquery.ui/blitzer.scss +38 -43
  72. data/templates/jrails/jquery.ui/cupertino/ui-bg_highlight-soft_25_ffef8f_1x100.png +0 -0
  73. data/templates/jrails/jquery.ui/cupertino.scss +38 -43
  74. data/templates/jrails/jquery.ui/dark-hive/ui-bg_highlight-soft_33_003147_1x100.png +0 -0
  75. data/templates/jrails/jquery.ui/dark-hive/ui-icons_a83300_256x240.png +0 -0
  76. data/templates/jrails/jquery.ui/dark-hive.scss +38 -43
  77. data/templates/jrails/jquery.ui/dot-luv/ui-bg_diagonals-thick_15_0b3e6f_40x40.png +0 -0
  78. data/templates/jrails/jquery.ui/dot-luv/ui-bg_dots-small_30_a32d00_2x2.png +0 -0
  79. data/templates/jrails/jquery.ui/dot-luv/ui-bg_dots-small_40_00498f_2x2.png +0 -0
  80. data/templates/jrails/jquery.ui/dot-luv/ui-icons_00498f_256x240.png +0 -0
  81. data/templates/jrails/jquery.ui/dot-luv.scss +38 -43
  82. data/templates/jrails/jquery.ui/eggplant/ui-bg_highlight-soft_45_5f5964_1x100.png +0 -0
  83. data/templates/jrails/jquery.ui/eggplant/ui-icons_ebccce_256x240.png +0 -0
  84. data/templates/jrails/jquery.ui/eggplant.scss +38 -43
  85. data/templates/jrails/jquery.ui/excite-bike/ui-bg_diagonals-thick_20_e69700_40x40.png +0 -0
  86. data/templates/jrails/jquery.ui/excite-bike/ui-bg_flat_0_e69700_40x100.png +0 -0
  87. data/templates/jrails/jquery.ui/excite-bike/ui-bg_highlight-soft_100_f9f9f9_1x100.png +0 -0
  88. data/templates/jrails/jquery.ui/excite-bike/ui-icons_0a82eb_256x240.png +0 -0
  89. data/templates/jrails/jquery.ui/excite-bike/ui-icons_0b54d5_256x240.png +0 -0
  90. data/templates/jrails/jquery.ui/excite-bike.scss +38 -43
  91. data/templates/jrails/jquery.ui/flick/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
  92. data/templates/jrails/jquery.ui/flick.scss +38 -43
  93. data/templates/jrails/jquery.ui/hot-sneaks/ui-bg_diagonals-small_50_ff3853_40x40.png +0 -0
  94. data/templates/jrails/jquery.ui/hot-sneaks/ui-bg_diagonals-small_75_ccd232_40x40.png +0 -0
  95. data/templates/jrails/jquery.ui/hot-sneaks/ui-bg_flat_75_ba9217_40x100.png +0 -0
  96. data/templates/jrails/jquery.ui/hot-sneaks/ui-icons_e1e463_256x240.png +0 -0
  97. data/templates/jrails/jquery.ui/hot-sneaks.scss +38 -43
  98. data/templates/jrails/jquery.ui/humanity/ui-bg_glass_100_f5f0e5_1x400.png +0 -0
  99. data/templates/jrails/jquery.ui/humanity/ui-bg_highlight-hard_65_fee4bd_1x100.png +0 -0
  100. data/templates/jrails/jquery.ui/humanity/ui-bg_inset-soft_100_f4f0ec_1x100.png +0 -0
  101. data/templates/jrails/jquery.ui/humanity/ui-icons_f35f07_256x240.png +0 -0
  102. data/templates/jrails/jquery.ui/humanity/ui-icons_ff7519_256x240.png +0 -0
  103. data/templates/jrails/jquery.ui/humanity.scss +38 -43
  104. data/templates/jrails/jquery.ui/le-frog/ui-bg_glass_55_fbf5d0_1x400.png +0 -0
  105. data/templates/jrails/jquery.ui/le-frog/ui-bg_highlight-soft_33_3a8104_1x100.png +0 -0
  106. data/templates/jrails/jquery.ui/le-frog/ui-bg_highlight-soft_50_4eb305_1x100.png +0 -0
  107. data/templates/jrails/jquery.ui/le-frog/ui-bg_highlight-soft_60_4ca20b_1x100.png +0 -0
  108. data/templates/jrails/jquery.ui/le-frog/ui-icons_72b42d_256x240.png +0 -0
  109. data/templates/jrails/jquery.ui/le-frog.scss +38 -43
  110. data/templates/jrails/jquery.ui/mint-choc/ui-bg_glass_15_5f391b_1x400.png +0 -0
  111. data/templates/jrails/jquery.ui/mint-choc/ui-bg_gloss-wave_20_1c160d_500x100.png +0 -0
  112. data/templates/jrails/jquery.ui/mint-choc/ui-icons_9bcc60_256x240.png +0 -0
  113. data/templates/jrails/jquery.ui/mint-choc.scss +38 -43
  114. data/templates/jrails/jquery.ui/overcast/ui-bg_flat_55_c0402a_40x100.png +0 -0
  115. data/templates/jrails/jquery.ui/overcast/ui-bg_glass_100_f8f8f8_1x400.png +0 -0
  116. data/templates/jrails/jquery.ui/overcast/ui-icons_70b2e1_256x240.png +0 -0
  117. data/templates/jrails/jquery.ui/overcast/ui-icons_fbc856_256x240.png +0 -0
  118. data/templates/jrails/jquery.ui/overcast.scss +38 -43
  119. data/templates/jrails/jquery.ui/pepper-grinder/ui-bg_fine-grain_65_654b24_60x60.png +0 -0
  120. data/templates/jrails/jquery.ui/pepper-grinder/ui-icons_fbdb93_256x240.png +0 -0
  121. data/templates/jrails/jquery.ui/pepper-grinder.scss +38 -43
  122. data/templates/jrails/jquery.ui/redmond/ui-bg_flat_55_fbec88_40x100.png +0 -0
  123. data/templates/jrails/jquery.ui/redmond/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
  124. data/templates/jrails/jquery.ui/redmond/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
  125. data/templates/jrails/jquery.ui/redmond/ui-icons_d8e7f3_256x240.png +0 -0
  126. data/templates/jrails/jquery.ui/redmond.scss +38 -43
  127. data/templates/jrails/jquery.ui/smoothness/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  128. data/templates/jrails/jquery.ui/smoothness/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  129. data/templates/jrails/jquery.ui/smoothness.scss +38 -43
  130. data/templates/jrails/jquery.ui/south-street/ui-bg_highlight-hard_100_f5f3e5_1x100.png +0 -0
  131. data/templates/jrails/jquery.ui/south-street/ui-bg_highlight-soft_25_67b021_1x100.png +0 -0
  132. data/templates/jrails/jquery.ui/south-street/ui-bg_highlight-soft_95_ffedad_1x100.png +0 -0
  133. data/templates/jrails/jquery.ui/south-street/ui-icons_847e71_256x240.png +0 -0
  134. data/templates/jrails/jquery.ui/south-street.scss +38 -43
  135. data/templates/jrails/jquery.ui/start/ui-bg_glass_55_f8da4e_1x400.png +0 -0
  136. data/templates/jrails/jquery.ui/start/ui-bg_gloss-wave_75_2191c0_500x100.png +0 -0
  137. data/templates/jrails/jquery.ui/start/ui-icons_056b93_256x240.png +0 -0
  138. data/templates/jrails/jquery.ui/start/ui-icons_d8e7f3_256x240.png +0 -0
  139. data/templates/jrails/jquery.ui/start/ui-icons_f7a50d_256x240.png +0 -0
  140. data/templates/jrails/jquery.ui/start/ui-icons_fcd113_256x240.png +0 -0
  141. data/templates/jrails/jquery.ui/start.scss +38 -43
  142. data/templates/jrails/jquery.ui/sunny/ui-bg_diagonals-medium_20_d34d17_40x40.png +0 -0
  143. data/templates/jrails/jquery.ui/sunny/ui-bg_gloss-wave_60_fece2f_500x100.png +0 -0
  144. data/templates/jrails/jquery.ui/sunny/ui-bg_gloss-wave_90_fff9e5_500x100.png +0 -0
  145. data/templates/jrails/jquery.ui/sunny/ui-bg_highlight-soft_100_feeebd_1x100.png +0 -0
  146. data/templates/jrails/jquery.ui/sunny/ui-icons_3d3d3d_256x240.png +0 -0
  147. data/templates/jrails/jquery.ui/sunny/ui-icons_d19405_256x240.png +0 -0
  148. data/templates/jrails/jquery.ui/sunny/ui-icons_eb990f_256x240.png +0 -0
  149. data/templates/jrails/jquery.ui/sunny/ui-icons_ffe180_256x240.png +0 -0
  150. data/templates/jrails/jquery.ui/sunny.scss +38 -43
  151. data/templates/jrails/jquery.ui/swanky-purse/ui-bg_diamond_10_4f4221_10x8.png +0 -0
  152. data/templates/jrails/jquery.ui/swanky-purse/ui-bg_diamond_8_443113_10x8.png +0 -0
  153. data/templates/jrails/jquery.ui/swanky-purse/ui-bg_highlight-hard_65_fee4bd_1x100.png +0 -0
  154. data/templates/jrails/jquery.ui/swanky-purse/ui-icons_e8e2b5_256x240.png +0 -0
  155. data/templates/jrails/jquery.ui/swanky-purse/ui-icons_f9f2bd_256x240.png +0 -0
  156. data/templates/jrails/jquery.ui/swanky-purse/ui-icons_ff7519_256x240.png +0 -0
  157. data/templates/jrails/jquery.ui/swanky-purse.scss +38 -43
  158. data/templates/jrails/jquery.ui/trontastic/ui-bg_diagonals-small_50_262626_40x40.png +0 -0
  159. data/templates/jrails/jquery.ui/trontastic/ui-bg_flat_0_4c4c4c_40x100.png +0 -0
  160. data/templates/jrails/jquery.ui/trontastic/ui-bg_gloss-wave_85_9fda58_500x100.png +0 -0
  161. data/templates/jrails/jquery.ui/trontastic/ui-bg_gloss-wave_95_f6ecd5_500x100.png +0 -0
  162. data/templates/jrails/jquery.ui/trontastic/ui-icons_9fda58_256x240.png +0 -0
  163. data/templates/jrails/jquery.ui/trontastic.scss +38 -43
  164. data/templates/jrails/jquery.ui/ui-darkness/ui-bg_glass_40_0078a3_1x400.png +0 -0
  165. data/templates/jrails/jquery.ui/ui-darkness/ui-icons_a83300_256x240.png +0 -0
  166. data/templates/jrails/jquery.ui/ui-darkness.scss +38 -43
  167. data/templates/jrails/jquery.ui/ui-lightness/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  168. data/templates/jrails/jquery.ui/ui-lightness/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  169. data/templates/jrails/jquery.ui/ui-lightness/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  170. data/templates/jrails/jquery.ui/ui-lightness/ui-icons_228ef1_256x240.png +0 -0
  171. data/templates/jrails/jquery.ui/ui-lightness.scss +38 -43
  172. data/templates/jrails/jquery.ui/vader/ui-bg_highlight-soft_35_adadad_1x100.png +0 -0
  173. data/templates/jrails/jquery.ui/vader/ui-icons_bbbbbb_256x240.png +0 -0
  174. data/templates/jrails/jquery.ui/vader.scss +38 -43
  175. data/templates/jrails/jrails.min.js +4 -4
  176. data/templates/jrails/manifest.rb +0 -1
  177. data/templates/ribbon/jquery.ribbon.min.js +12 -12
  178. metadata +28 -4
@@ -1,32 +1,31 @@
1
- /*************************************************************************
1
+ /*
2
2
  jquery.dynatree.js
3
3
  Dynamic tree view control, with support for lazy loading of branches.
4
4
 
5
- Copyright (c) 2008-2010 Martin Wendt (http://wwWendt.de)
6
- Licensed under the MIT License (MIT-License.txt)
7
-
5
+ Copyright (c) 2008-2010, Martin Wendt (http://wwWendt.de)
6
+ Dual licensed under the MIT or GPL Version 2 licenses.
7
+ http://code.google.com/p/dynatree/wiki/LicenseInfo
8
+
8
9
  A current version and some documentation is available at
9
10
  http://dynatree.googlecode.com/
10
11
 
11
- Let me know, if you find bugs or improvements (martin at domain wwWendt.de).
12
-
13
- $Version: 0.5.3$
14
- $Revision: 313, 2010-03-15 15:55:09$
12
+ $Version:$
13
+ $Revision:$
15
14
 
16
15
  @depends: jquery.js
17
- @depends: ui.core.js
16
+ @depends: jquery.ui.core.js
18
17
  @depends: jquery.cookie.js
19
- *************************************************************************/
18
+ */
20
19
 
21
20
 
22
- /*************************************************************************
21
+ /*
23
22
  * Debug functions
24
23
  */
25
24
 
26
- var _canLog = true;
25
+ var _canLog = false;
27
26
 
28
27
  function _log(mode, msg) {
29
- /**
28
+ /*
30
29
  * Usage: logMsg("%o was toggled", this);
31
30
  */
32
31
  if( !_canLog )
@@ -64,10 +63,8 @@ function logMsg(msg) {
64
63
  // Forward declaration
65
64
  var getDynaTreePersistData = undefined;
66
65
 
67
-
68
-
69
- /*************************************************************************
70
- * Constants
66
+ /*
67
+ * Constants
71
68
  */
72
69
  var DTNodeStatus_Error = -1;
73
70
  var DTNodeStatus_Loading = 1;
@@ -77,7 +74,7 @@ var DTNodeStatus_Ok = 0;
77
74
  // Start of local namespace
78
75
  ;(function($) {
79
76
 
80
- /*************************************************************************
77
+ /*
81
78
  * Common tool functions.
82
79
  */
83
80
 
@@ -89,14 +86,24 @@ var Class = {
89
86
  }
90
87
  }
91
88
 
92
- /*************************************************************************
89
+ // Tool function to get dtnode from the event target:
90
+ function getDtNodeFromElement(el) {
91
+ var iMax = 5;
92
+ while( el && iMax-- ) {
93
+ if( el.dtnode ) return el.dtnode;
94
+ el = el.parentNode;
95
+ };
96
+ return null;
97
+ }
98
+
99
+ /*
93
100
  * Class DynaTreeNode
94
101
  */
95
102
  var DynaTreeNode = Class.create();
96
103
 
97
104
  DynaTreeNode.prototype = {
98
105
  initialize: function(parent, tree, data) {
99
- /**
106
+ /*
100
107
  * @constructor
101
108
  */
102
109
  this.parent = parent;
@@ -106,8 +113,10 @@ DynaTreeNode.prototype = {
106
113
  if( data.key == undefined )
107
114
  data.key = "_" + tree._nodeCount++;
108
115
  this.data = $.extend({}, $.ui.dynatree.nodedatadefaults, data);
109
- this.div = null; // not yet created
116
+ // this.div = null; // not yet created
117
+ this.li = null; // not yet created
110
118
  this.span = null; // not yet created
119
+ this.ul = null; // not yet created
111
120
  this.childList = null; // no subnodes yet
112
121
  // this.isRead = false; // Lazy content not yet read
113
122
  this.isLoading = false; // Lazy content is being loaded
@@ -140,11 +149,12 @@ DynaTreeNode.prototype = {
140
149
  var opts = this.tree.options;
141
150
  var cache = this.tree.cache;
142
151
  // parent connectors
143
- var rootParent = opts.rootVisible ? null : this.tree.tnRoot;
144
- var bHideFirstExpander = (opts.rootVisible && opts.minExpandLevel>0) || opts.minExpandLevel>1;
145
- var bHideFirstConnector = opts.rootVisible || opts.minExpandLevel>0;
146
-
152
+ // var rootParent = opts.rootVisible ? null : this.tree.tnRoot;
153
+ // var bHideFirstExpander = (opts.rootVisible && opts.minExpandLevel>0) || opts.minExpandLevel>1;
154
+ // var bHideFirstConnector = opts.rootVisible || opts.minExpandLevel>0;
155
+ var level = this.getLevel();
147
156
  var res = "";
157
+ /*
148
158
  var p = this.parent;
149
159
  while( p ) {
150
160
  // Suppress first connector column, if visible top level is always expanded
@@ -153,10 +163,11 @@ DynaTreeNode.prototype = {
153
163
  res = ( p.isLastSibling() ? cache.tagEmpty : cache.tagVline) + res;
154
164
  p = p.parent;
155
165
  }
156
-
166
+ */
157
167
  // connector (expanded, expandable or simple)
158
- if( bHideFirstExpander && this.parent==rootParent ) {
159
- // skip connector
168
+
169
+ if( level < opts.minExpandLevel ) {
170
+ // skip expander/connector
160
171
  } else if ( this.childList || this.data.isLazy ) {
161
172
  res += cache.tagExpander;
162
173
  } else {
@@ -184,101 +195,145 @@ DynaTreeNode.prototype = {
184
195
  return res;
185
196
  },
186
197
 
198
+
187
199
  _fixOrder: function() {
188
- /**
189
- * Make sure, that <div> order matches childList order.
200
+ /*
201
+ * Make sure, that <li> order matches childList order.
190
202
  */
191
203
  var cl = this.childList;
192
204
  if( !cl )
193
205
  return;
194
- var childDiv = this.div.firstChild.nextSibling;
206
+ var childLI = this.ul.firstChild;
195
207
  for(var i=0; i<cl.length-1; i++) {
196
208
  var childNode1 = cl[i];
197
- var childNode2 = childDiv.firstChild.dtnode;
209
+ var childNode2 = childLI.dtnode;
198
210
  if( childNode1 !== childNode2 ) {
199
- //
200
211
  this.tree.logDebug("_fixOrder: mismatch at index " + i + ": " + childNode1 + " != " + childNode2);
201
- this.div.insertBefore(childNode1.div, childNode2.div);
212
+ this.ul.insertBefore(childNode1.li, childNode2.li);
202
213
  } else {
203
- childDiv = childDiv.nextSibling;
214
+ childLI = childLI.nextSibling;
204
215
  }
205
216
  }
206
- },
207
-
208
- render: function(bDeep, bHidden) {
209
- /**
210
- * Create HTML markup for this node.
217
+ },
218
+
219
+ render: function(useEffects) {
220
+ /*
221
+ * create <li><span>..</span> .. </li> tags for this node.
211
222
  *
212
- * <div> // This div contains the node's span and list of child div's.
213
- * <span id='key'>S S S A</span> // Span contains graphic spans and title <a> tag
214
- * <div>child1</div>
215
- * <div>child2</div>
216
- * </div>
223
+ * <li id='key'> // This div contains the node's span and list of child div's.
224
+ * <span class='title'>S S S A</span> // Span contains graphic spans and title <a> tag
225
+ * <ul> // only present, when node has children
226
+ * <li>child1</li>
227
+ * <li>child2</li>
228
+ * </ul>
229
+ * </li>
217
230
  */
218
- // this.tree.logDebug("%o.render()", this);
231
+ this.tree.logDebug("%o.render(%s)", this, useEffects);
232
+ // ---
219
233
  var opts = this.tree.options;
220
234
  var cn = opts.classNames;
221
235
  var isLastSib = this.isLastSibling();
222
- // ---
223
- if( ! this.div ) {
224
- this.span = document.createElement("span");
225
- this.span.dtnode = this;
226
- if( this.data.key )
227
- this.span.id = this.tree.options.idPrefix + this.data.key;
228
- this.div = document.createElement("div");
229
- this.div.appendChild(this.span);
230
-
231
- if ( this.parent ) {
232
- this.parent.div.appendChild(this.div);
236
+
237
+ if( !this.parent && !this.ul ) {
238
+ // Root node has only a <ul>
239
+ this.li = this.span = null;
240
+ this.ul = document.createElement("ul");
241
+ if( opts.minExpandLevel > 1 )
242
+ this.ul.className = cn.container + " " + cn.noConnector;
243
+ else
244
+ this.ul.className = cn.container;
245
+
246
+ } else if( this.parent ) {
247
+ // Create <li><span /> </li>
248
+ if( ! this.li ) {
249
+ this.li = document.createElement("li");
250
+ this.li.dtnode = this;
251
+ if( this.data.key && opts.generateIds )
252
+ this.li.id = opts.idPrefix + this.data.key;
253
+
254
+ this.span = document.createElement("span");
255
+ this.span.className = cn.title;
256
+ this.li.appendChild(this.span);
257
+
258
+ if( !this.parent.ul ) {
259
+ // This is the parent's first child: create UL tag
260
+ // (Hidden, because it will be
261
+ this.parent.ul = document.createElement("ul");
262
+ this.parent.ul.style.display = "none";
263
+ this.parent.li.appendChild(this.parent.ul);
264
+ }
265
+ this.parent.ul.appendChild(this.li);
233
266
  }
267
+ // set node connector images, links and text
268
+ this.span.innerHTML = this._getInnerHtml();
269
+
270
+ // Set classes for current status
271
+ var cnList = [];
272
+ cnList.push(cn.node);
273
+ if( this.data.isFolder )
274
+ cnList.push(cn.folder);
275
+ if( this.bExpanded )
276
+ cnList.push(cn.expanded);
277
+ if( this.childList != null )
278
+ cnList.push(cn.hasChildren);
279
+ // if( this.data.isLazy && !this.isRead )
280
+ if( this.data.isLazy && this.childList==null )
281
+ cnList.push(cn.lazy);
282
+ if( isLastSib )
283
+ cnList.push(cn.lastsib);
284
+ if( this.bSelected )
285
+ cnList.push(cn.selected);
286
+ if( this.hasSubSel )
287
+ cnList.push(cn.partsel);
288
+ if( this.tree.activeNode === this )
289
+ cnList.push(cn.active);
290
+ if( this.data.addClass )
291
+ cnList.push(this.data.addClass);
292
+ // IE6 doesn't correctly evaluate multiple class names,
293
+ // so we create combined class names that can be used in the CSS
294
+ cnList.push(cn.combinedExpanderPrefix
295
+ + (this.bExpanded ? "e" : "c")
296
+ + (this.data.isLazy && this.childList==null ? "d" : "")
297
+ + (isLastSib ? "l" : "")
298
+ );
299
+ cnList.push(cn.combinedIconPrefix
300
+ + (this.bExpanded ? "e" : "c")
301
+ + (this.data.isFolder ? "f" : "")
302
+ );
303
+ this.span.className = cnList.join(" ");
304
+
305
+ // TODO: we should not set this in the <span> tag also, if we set it here:
306
+ this.li.className = isLastSib ? cn.lastsib : "";
307
+
308
+ // Hide children, if node is collapsed
309
+ // this.ul.style.display = ( this.bExpanded || !this.parent ) ? "" : "none";
310
+ }
234
311
 
235
- if( this.parent==null && !this.tree.options.rootVisible )
236
- this.span.style.display = "none";
237
- }
238
- // set node connector images, links and text
239
- this.span.innerHTML = this._getInnerHtml();
240
-
241
- // hide this node, if parent is collapsed
242
- this.div.style.display = ( this.parent==null || this.parent.bExpanded ? "" : "none");
243
-
244
- // Set classes for current status
245
- var cnList = [];
246
- cnList.push( ( this.data.isFolder ) ? cn.folder : cn.document );
247
- if( this.bExpanded )
248
- cnList.push(cn.expanded);
249
- if( this.childList != null )
250
- cnList.push(cn.hasChildren);
251
- if( this.data.isLazy && this.childList==null )
252
- cnList.push(cn.lazy);
253
- if( isLastSib )
254
- cnList.push(cn.lastsib);
255
- if( this.bSelected )
256
- cnList.push(cn.selected);
257
- if( this.hasSubSel )
258
- cnList.push(cn.partsel);
259
- if( this.tree.activeNode === this )
260
- cnList.push(cn.active);
261
- if( this.data.addClass )
262
- cnList.push(this.data.addClass);
263
- // IE6 doesn't correctly evaluate multiple class names,
264
- // so we create combined class names that can be used in the CSS
265
- cnList.push(cn.combinedExpanderPrefix
266
- + (this.bExpanded ? "e" : "c")
267
- + (this.data.isLazy && this.childList==null ? "d" : "")
268
- + (isLastSib ? "l" : "")
269
- );
270
- cnList.push(cn.combinedIconPrefix
271
- + (this.bExpanded ? "e" : "c")
272
- + (this.data.isFolder ? "f" : "")
273
- );
274
- this.span.className = cnList.join(" ");
275
-
276
- if( bDeep && this.childList && (bHidden || this.bExpanded) ) {
312
+ if( this.bExpanded && this.childList ) {
277
313
  for(var i=0; i<this.childList.length; i++) {
278
- this.childList[i].render(bDeep, bHidden)
314
+ this.childList[i].render();
279
315
  }
280
316
  this._fixOrder();
281
317
  }
318
+ // Hide children, if node is collapsed
319
+ if( this.ul ) {
320
+ var isHidden = (this.ul.style.display == "none");
321
+ // logMsg("isHidden:%s", isHidden);
322
+ if( useEffects && opts.fx && !!isHidden == !!this.bExpanded ) {
323
+ var duration = opts.fx.duration || 200;
324
+ $(this.ul).animate(opts.fx, duration);
325
+ } else {
326
+ this.ul.style.display = ( this.bExpanded || !this.parent ) ? "" : "none";
327
+ }
328
+ }
329
+ },
330
+
331
+ getParent: function() {
332
+ return this.parent;
333
+ },
334
+
335
+ getChildren: function() {
336
+ return this.childList;
282
337
  },
283
338
 
284
339
  hasChildren: function() {
@@ -291,7 +346,7 @@ DynaTreeNode.prototype = {
291
346
  return p.childList[p.childList.length-1] === this;
292
347
  },
293
348
 
294
- prevSibling: function() {
349
+ getPrevSibling: function() {
295
350
  if( !this.parent ) return null;
296
351
  var ac = this.parent.childList;
297
352
  for(var i=1; i<ac.length; i++) // start with 1, so prev(first) = null
@@ -300,7 +355,7 @@ DynaTreeNode.prototype = {
300
355
  return null;
301
356
  },
302
357
 
303
- nextSibling: function() {
358
+ getNextSibling: function() {
304
359
  if( !this.parent ) return null;
305
360
  var ac = this.parent.childList;
306
361
  for(var i=0; i<ac.length-1; i++) // up to length-2, so next(last) = null
@@ -308,13 +363,56 @@ DynaTreeNode.prototype = {
308
363
  return ac[i+1];
309
364
  return null;
310
365
  },
311
-
366
+
367
+ isStatusNode: function() {
368
+ return (this.data.isStatusNode === true);
369
+ },
370
+
371
+ isChildOf: function(otherNode) {
372
+ return (this.parent && this.parent === otherNode);
373
+ },
374
+
375
+ isDescendantOf: function(otherNode) {
376
+ if(!otherNode)
377
+ return false;
378
+ var p = this.parent;
379
+ while( p ) {
380
+ if( p===otherNode )
381
+ return true;
382
+ p = p.parent;
383
+ }
384
+ return false;
385
+ },
386
+
387
+ sortChildren: function(cmp, deep) {
388
+ /*
389
+ * Sort child list by title.
390
+ * cmd: optional comapre function.
391
+ * deep: optional: pass true to sort all descendant nodes.
392
+ */
393
+ var cl = this.childList;
394
+ if( !cl )
395
+ return;
396
+ cmp = cmp || function(a, b) {
397
+ return a.data.title === b.data.title ? 0 : a.data.title > b.data.title;
398
+ };
399
+ cl.sort(cmp);
400
+ if( deep ){
401
+ for(var i=0; i<cl.length; i++){
402
+ if( cl[i].childList )
403
+ cl[i].sortChildren(cmp, "$norender$");
404
+ }
405
+ }
406
+ if( deep !== "$norender$" )
407
+ this.render();
408
+ },
409
+
312
410
  _setStatusNode: function(data) {
313
411
  // Create, modify or remove the status child node (pass 'null', to remove it).
314
412
  var firstChild = ( this.childList ? this.childList[0] : null );
315
413
  if( !data ) {
316
414
  if ( firstChild ) {
317
- this.div.removeChild(firstChild.div);
415
+ this.ul.removeChild(firstChild.li);
318
416
  if( this.childList.length == 1 )
319
417
  this.childList = null;
320
418
  else
@@ -323,7 +421,7 @@ DynaTreeNode.prototype = {
323
421
  } else if ( firstChild ) {
324
422
  data.isStatusNode = true;
325
423
  firstChild.data = data;
326
- firstChild.render(false, false);
424
+ firstChild.render();
327
425
  } else {
328
426
  data.isStatusNode = true;
329
427
  firstChild = this.addChild(data);
@@ -338,9 +436,10 @@ DynaTreeNode.prototype = {
338
436
  this._setStatusNode(null);
339
437
  // this.isRead = true;
340
438
  this.isLoading = false;
341
- this.render(false, false);
439
+ this.render();
342
440
  if( this.tree.options.autoFocus ) {
343
- if( this === this.tree.tnRoot && !this.tree.options.rootVisible && this.childList ) {
441
+ // if( this === this.tree.tnRoot && !this.tree.options.rootVisible && this.childList ) {
442
+ if( this === this.tree.tnRoot && this.childList ) {
344
443
  // special case: using ajaxInit
345
444
  this.childList[0].focus();
346
445
  } else {
@@ -381,6 +480,9 @@ DynaTreeNode.prototype = {
381
480
  },
382
481
 
383
482
  getLevel: function() {
483
+ /*
484
+ * Return node depth. 0: System root node, 1: visible top-level node.
485
+ */
384
486
  var level = 0;
385
487
  var dtn = this.parent;
386
488
  while( dtn ) {
@@ -391,7 +493,7 @@ DynaTreeNode.prototype = {
391
493
  },
392
494
 
393
495
  _getTypeForOuterNodeEvent: function(event) {
394
- /** Return the inner node span (title, checkbox or expander) if
496
+ /* Return the inner node span (title, checkbox or expander) if
395
497
  * event.target points to the outer span.
396
498
  * This function should fix issue #93:
397
499
  * FF2 ignores empty spans, when generating events (returning the parent instead).
@@ -399,8 +501,7 @@ DynaTreeNode.prototype = {
399
501
  var cns = this.tree.options.classNames;
400
502
  var target = event.target;
401
503
  // Only process clicks on an outer node span (probably due to a FF2 event handling bug)
402
- if( target.className.indexOf(cns.folder)<0
403
- && target.className.indexOf(cns.document)<0 ) {
504
+ if( target.className.indexOf(cns.node)<0 ) {
404
505
  return null
405
506
  }
406
507
  // Event coordinates, relative to outer node span:
@@ -430,7 +531,7 @@ DynaTreeNode.prototype = {
430
531
 
431
532
  getEventTargetType: function(event) {
432
533
  // Return the part of a node, that a click event occured on.
433
- // Note: there is no check, if the was fired on TIHS node.
534
+ // Note: there is no check, if the event was fired on TIHS node.
434
535
  var tcn = event && event.target ? event.target.className : "";
435
536
  var cns = this.tree.options.classNames;
436
537
 
@@ -444,7 +545,7 @@ DynaTreeNode.prototype = {
444
545
  return "icon";
445
546
  else if( tcn==cns.empty || tcn==cns.vline || tcn==cns.connector )
446
547
  return "prefix";
447
- else if( tcn.indexOf(cns.folder)>=0 || tcn.indexOf(cns.document)>=0 )
548
+ else if( tcn.indexOf(cns.node)>=0 )
448
549
  // FIX issue #93
449
550
  return this._getTypeForOuterNodeEvent(event);
450
551
  return null;
@@ -549,7 +650,8 @@ DynaTreeNode.prototype = {
549
650
  break;
550
651
  }
551
652
  }
552
- if( this.parent == null && this.tree.options.minExpandLevel>0 ) {
653
+ // if( this.parent == null && this.tree.options.minExpandLevel>0 ) {
654
+ if( this.parent == null ) {
553
655
  expand = false;
554
656
  }
555
657
  if( expand ) {
@@ -705,9 +807,8 @@ DynaTreeNode.prototype = {
705
807
  this.tree.logDebug("_loadContent: succeeded - %o", this);
706
808
  }
707
809
  } catch(e) {
708
- // alert(e);
709
- this.setLazyNodeStatus(DTNodeStatus_Error);
710
810
  this.tree.logWarning("_loadContent: failed - %o", e);
811
+ this.setLazyNodeStatus(DTNodeStatus_Error, {tooltip: ""+e});
711
812
  }
712
813
  },
713
814
 
@@ -718,8 +819,8 @@ DynaTreeNode.prototype = {
718
819
  return;
719
820
  }
720
821
  var opts = this.tree.options;
721
- if( !bExpand && this.getLevel()<opts.minExpandLevel ) {
722
- this.tree.logDebug("dtnode._expand(%o) forced expand - %o", bExpand, this);
822
+ if( !bExpand && this.getLevel() < opts.minExpandLevel ) {
823
+ this.tree.logDebug("dtnode._expand(%o) prevented collapse - %o", bExpand, this);
723
824
  return;
724
825
  }
725
826
  if ( opts.onQueryExpand && opts.onQueryExpand.call(this.span, bExpand, this) == false )
@@ -733,8 +834,9 @@ DynaTreeNode.prototype = {
733
834
  else
734
835
  this.tree.persistence.clearExpand(this.data.key);
735
836
  }
736
-
737
- this.render(false);
837
+ // Do not apply animations in init phase, or before lazy-loading
838
+ var allowEffects = !(this.data.isLazy && this.childList==null) && !this.isLoading;
839
+ this.render(allowEffects);
738
840
 
739
841
  // Auto-collapse mode: collapse all siblings
740
842
  if( this.bExpanded && this.parent && opts.autoCollapse ) {
@@ -753,39 +855,17 @@ DynaTreeNode.prototype = {
753
855
  return;
754
856
  }
755
857
  // this.tree.logDebug("_expand: start div toggle - %o", this);
756
-
757
- var fxDuration = opts.fx ? (opts.fx.duration || 200) : 0;
758
- if( this.childList ) {
759
- for(var i=0; i<this.childList.length; i++ ) {
760
- var $child = $(this.childList[i].div);
761
- if( fxDuration ) {
762
- // This is a toggle, so only do it, if not already rendered (in)visible (issue 98)
763
- if( bExpand != $child.is(':visible') )
764
- $child.animate(opts.fx, fxDuration);
765
- } else {
766
- if( bExpand )
767
- $child.show();
768
- else
769
- $child.hide(); // TODO: this seems to be slow, when called the first time for an element
770
- }
771
- }
772
- }
773
-
774
- /* issue 109: using selector filter is really SLOW.
775
- // issue 98: only toggle, if render hasn't set visibility already:
776
- var filter = ">DIV" + (bExpand ? ":hidden" : ":visible");
777
-
858
+ /*
778
859
  if( opts.fx ) {
860
+ this.render(true);
779
861
  var duration = opts.fx.duration || 200;
780
- // $(">DIV", this.div).animate(opts.fx, duration);
781
- $(filter, this.div).animate(opts.fx, duration);
862
+ $(this.ul).animate(opts.fx, duration);
782
863
  } else {
783
- $(filter, this.div).toggle();
784
- // var $d = $(">DIV", this.div);
785
- // this.tree.logDebug("_expand: got div, start toggle - %o", this);
786
- // $d.toggle();
864
+ this.render();
865
+ logMsg("_expand: got div, start toggle - %o", this);
787
866
  }
788
- //*/
867
+ */
868
+
789
869
  // this.tree.logDebug("_expand: end div toggle - %o", this);
790
870
 
791
871
  if ( opts.onExpand )
@@ -795,11 +875,42 @@ DynaTreeNode.prototype = {
795
875
  expand: function(flag) {
796
876
  if( !this.childList && !this.data.isLazy && flag )
797
877
  return; // Prevent expanding empty nodes
798
- if( this.parent == null && this.tree.options.minExpandLevel>0 && !flag )
878
+ // if( this.parent == null && this.tree.options.minExpandLevel>0 && !flag )
879
+ if( this.parent == null && !flag )
799
880
  return; // Prevent collapsing the root
800
881
  this._expand(flag);
801
882
  },
802
883
 
884
+ scheduleAction: function(mode, ms) {
885
+ /* Schedule activity for delayed execution (cancel any pending request).
886
+ * scheduleAction('cancel') will cancel the request.
887
+ */
888
+ if( this.tree.timer ) {
889
+ clearTimeout(this.tree.timer);
890
+ logMsg("clearTimeout(%o)", this.tree.timer);
891
+ }
892
+ var self = this; // required for closures
893
+ switch (mode) {
894
+ case "cancel":
895
+ // Simply made sure that timer was cleared
896
+ break;
897
+ case "expand":
898
+ this.tree.timer = setTimeout(function(){
899
+ logMsg("setTimeout: trigger");
900
+ self.expand(true);
901
+ }, ms);
902
+ break;
903
+ case "activate":
904
+ this.tree.timer = setTimeout(function(){
905
+ self.activate();
906
+ }, ms);
907
+ break;
908
+ default:
909
+ throw "Invalid mode " + mode;
910
+ }
911
+ logMsg("setTimeout(%s, %s): %s", mode, ms, this.tree.timer);
912
+ },
913
+
803
914
  toggleExpand: function() {
804
915
  this.expand(!this.bExpanded);
805
916
  },
@@ -874,7 +985,8 @@ DynaTreeNode.prototype = {
874
985
  if( this.bExpanded ) {
875
986
  this.toggleExpand();
876
987
  this.focus();
877
- } else if( this.parent && (this.tree.options.rootVisible || this.parent.parent) ) {
988
+ // } else if( this.parent && (this.tree.options.rootVisible || this.parent.parent) ) {
989
+ } else if( this.parent && this.parent.parent ) {
878
990
  this.parent.focus();
879
991
  }
880
992
  break;
@@ -887,10 +999,11 @@ DynaTreeNode.prototype = {
887
999
  }
888
1000
  break;
889
1001
  case 38: // <up>
890
- var sib = this.prevSibling();
1002
+ var sib = this.getPrevSibling();
891
1003
  while( sib && sib.bExpanded && sib.childList )
892
1004
  sib = sib.childList[sib.childList.length-1];
893
- if( !sib && this.parent && (this.tree.options.rootVisible || this.parent.parent) )
1005
+ // if( !sib && this.parent && (this.tree.options.rootVisible || this.parent.parent) )
1006
+ if( !sib && this.parent && this.parent.parent )
894
1007
  sib = this.parent;
895
1008
  if( sib ) sib.focus();
896
1009
  break;
@@ -901,7 +1014,7 @@ DynaTreeNode.prototype = {
901
1014
  } else {
902
1015
  var parents = this._parentList(false, true);
903
1016
  for(var i=parents.length-1; i>=0; i--) {
904
- sib = parents[i].nextSibling();
1017
+ sib = parents[i].getNextSibling();
905
1018
  if( sib ) break;
906
1019
  }
907
1020
  }
@@ -952,8 +1065,8 @@ DynaTreeNode.prototype = {
952
1065
  visit: function(fn, data, includeSelf) {
953
1066
  // Call fn(dtnode, data) for all child nodes. Stop iteration, if fn() returns false.
954
1067
  var n = 0;
955
- if( includeSelf == true ) {
956
- if( fn(this, data) == false )
1068
+ if( includeSelf === true ) {
1069
+ if( fn(this, data) === false )
957
1070
  return 1;
958
1071
  n++;
959
1072
  }
@@ -963,11 +1076,24 @@ DynaTreeNode.prototype = {
963
1076
  return n;
964
1077
  },
965
1078
 
1079
+ visitParents: function(fn, includeSelf) {
1080
+ // Visit parent nodes (bottom up)
1081
+ if(includeSelf && fn(this) === false) {
1082
+ return false;
1083
+ }
1084
+ var p = this.parent;
1085
+ while( p ) {
1086
+ if(fn(p) === false)
1087
+ return false;
1088
+ p = p.parent;
1089
+ }
1090
+ },
1091
+
966
1092
  remove: function() {
967
1093
  // Remove this node
968
1094
  // this.tree.logDebug ("%o.remove()", this);
969
1095
  if ( this === this.tree.root )
970
- return false;
1096
+ throw "Cannot remove system root";
971
1097
  return this.parent.removeChild(this);
972
1098
  },
973
1099
 
@@ -988,7 +1114,8 @@ DynaTreeNode.prototype = {
988
1114
  this.tree.persistence.clearExpand(tn.data.key);
989
1115
  }
990
1116
  tn.removeChildren(true);
991
- this.div.removeChild(tn.div);
1117
+ // this.div.removeChild(tn.div);
1118
+ this.ul.removeChild(tn.li);
992
1119
  for(var i=0; i<ac.length; i++) {
993
1120
  if( ac[i] === tn ) {
994
1121
  this.childList.splice(i, 1);
@@ -1016,7 +1143,9 @@ DynaTreeNode.prototype = {
1016
1143
  this.tree.persistence.clearExpand(tn.data.key);
1017
1144
  }
1018
1145
  tn.removeChildren(true, retainPersistence);
1019
- this.div.removeChild(tn.div);
1146
+ // this.div.removeChild(tn.div);
1147
+ if( this.ul )
1148
+ this.ul.removeChild(tn.li);
1020
1149
  delete tn;
1021
1150
  }
1022
1151
  this.childList = null;
@@ -1025,7 +1154,7 @@ DynaTreeNode.prototype = {
1025
1154
  // this._expand(false);
1026
1155
  // this.isRead = false;
1027
1156
  this.isLoading = false;
1028
- this.render(false, false);
1157
+ this.render();
1029
1158
  }
1030
1159
  },
1031
1160
 
@@ -1048,9 +1177,8 @@ DynaTreeNode.prototype = {
1048
1177
  },
1049
1178
 
1050
1179
  _addChildNode: function(dtnode, beforeNode) {
1051
- /**
1180
+ /*
1052
1181
  * Internal function to add one single DynatreeNode as a child.
1053
- *
1054
1182
  */
1055
1183
  var tree = this.tree;
1056
1184
  var opts = tree.options;
@@ -1064,7 +1192,7 @@ DynaTreeNode.prototype = {
1064
1192
  // throw "<beforeNode> must be another child of <this>";
1065
1193
 
1066
1194
  // --- Add dtnode as a child
1067
- if ( this.childList==null ) {
1195
+ if ( this.childList === null ) {
1068
1196
  this.childList = [];
1069
1197
  } else if( ! beforeNode ) {
1070
1198
  // Fix 'lastsib'
@@ -1148,13 +1276,13 @@ DynaTreeNode.prototype = {
1148
1276
  }
1149
1277
  // render this node and the new child
1150
1278
  if ( tree.bEnableUpdate )
1151
- this.render(true, true);
1279
+ this.render();
1152
1280
 
1153
1281
  return dtnode;
1154
1282
  },
1155
1283
 
1156
1284
  addChild: function(obj, beforeNode) {
1157
- /**
1285
+ /*
1158
1286
  * Add a node object as child.
1159
1287
  *
1160
1288
  * This should be the only place, where a DynaTreeNode is constructed!
@@ -1207,7 +1335,7 @@ DynaTreeNode.prototype = {
1207
1335
  appendAjax: function(ajaxOptions) {
1208
1336
  this.removeChildren(false, true);
1209
1337
  this.setLazyNodeStatus(DTNodeStatus_Loading);
1210
- // Ajax option inheritance: $.ajaxSetup < $.ui.dynatree.defaults.ajaxDefaults < tree.options.ajaxDefaults < ajaxOptions
1338
+ // Ajax option inheritance: $.ajaxSetup < $.ui.dynatree.prototype.options.ajaxDefaults < tree.options.ajaxDefaults < ajaxOptions
1211
1339
  var self = this;
1212
1340
  var orgSuccess = ajaxOptions.success;
1213
1341
  var orgError = ajaxOptions.error;
@@ -1233,7 +1361,6 @@ DynaTreeNode.prototype = {
1233
1361
  },
1234
1362
  error: function(XMLHttpRequest, textStatus, errorThrown){
1235
1363
  // <this> is the request options
1236
- // self.tree.logWarning("appendAjax failed: %o:\n%o\n%o", textStatus, XMLHttpRequest, errorThrown);
1237
1364
  self.tree.logWarning("appendAjax failed:", textStatus, ":\n", XMLHttpRequest, "\n", errorThrown);
1238
1365
  self.setLazyNodeStatus(DTNodeStatus_Error, {info: textStatus, tooltip: ""+errorThrown});
1239
1366
  if( orgError )
@@ -1242,11 +1369,124 @@ DynaTreeNode.prototype = {
1242
1369
  });
1243
1370
  $.ajax(options);
1244
1371
  },
1372
+
1373
+ move: function(targetNode, mode) {
1374
+ /* Move this node to targetNode.
1375
+ * mode 'child': append this node as last child of targetNode.
1376
+ * This is the default. To be compatble with the D'n'd
1377
+ * hitMode, we also accept 'over'.
1378
+ * mode 'before': add this node as sibling before targetNode.
1379
+ * mode 'after': add this node as sibling after targetNode.
1380
+ */
1381
+ if(this === targetNode)
1382
+ return;
1383
+ if( !this.parent )
1384
+ throw "Cannot move system root";
1385
+ if(mode === undefined || mode == "over")
1386
+ mode = "child";
1387
+ var prevParent = this.parent;
1388
+ var targetParent = (mode === "child") ? targetNode : targetNode.parent;
1389
+ if( targetParent.isDescendantOf(this) )
1390
+ throw "Cannot move a node to it's own descendant";
1391
+
1392
+ // Unlink this node from current parent
1393
+ if( this.parent.childList.length == 1 ) {
1394
+ this.parent.childList = null;
1395
+ this.parent.bExpanded = false;
1396
+ } else {
1397
+ var pos = $.inArray(this, this.parent.childList);
1398
+ if( pos < 0 )
1399
+ throw "Internal error";
1400
+ this.parent.childList.splice(pos, 1);
1401
+ }
1402
+ this.parent.ul.removeChild(this.li);
1403
+ this.li = null;
1404
+
1405
+ // Insert this node to target parent's child list
1406
+ this.parent = targetParent;
1407
+ if( targetParent.hasChildren() ) {
1408
+ switch(mode) {
1409
+ case "child":
1410
+ // Append to existing target children
1411
+ targetParent.childList.push(this);
1412
+ break;
1413
+ case "before":
1414
+ // Insert this node before target node
1415
+ var pos = $.inArray(targetNode, targetParent.childList);
1416
+ if( pos < 0 )
1417
+ throw "Internal error";
1418
+ targetParent.childList.splice(pos, 0, this);
1419
+ break;
1420
+ case "after":
1421
+ // Insert this node after target node
1422
+ var pos = $.inArray(targetNode, targetParent.childList);
1423
+ if( pos < 0 )
1424
+ throw "Internal error";
1425
+ targetParent.childList.splice(pos+1, 0, this);
1426
+ break;
1427
+ default:
1428
+ throw "Invalid mode " + mode;
1429
+ }
1430
+ } else {
1431
+ targetParent.childList = [ this ];
1432
+ }
1433
+ if( this.tree !== targetNode.tree ) {
1434
+ // Fix node.tree for all source nodes
1435
+ this.visit(function(dtnode){
1436
+ dtnode.tree = targetNode.tree;
1437
+ }, null, true);
1438
+ throw "Not yet implemented.";
1439
+ }
1440
+ // TODO: fix selection state
1441
+ // TODO: fix active state
1442
+ if( !prevParent.isDescendantOf(targetParent)) {
1443
+ prevParent.render();
1444
+ }
1445
+ if( !targetParent.isDescendantOf(prevParent) ) {
1446
+ targetParent.render();
1447
+ }
1448
+ // this.tree.redraw();
1449
+ /*
1450
+ var tree = this.tree;
1451
+ var opts = tree.options;
1452
+ var pers = tree.persistence;
1453
+
1454
+
1455
+ // Always expand, if it's below minExpandLevel
1456
+ // tree.logDebug ("%o._addChildNode(%o), l=%o", this, dtnode, dtnode.getLevel());
1457
+ if ( opts.minExpandLevel >= dtnode.getLevel() ) {
1458
+ // tree.logDebug ("Force expand for %o", dtnode);
1459
+ this.bExpanded = true;
1460
+ }
1461
+
1462
+ // In multi-hier mode, update the parents selection state
1463
+ // issue #82: only if not initializing, because the children may not exist yet
1464
+ // if( !dtnode.data.isStatusNode && opts.selectMode==3 && !isInitializing )
1465
+ // dtnode._fixSelectionState();
1466
+
1467
+ // In multi-hier mode, update the parents selection state
1468
+ if( dtnode.bSelected && opts.selectMode==3 ) {
1469
+ var p = this;
1470
+ while( p ) {
1471
+ if( !p.hasSubSel )
1472
+ p._setSubSel(true);
1473
+ p = p.parent;
1474
+ }
1475
+ }
1476
+ // render this node and the new child
1477
+ if ( tree.bEnableUpdate )
1478
+ this.render();
1479
+
1480
+ return dtnode;
1481
+
1482
+ */
1483
+ },
1484
+
1245
1485
  // --- end of class
1246
1486
  lastentry: undefined
1247
1487
  }
1248
1488
 
1249
- /*************************************************************************
1489
+ /*
1250
1490
  * class DynaTreeStatus
1251
1491
  */
1252
1492
 
@@ -1268,8 +1508,8 @@ DynaTreeStatus.prototype = {
1268
1508
  initialize: function(cookieId, cookieOpts) {
1269
1509
  this._log("DynaTreeStatus: initialize");
1270
1510
  if( cookieId === undefined )
1271
- cookieId = $.ui.dynatree.defaults.cookieId;
1272
- cookieOpts = $.extend({}, $.ui.dynatree.defaults.cookie, cookieOpts);
1511
+ cookieId = $.ui.dynatree.prototype.options.cookieId;
1512
+ cookieOpts = $.extend({}, $.ui.dynatree.prototype.options.cookie, cookieOpts);
1273
1513
 
1274
1514
  this.cookieId = cookieId;
1275
1515
  this.cookieOpts = cookieOpts;
@@ -1359,8 +1599,7 @@ DynaTreeStatus.prototype = {
1359
1599
  lastentry: undefined
1360
1600
  };
1361
1601
 
1362
-
1363
- /*************************************************************************
1602
+ /*
1364
1603
  * class DynaTree
1365
1604
  */
1366
1605
 
@@ -1368,7 +1607,7 @@ var DynaTree = Class.create();
1368
1607
 
1369
1608
  // --- Static members ----------------------------------------------------------
1370
1609
 
1371
- DynaTree.version = "$Version: 0.5.3$";
1610
+ DynaTree.version = "$Version:$";
1372
1611
  /*
1373
1612
  DynaTree._initTree = function() {
1374
1613
  };
@@ -1387,8 +1626,11 @@ DynaTree.prototype = {
1387
1626
  this.$widget = $widget;
1388
1627
  this.options = $widget.options;
1389
1628
  this.$tree = $widget.element;
1629
+ this.timer = null;
1390
1630
  // find container element
1391
1631
  this.divTree = this.$tree.get(0);
1632
+ //
1633
+ _initDragAndDrop(this);
1392
1634
  },
1393
1635
 
1394
1636
  // member functions
@@ -1401,10 +1643,20 @@ DynaTree.prototype = {
1401
1643
  this.activeNode = null;
1402
1644
  this.focusNode = null;
1403
1645
 
1646
+ // Some deprecation warnings to help with migration
1647
+ if( opts.rootVisible !== undefined )
1648
+ _log("warn", "Option 'rootVisible' is no longer supported.");
1649
+ if( opts.title !== undefined )
1650
+ _log("warn", "Option 'title' is no longer supported.");
1651
+ if( opts.minExpandLevel < 1 ) {
1652
+ _log("warn", "Option 'minExpandLevel' must be >= 1.");
1653
+ opts.minExpandLevel = 1;
1654
+ }
1655
+
1404
1656
  // If a 'options.classNames' dictionary was passed, still use defaults
1405
1657
  // for undefined classes:
1406
- if( opts.classNames !== $.ui.dynatree.defaults.classNames ) {
1407
- opts.classNames = $.extend({}, $.ui.dynatree.defaults.classNames, opts.classNames);
1658
+ if( opts.classNames !== $.ui.dynatree.prototype.options.classNames ) {
1659
+ opts.classNames = $.extend({}, $.ui.dynatree.prototype.options.classNames, opts.classNames);
1408
1660
  }
1409
1661
  // Guess skin path, if not specified
1410
1662
  if(!opts.imagePath) {
@@ -1447,18 +1699,24 @@ DynaTree.prototype = {
1447
1699
  $(this.divTree).empty();
1448
1700
  else if( this.divRoot )
1449
1701
  $(this.divRoot).remove();
1450
-
1702
+ /*
1451
1703
  // create the root element
1452
1704
  this.tnRoot = new DynaTreeNode(null, this, {title: opts.title, key: "root"});
1453
1705
  this.tnRoot.data.isFolder = true;
1454
1706
  this.tnRoot.render(false, false);
1455
1707
  this.divRoot = this.tnRoot.div;
1456
1708
  this.divRoot.className = opts.classNames.container;
1709
+
1457
1710
  // add root to container
1458
1711
  // TODO: this should be delayed until all children have been created for performance reasons
1459
1712
  this.divTree.appendChild(this.divRoot);
1713
+ */
1714
+ // Create the root element
1715
+ this.tnRoot = new DynaTreeNode(null, this, {});
1716
+ this.tnRoot.render();
1717
+ this.divTree.appendChild(this.tnRoot.ul);
1460
1718
 
1461
- var root = this.tnRoot;
1719
+ var root = this.tnRoot;
1462
1720
  var isReloading = ( opts.persist && this.persistence.isReloading() );
1463
1721
  var isLazy = false;
1464
1722
  var prevFlag = this.enableUpdate(false);
@@ -1482,7 +1740,7 @@ DynaTree.prototype = {
1482
1740
 
1483
1741
  } else {
1484
1742
  // Init tree from the first UL element inside the container <div>
1485
- var $ul = this.$tree.find(">ul").hide();
1743
+ var $ul = this.$tree.find(">ul:first").hide();
1486
1744
  this._createFromTag(root, $ul);
1487
1745
  $ul.remove();
1488
1746
  }
@@ -1539,9 +1797,9 @@ DynaTree.prototype = {
1539
1797
  // Set up onPostInit callback to be called when Ajax returns
1540
1798
  if( opts.onPostInit ) {
1541
1799
  if( ajaxOpts.success )
1542
- this.tree.logWarning("initAjax: success callback is ignored when onPostInit was specified.");
1800
+ this.logWarning("initAjax: success callback is ignored when onPostInit was specified.");
1543
1801
  if( ajaxOpts.error )
1544
- this.tree.logWarning("initAjax: error callback is ignored when onPostInit was specified.");
1802
+ this.logWarning("initAjax: error callback is ignored when onPostInit was specified.");
1545
1803
  var isReloading = pers.isReloading();
1546
1804
  ajaxOpts["success"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, false); };
1547
1805
  ajaxOpts["error"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, true); };
@@ -1551,7 +1809,8 @@ DynaTree.prototype = {
1551
1809
  },
1552
1810
 
1553
1811
  toString: function() {
1554
- return "DynaTree '" + this.options.title + "'";
1812
+ // return "DynaTree '" + this.options.title + "'";
1813
+ return "Dynatree '" + this.$tree.attr("id") + "'";
1555
1814
  },
1556
1815
 
1557
1816
  toDict: function() {
@@ -1593,7 +1852,7 @@ DynaTree.prototype = {
1593
1852
 
1594
1853
  redraw: function() {
1595
1854
  this.logDebug("dynatree.redraw()...");
1596
- this.tnRoot.render(true, true);
1855
+ this.tnRoot.render();
1597
1856
  this.logDebug("dynatree.redraw() done.");
1598
1857
  },
1599
1858
 
@@ -1730,7 +1989,7 @@ TODO: better?
1730
1989
  }
1731
1990
  }
1732
1991
  }
1733
- childNode = parentTreeNode.addChild(data);
1992
+ var childNode = parentTreeNode.addChild(data);
1734
1993
  // Recursive reading of child nodes, if LI tag contains an UL tag
1735
1994
  var $ul = $li.find(">ul:first");
1736
1995
  if( $ul.length ) {
@@ -1742,23 +2001,211 @@ TODO: better?
1742
2001
  _checkConsistency: function() {
1743
2002
  // this.logDebug("tree._checkConsistency() NOT IMPLEMENTED - %o", this);
1744
2003
  },
2004
+
2005
+ _setDndStatus: function(sourceNode, targetNode, helper, hitMode, accept) {
2006
+ // hitMode: 'after', 'before', 'over', 'out', 'start', 'stop'
2007
+ var $source = sourceNode ? $(sourceNode.span) : null;
2008
+ var $target = $(targetNode.span);
2009
+ if( !this.$dndMarker ) {
2010
+ this.$dndMarker = $("<div id='dynatree_drop_marker'></div>")
2011
+ .hide()
2012
+ .prependTo("body");
2013
+ logMsg("Creating marker: %o", this.$dndMarker);
2014
+ }
2015
+ if(hitMode === "start"){
2016
+ }
2017
+ if(hitMode === "stop"){
2018
+ // sourceNode.removeClass("dynatree-drop-target");
2019
+ }
2020
+ if(hitMode === "after" || hitMode === "before" || hitMode === "over"){
2021
+ // $source && $source.addClass("dynatree-drag-source");
2022
+ $target.addClass("dynatree-drop-target");
2023
+ var pos = $target.position();
2024
+ switch(hitMode){
2025
+ case "before":
2026
+ pos.top -= 8;
2027
+ break;
2028
+ case "after":
2029
+ pos.top += 8;
2030
+ break;
2031
+ default:
2032
+ pos.left += 8;
2033
+ }
2034
+ this.$dndMarker.css({"left": (pos.left) + "px", "top": (pos.top) + "px" })
2035
+ .show();
2036
+ // helper.addClass("dynatree-drop-hover");
2037
+ } else {
2038
+ // $source && $source.removeClass("dynatree-drag-source");
2039
+ $target.removeClass("dynatree-drop-target");
2040
+ this.$dndMarker.hide();
2041
+ // helper.removeClass("dynatree-drop-hover");
2042
+ }
2043
+ if(hitMode === "after"){
2044
+ $target.addClass("dynatree-drop-after");
2045
+ } else {
2046
+ $target.removeClass("dynatree-drop-after");
2047
+ }
2048
+ if(hitMode === "before"){
2049
+ $target.addClass("dynatree-drop-before");
2050
+ } else {
2051
+ $target.removeClass("dynatree-drop-before");
2052
+ }
2053
+ if(accept === true){
2054
+ $source && $source.addClass("dynatree-drop-accept");
2055
+ $target.addClass("dynatree-drop-accept");
2056
+ helper.addClass("dynatree-drop-accept");
2057
+ }else{
2058
+ $source && $source.removeClass("dynatree-drop-accept");
2059
+ $target.removeClass("dynatree-drop-accept");
2060
+ helper.removeClass("dynatree-drop-accept");
2061
+ }
2062
+ if(accept === false){
2063
+ $source && $source.addClass("dynatree-drop-reject");
2064
+ $target.addClass("dynatree-drop-reject");
2065
+ helper.addClass("dynatree-drop-reject");
2066
+ }else{
2067
+ $source && $source.removeClass("dynatree-drop-reject");
2068
+ $target.removeClass("dynatree-drop-reject");
2069
+ helper.removeClass("dynatree-drop-reject");
2070
+ }
2071
+ },
2072
+
2073
+ _onDragEvent: function(eventName, node, otherNode, event, ui, draggable) {
2074
+ /*
2075
+ * Handles drag'n'drop functionality.
2076
+ */
2077
+ var _calcHitMode = function() {
2078
+
2079
+ }
2080
+ if(eventName !== "over")
2081
+ this.logDebug("tree._onDragEvent(%s, %o, %o) - %o", eventName, node, otherNode, this);
2082
+ var opts = this.options;
2083
+ var dnd = this.options.dnd;
2084
+ var res = null;
2085
+ var nodeTag = $(node.span);
2086
+ switch (eventName) {
2087
+ case "helper":
2088
+ // Only event and node argument is available
2089
+ var helper = $("<div class='dynatree-drag-helper'><span class='dynatree-drag-helper-img' /></div>")
2090
+ .append($(event.target).closest('a').clone());
2091
+ // Attach node reference to helper object
2092
+ helper.data("dtSourceNode", node);
2093
+ logMsg("helper.sourceNode=%o", helper.data("dtSourceNode"));
2094
+ res = helper;
2095
+ break;
2096
+ case "start":
2097
+ if(node.isStatusNode()) {
2098
+ res = false;
2099
+ } else if(dnd.onDragStart) {
2100
+ res = dnd.onDragStart(node)
2101
+ }
2102
+ if(res === false) {
2103
+ this.logDebug("tree.onDragStart() cancelled");
2104
+ draggable._clear();
2105
+ } else {
2106
+ nodeTag.addClass("dynatree-drag-source");
2107
+ }
2108
+ break;
2109
+ case "enter":
2110
+ res = dnd.onDragEnter ? dnd.onDragEnter(node, otherNode) : null;
2111
+ // logMsg("helper %o", ui.helper);
2112
+ ui.helper.data("enterResponse", res);
2113
+ this.logDebug("helper.enterResponse: %o", res);
2114
+ // this._setDndStatus(otherNode, node, ui.helper, "over", res!==false);
2115
+ break;
2116
+ case "over":
2117
+ // Auto-expand node
2118
+ if(dnd.autoExpandMS && node.hasChildren() && !node.bExpanded) {
2119
+ node.scheduleAction("expand", dnd.autoExpandMS);
2120
+ }
2121
+ var enterResponse = ui.helper.data("enterResponse");
2122
+ var hitMode = null;
2123
+ if(enterResponse === false){
2124
+ // Don't call onDragOver if onEnter returned false.
2125
+ break;
2126
+ } else if(typeof enterResponse === "string") {
2127
+ // Use hitMode from onEnter if provided.
2128
+ hitMode = enterResponse;
2129
+ } else {
2130
+ // Calculate hitMode from relative cursor position.
2131
+ var nodeOfs = nodeTag.position();
2132
+ var relPos = { x: event.clientX - nodeOfs.left,
2133
+ y: event.clientY - nodeOfs.top };
2134
+ var relPos2 = { x: relPos.x / nodeTag.width(),
2135
+ y: relPos.y / nodeTag.height() };
2136
+ if( (relPos2.y > 0.25 && relPos2.y < 0.75)
2137
+ // || (relPos2.x > 0.8 )
2138
+ ) {
2139
+ hitMode = "over";
2140
+ } else if(relPos2.y <= 0.25) {
2141
+ hitMode = "before";
2142
+ } else {
2143
+ hitMode = "after";
2144
+ }
2145
+ ui.helper.data("hitMode", hitMode);
2146
+ // logMsg(" clientPos: %s/%s", event.clientX, event.clientY);
2147
+ // logMsg(" nodeOfs: %s/%s", nodeOfs.left, nodeOfs.top);
2148
+ // logMsg(" relPos: %s/%s", relPos.x, relPos.y);
2149
+ // logMsg(" relPos2: %s/%s: %s", relPos2.x, relPos2.y, hitMode);
2150
+ // logMsg(" e:%o", event);
2151
+ }
2152
+ /* var checkPos = function(node, pos) {
2153
+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;
2154
+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;
2155
+ var itemHeight = o.height, itemWidth = o.width;
2156
+ var itemTop = o.top, itemLeft = o.left;
2157
+
2158
+ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);
2159
+ };
2160
+ var relPos = event.()*/
2161
+ if(dnd.onDragOver)
2162
+ res = dnd.onDragOver(node, otherNode, hitMode)
2163
+ this._setDndStatus(otherNode, node, ui.helper, hitMode, res!==false)
2164
+ break;
2165
+ case "drop":
2166
+ var enterResponse = ui.helper.data("enterResponse");
2167
+ var hitMode = ui.helper.data("hitMode");
2168
+ if(dnd.onDrop && enterResponse !== false)
2169
+ dnd.onDrop(node, otherNode, hitMode)
2170
+ break;
2171
+ case "leave":
2172
+ // Cancel pending expand request
2173
+ node.scheduleAction("cancel");
2174
+ ui.helper.data("enterResponse", null);
2175
+ ui.helper.data("hitMode", null);
2176
+ // nodeTag.removeClass("dynatree-drop-hover dynatree-drop-accept dynatree-drop-reject");
2177
+ this._setDndStatus(otherNode, node, ui.helper, "out", undefined)
2178
+ if(dnd.onDragLeave)
2179
+ dnd.onDragLeave(node, otherNode)
2180
+ break;
2181
+ case "stop":
2182
+ nodeTag.removeClass("dynatree-drag-source");
2183
+ if(dnd.onDragStop)
2184
+ dnd.onDragStop(node)
2185
+ break;
2186
+ default:
2187
+ throw "Unsupported drag event: " + eventName;
2188
+ }
2189
+ return res;
2190
+ },
1745
2191
 
1746
2192
  // --- end of class
1747
2193
  lastentry: undefined
1748
2194
  };
1749
2195
 
1750
- /*************************************************************************
1751
- * widget $(..).dynatree
2196
+ /*
2197
+ * Widget $(..).dynatree
1752
2198
  */
1753
2199
 
1754
2200
  $.widget("ui.dynatree", {
2201
+ /*
1755
2202
  init: function() {
1756
2203
  // ui.core 1.6 renamed init() to _init(): this stub assures backward compatibility
1757
- _log("warn", "ui.dynatree.init() was called; you should upgrade to ui.core.js v1.6 or higher.");
2204
+ _log("warn", "ui.dynatree.init() was called; you should upgrade to jquery.ui.core.js v1.8 or higher.");
1758
2205
  return this._init();
1759
2206
  },
1760
-
1761
- _init: function() {
2207
+ */
2208
+ _init: function() {
1762
2209
  if( parseFloat($.ui.version) < 1.8 ) {
1763
2210
  // jquery.ui.core 1.8 renamed _init() to _create(): this stub assures backward compatibility
1764
2211
  _log("warn", "ui.dynatree._init() was called; you should upgrade to jquery.ui.core.js v1.8 or higher.");
@@ -1768,11 +2215,9 @@ $.widget("ui.dynatree", {
1768
2215
  _log("debug", "ui.dynatree._init() was called; no current default functionality.");
1769
2216
  },
1770
2217
 
1771
- _create: function() {
1772
- if( parseFloat($.ui.version) >= 1.8 ) {
1773
- this.options = $.extend(true, $[this.namespace][this.widgetName].defaults, this.options);
1774
- }
2218
+ _create: function() {
1775
2219
  logMsg("Dynatree._create(): version='%s', debugLevel=%o.", DynaTree.version, this.options.debugLevel);
2220
+
1776
2221
  var opts = this.options;
1777
2222
  // The widget framework supplies this.element and this.options.
1778
2223
  this.options.event += ".dynatree"; // namespace event
@@ -1786,7 +2231,7 @@ $.widget("ui.dynatree", {
1786
2231
  // Create the DynaTree object
1787
2232
  this.tree = new DynaTree(this);
1788
2233
  this.tree._load();
1789
- this.tree.logDebug("Dynatree._create(): done.");
2234
+ this.tree.logDebug("Dynatree._init(): done.");
1790
2235
  },
1791
2236
 
1792
2237
  bind: function() {
@@ -1796,21 +2241,11 @@ $.widget("ui.dynatree", {
1796
2241
  // Prevent duplicate binding
1797
2242
  this.unbind();
1798
2243
 
1799
- // Tool function to get dtnode from the event target:
1800
- function __getNodeFromElement(el) {
1801
- var iMax = 5;
1802
- while( el && iMax-- ) {
1803
- if( el.dtnode ) return el.dtnode;
1804
- el = el.parentNode;
1805
- };
1806
- return null;
1807
- }
1808
-
1809
2244
  var eventNames = "click.dynatree dblclick.dynatree";
1810
2245
  if( o.keyboard ) // Note: leading ' '!
1811
2246
  eventNames += " keypress.dynatree keydown.dynatree";
1812
2247
  $this.bind(eventNames, function(event){
1813
- var dtnode = __getNodeFromElement(event.target);
2248
+ var dtnode = getDtNodeFromElement(event.target);
1814
2249
  if( !dtnode )
1815
2250
  return true; // Allow bubbling of other events
1816
2251
  var prevPhase = dtnode.tree.phase;
@@ -1830,7 +2265,7 @@ $.widget("ui.dynatree", {
1830
2265
  };
1831
2266
  } catch(e) {
1832
2267
  var _ = null; // issue 117
1833
- // dtnode.tree.logError("bind(%o): dtnode: %o", event, dtnode);
2268
+ dtnode.tree.logWarning("bind(%o): dtnode: %o, error: %o", event, dtnode, e);
1834
2269
  } finally {
1835
2270
  dtnode.tree.phase = prevPhase;
1836
2271
  }
@@ -1843,7 +2278,7 @@ $.widget("ui.dynatree", {
1843
2278
  // Handles blur and focus.
1844
2279
  // Fix event for IE:
1845
2280
  event = arguments[0] = $.event.fix( event || window.event );
1846
- var dtnode = __getNodeFromElement(event.target);
2281
+ var dtnode = getDtNodeFromElement(event.target);
1847
2282
  return dtnode ? dtnode.onFocus(event) : false;
1848
2283
  }
1849
2284
  var div = this.tree.divTree;
@@ -1872,13 +2307,13 @@ $.widget("ui.dynatree", {
1872
2307
  enable: function() {
1873
2308
  this.bind();
1874
2309
  // Call default disable(): remove -disabled from css:
1875
- $.widget.prototype.enable.apply(this, arguments);
2310
+ $.Widget.prototype.enable.apply(this, arguments);
1876
2311
  },
1877
2312
 
1878
2313
  disable: function() {
1879
2314
  this.unbind();
1880
2315
  // Call default disable(): add -disabled to css:
1881
- $.widget.prototype.disable.apply(this, arguments);
2316
+ $.Widget.prototype.disable.apply(this, arguments);
1882
2317
  },
1883
2318
 
1884
2319
  // --- getter methods (i.e. NOT returning a reference to $)
@@ -1905,14 +2340,16 @@ $.widget("ui.dynatree", {
1905
2340
 
1906
2341
  // The following methods return a value (thus breaking the jQuery call chain):
1907
2342
 
1908
- $.ui.dynatree.getter = "getTree getRoot getActiveNode getSelectedNodes";
1909
-
2343
+ // @@ 1.8
2344
+ //$.ui.dynatree.getter = "getTree getRoot getActiveNode getSelectedNodes";
1910
2345
 
1911
- // Plugin default options:
1912
2346
 
1913
- $.ui.dynatree.defaults = {
1914
- title: "Dynatree root", // Name of the root node.
1915
- rootVisible: false, // Set to true, to make the root node visible.
2347
+ /*
2348
+ * Plugin default options:
2349
+ */
2350
+ //$.ui.dynatree.defaults = { @@ 1.8
2351
+ $.ui.dynatree.prototype.options = {
2352
+ title: "Dynatree", // Tree's name (only used for debug outpu)
1916
2353
  minExpandLevel: 1, // 1: root node is not collapsible
1917
2354
  imagePath: null, // Path to a folder containing icons. Defaults to 'skin/' subdirectory.
1918
2355
  children: null, // Init tree structure from this object array.
@@ -1927,7 +2364,8 @@ $.ui.dynatree.defaults = {
1927
2364
  checkbox: false, // Show checkboxes.
1928
2365
  selectMode: 2, // 1:single, 2:multi, 3:multi-hier
1929
2366
  fx: null, // Animations, e.g. null or { height: "toggle", duration: 200 }
1930
-
2367
+ enableDrag: false,
2368
+ enableDrop: false,
1931
2369
  // Low level event handlers: onEvent(dtnode, event): return false, to stop default processing
1932
2370
  onClick: null, // null: generate focus, expand, activate, select events.
1933
2371
  onDblClick: null, // (No default actions.)
@@ -1949,6 +2387,19 @@ $.ui.dynatree.defaults = {
1949
2387
  onExpand: null, // Callback(dtnode) when a node is expanded/collapsed.
1950
2388
  onLazyRead: null, // Callback(dtnode) when a lazy node is expanded for the first time.
1951
2389
 
2390
+ // Drag'n'drop support
2391
+ dnd: {
2392
+ // Make tree nodes draggable:
2393
+ onDragStart: null, // Callback(sourceNode), return true, to enable dnd
2394
+ onDragStop: null, // Callback(sourceNode)
2395
+ helper: null,
2396
+ // Make tree nodes accept draggables
2397
+ autoExpandMS: 1000, // Expand nodes after n milliseconds of hovering.
2398
+ onDragEnter: null, // Callback(targetNode, sourceNode)
2399
+ onDragOver: null, // Callback(targetNode, sourceNode, hitMode)
2400
+ onDrop: null, // Callback(targetNode, sourceNode, hitMode)
2401
+ onDragLeave: null // Callback(targetNode, sourceNode)
2402
+ },
1952
2403
  ajaxDefaults: { // Used by initAjax option
1953
2404
  cache: false, // false: Append random '_' argument to the request url to prevent caching.
1954
2405
  dataType: "json" // Expect json format and pass json object to callbacks.
@@ -1957,8 +2408,9 @@ $.ui.dynatree.defaults = {
1957
2408
  loading: "Loading&#8230;",
1958
2409
  loadError: "Load error!"
1959
2410
  },
1960
- idPrefix: "ui-dynatree-id-", // Used to generate node id's like <span id="ui-dynatree-id-<key>">.
1961
- // cookieId: "ui-dynatree-cookie", // Choose a more unique name, to allow multiple trees.
2411
+ generateIds: false,
2412
+ idPrefix: "dynatree-id-", // Used to generate node id's like <span id="dynatree-id-<key>">.
2413
+ // cookieId: "dynatree-cookie", // Choose a more unique name, to allow multiple trees.
1962
2414
  cookieId: "dynatree", // Choose a more unique name, to allow multiple trees.
1963
2415
  cookie: {
1964
2416
  expires: null //7, // Days or Date; null: session cookie
@@ -1970,40 +2422,42 @@ $.ui.dynatree.defaults = {
1970
2422
  // Note: if only single entries are passed for options.classNames, all other
1971
2423
  // values are still set to default.
1972
2424
  classNames: {
1973
- container: "ui-dynatree-container",
1974
- folder: "ui-dynatree-folder",
1975
- document: "ui-dynatree-document",
2425
+ container: "dynatree-container",
2426
+ node: "dynatree-node",
2427
+ folder: "dynatree-folder",
2428
+ // document: "dynatree-document",
1976
2429
 
1977
- empty: "ui-dynatree-empty",
1978
- vline: "ui-dynatree-vline",
1979
- expander: "ui-dynatree-expander",
1980
- connector: "ui-dynatree-connector",
1981
- checkbox: "ui-dynatree-checkbox",
1982
- nodeIcon: "ui-dynatree-icon",
1983
- title: "ui-dynatree-title",
2430
+ empty: "dynatree-empty",
2431
+ vline: "dynatree-vline",
2432
+ expander: "dynatree-expander",
2433
+ connector: "dynatree-connector",
2434
+ checkbox: "dynatree-checkbox",
2435
+ nodeIcon: "dynatree-icon",
2436
+ title: "dynatree-title",
2437
+ noConnector: "dynatree-no-connector",
1984
2438
 
1985
- nodeError: "ui-dynatree-statusnode-error",
1986
- nodeWait: "ui-dynatree-statusnode-wait",
1987
- hidden: "ui-dynatree-hidden",
1988
- combinedExpanderPrefix: "ui-dynatree-exp-",
1989
- combinedIconPrefix: "ui-dynatree-ico-",
1990
- // disabled: "ui-dynatree-disabled",
1991
- hasChildren: "ui-dynatree-has-children",
1992
- active: "ui-dynatree-active",
1993
- selected: "ui-dynatree-selected",
1994
- expanded: "ui-dynatree-expanded",
1995
- lazy: "ui-dynatree-lazy",
1996
- focused: "ui-dynatree-focused",
1997
- partsel: "ui-dynatree-partsel",
1998
- lastsib: "ui-dynatree-lastsib"
1999
- },
2000
- debugLevel: 1,
2439
+ nodeError: "dynatree-statusnode-error",
2440
+ nodeWait: "dynatree-statusnode-wait",
2441
+ hidden: "dynatree-hidden",
2442
+ combinedExpanderPrefix: "dynatree-exp-",
2443
+ combinedIconPrefix: "dynatree-ico-",
2444
+ // disabled: "dynatree-disabled",
2445
+ hasChildren: "dynatree-has-children",
2446
+ active: "dynatree-active",
2447
+ selected: "dynatree-selected",
2448
+ expanded: "dynatree-expanded",
2449
+ lazy: "dynatree-lazy",
2450
+ focused: "dynatree-focused",
2451
+ partsel: "dynatree-partsel",
2452
+ lastsib: "dynatree-lastsib"
2453
+ },
2454
+ debugLevel: 0, // 0:quiet, 1:normal, 2:debug $REPLACE: debugLevel: 1,
2001
2455
 
2002
2456
  // ------------------------------------------------------------------------
2003
2457
  lastentry: undefined
2004
2458
  };
2005
2459
 
2006
- /**
2460
+ /*
2007
2461
  * Reserved data attributes for a tree node.
2008
2462
  */
2009
2463
  $.ui.dynatree.nodedatadefaults = {
@@ -2029,6 +2483,131 @@ $.ui.dynatree.nodedatadefaults = {
2029
2483
  lastentry: undefined
2030
2484
  };
2031
2485
 
2486
+ /*
2487
+ * Drag and drop support
2488
+ */
2489
+ function _initDragAndDrop(tree) {
2490
+ var dnd = tree.options.dnd || null;
2491
+ // Register 'connectToDynatree' option with ui.draggable
2492
+ if(dnd && (dnd.onDragStart || dnd.onDrop)) {
2493
+ _registerDnd();
2494
+ }
2495
+ // Attach ui.draggable to this Dynatree instance
2496
+ if(dnd && dnd.onDragStart ) {
2497
+ tree.$tree.draggable({
2498
+ addClasses: false,
2499
+ appendTo: "body",
2500
+ containment: false,
2501
+ delay: 0,
2502
+ distance: 4,
2503
+ revert: false,
2504
+ // Delegate draggable.start, drag, and stop events to our handler
2505
+ connectToDynatree: true,
2506
+ // Let source tree create the helper element
2507
+ helper: function(event) {
2508
+ var sourceNode = getDtNodeFromElement(event.target);
2509
+ return sourceNode.tree._onDragEvent("helper", sourceNode, null, event, null, null);
2510
+ },
2511
+ _last: null
2512
+ });
2513
+ }
2514
+ // Attach ui.droppable to this Dynatree instance
2515
+ if(dnd && dnd.onDrop) {
2516
+ tree.$tree.droppable({
2517
+ addClasses: false,
2518
+ //tolerance: "intersect",
2519
+ tolerance: "touch",
2520
+ greedy: false,
2521
+ _last: null
2522
+ });
2523
+ }
2524
+ }
2525
+
2526
+ //--- Extend ui.draggable event handling --------------------------------------
2527
+ var didRegisterDnd = false;
2528
+ var _registerDnd = function() {
2529
+ if(didRegisterDnd)
2530
+ return;
2531
+ $.ui.plugin.add("draggable", "connectToDynatree", {
2532
+ start: function(event, ui) {
2533
+ var draggable = $(this).data("draggable");
2534
+ var sourceNode = ui.helper.data("dtSourceNode") || null;
2535
+ logMsg("draggable-connectToDynatree.start, %o", sourceNode);
2536
+ logMsg(" this: %o", this);
2537
+ logMsg(" event: %o", event);
2538
+ logMsg(" draggable: %o", draggable);
2539
+ logMsg(" ui: %o", ui);
2540
+ if(sourceNode) {
2541
+ // Adjust helper offset for tree nodes
2542
+ /*
2543
+ var sourcePosition = $(sourceNode.span).position();
2544
+ var cssPosition = $(ui.helper).position();
2545
+ logMsg(" draggable.offset.click: %s/%s", draggable.offset.click.left, draggable.offset.click.top);
2546
+ logMsg(" sourceNode.position: %s/%s", sourcePosition.left, sourcePosition.top);
2547
+ logMsg(" helper.position: %s/%s", cssPosition.left, cssPosition.top);
2548
+ logMsg(" event.target.offset: %s/%s, %sx%s", event.target.offsetLeft, event.target.offsetTop, event.target.offsetWidth, event.target.offsetHeight);
2549
+ logMsg(" draggable.positionAbs: %s/%s", draggable.positionAbs.left, draggable.positionAbs.top);
2550
+ */
2551
+ // Adjust helper offset, so cursor is slightly outside top/left corner
2552
+ // draggable.offset.click.top -= event.target.offsetTop;
2553
+ // draggable.offset.click.left -= event.target.offsetLeft;
2554
+ draggable.offset.click.top = -2;
2555
+ draggable.offset.click.left = + 16;
2556
+ logMsg(" draggable.offset.click FIXED: %s/%s", draggable.offset.click.left, draggable.offset.click.top);
2557
+ // Trigger onDragStart event
2558
+ // TODO: when called as connectTo..., the return value is ignored(?)
2559
+ return sourceNode.tree._onDragEvent("start", sourceNode, null, event, ui, draggable);
2560
+ }
2561
+ },
2562
+ drag: function(event, ui) {
2563
+ var draggable = $(this).data("draggable");
2564
+ var sourceNode = ui.helper.data("dtSourceNode") || null;
2565
+ var prevTargetNode = ui.helper.data("dtTargetNode") || null;
2566
+ var targetNode = getDtNodeFromElement(event.target);
2567
+ ui.helper.data("dtTargetNode", targetNode);
2568
+ // Leaving a tree node
2569
+ if(prevTargetNode && prevTargetNode !== targetNode ) {
2570
+ prevTargetNode.tree._onDragEvent("leave", prevTargetNode, sourceNode, event, ui, draggable);
2571
+ }
2572
+ if(targetNode){
2573
+ if(!targetNode.tree.options.dnd.onDrop) {
2574
+ // not enabled as drop target
2575
+ } else if(targetNode === prevTargetNode) {
2576
+ // Moving over same node
2577
+ targetNode.tree._onDragEvent("over", targetNode, sourceNode, event, ui, draggable);
2578
+ }else{
2579
+ // Entering this node first time
2580
+ targetNode.tree._onDragEvent("enter", targetNode, sourceNode, event, ui, draggable);
2581
+ }
2582
+ }
2583
+ // else go ahead with standard event handling
2584
+ },
2585
+ stop: function(event, ui) {
2586
+ var draggable = $(this).data("draggable");
2587
+ var sourceNode = ui.helper.data("dtSourceNode") || null;
2588
+ var targetNode = getDtNodeFromElement(event.target);
2589
+ // var targetTree = targetNode ? targetNode.tree : null;
2590
+ // if(dtnode && dtnode.tree.
2591
+ logMsg("draggable-connectToDynatree.stop, %o", sourceNode);
2592
+ var mouseDownEvent = draggable._mouseDownEvent;
2593
+ var eventType = event.type;
2594
+ logMsg(" type: %o, downEvent: %o, upEvent: %o", eventType, mouseDownEvent, event);
2595
+ var dropped = (eventType == "mouseup" && event.which == 1);
2596
+ if(!dropped)
2597
+ logMsg("Drag was cancelled");
2598
+ if(targetNode) {
2599
+ if(dropped)
2600
+ targetNode.tree._onDragEvent("drop", targetNode, sourceNode, event, ui, draggable);
2601
+ targetNode.tree._onDragEvent("leave", targetNode, sourceNode, event, ui, draggable);
2602
+ }
2603
+ if(sourceNode)
2604
+ sourceNode.tree._onDragEvent("stop", sourceNode, null, event, ui, draggable);
2605
+ }
2606
+ });
2607
+ didRegisterDnd = true;
2608
+ };
2609
+
2610
+
2032
2611
  // ---------------------------------------------------------------------------
2033
2612
  })(jQuery);
2034
2613