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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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