compass-jquery-plugin 0.3.0.beta.1 → 0.3.0.beta.2

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 (344) hide show
  1. data/VERSION.yml +1 -1
  2. data/compass-jquery-plugin.gemspec +2 -2
  3. data/gem_tasks/jrails13.rake +0 -1
  4. data/gem_tasks/jrails14.rake +1 -2
  5. data/lib/jquery.ui.rb +2 -2
  6. data/templates/dynatree/jquery.dynatree.js +2036 -2036
  7. data/templates/dynatree/jquery.dynatree.min.js +59 -59
  8. data/templates/dynatree/jquery.ui/dynatree.aero.scss +144 -144
  9. data/templates/dynatree/jquery.ui/dynatree.aqua.scss +144 -144
  10. data/templates/dynatree/jquery.ui/dynatree.crystal.scss +144 -144
  11. data/templates/dynatree/jquery.ui/dynatree.xp.scss +239 -239
  12. data/templates/dynatree/manifest.rb +127 -127
  13. data/templates/jqgrid/config/initializers/jqgrid.rb +2 -2
  14. data/templates/jqgrid/i18n/jqgrid/locale-bg.min.js +15 -15
  15. data/templates/jqgrid/i18n/jqgrid/locale-bg1251.min.js +15 -15
  16. data/templates/jqgrid/i18n/jqgrid/locale-cat.min.js +7 -7
  17. data/templates/jqgrid/i18n/jqgrid/locale-cn.min.js +8 -8
  18. data/templates/jqgrid/i18n/jqgrid/locale-cs.min.js +8 -8
  19. data/templates/jqgrid/i18n/jqgrid/locale-de.min.js +7 -7
  20. data/templates/jqgrid/i18n/jqgrid/locale-dk.min.js +6 -6
  21. data/templates/jqgrid/i18n/jqgrid/locale-el.min.js +13 -13
  22. data/templates/jqgrid/i18n/jqgrid/locale-en.min.js +6 -6
  23. data/templates/jqgrid/i18n/jqgrid/locale-fa.min.js +12 -12
  24. data/templates/jqgrid/i18n/jqgrid/locale-fi.min.js +6 -6
  25. data/templates/jqgrid/i18n/jqgrid/locale-fr.js +126 -126
  26. data/templates/jqgrid/i18n/jqgrid/locale-fr.min.js +7 -7
  27. data/templates/jqgrid/i18n/jqgrid/locale-he.min.js +13 -13
  28. data/templates/jqgrid/i18n/jqgrid/locale-is.min.js +7 -7
  29. data/templates/jqgrid/i18n/jqgrid/locale-it.min.js +7 -7
  30. data/templates/jqgrid/i18n/jqgrid/locale-ja.min.js +10 -10
  31. data/templates/jqgrid/i18n/jqgrid/locale-nl.min.js +6 -6
  32. data/templates/jqgrid/i18n/jqgrid/locale-no.min.js +6 -6
  33. data/templates/jqgrid/i18n/jqgrid/locale-pl.min.js +7 -7
  34. data/templates/jqgrid/i18n/jqgrid/locale-pt-br.min.js +7 -7
  35. data/templates/jqgrid/i18n/jqgrid/locale-pt.min.js +7 -7
  36. data/templates/jqgrid/i18n/jqgrid/locale-ro.min.js +8 -8
  37. data/templates/jqgrid/i18n/jqgrid/locale-ru.min.js +16 -16
  38. data/templates/jqgrid/i18n/jqgrid/locale-sk.js +127 -127
  39. data/templates/jqgrid/i18n/jqgrid/locale-sk.min.js +8 -8
  40. data/templates/jqgrid/i18n/jqgrid/locale-sp.min.js +7 -7
  41. data/templates/jqgrid/i18n/jqgrid/locale-sv.min.js +7 -7
  42. data/templates/jqgrid/i18n/jqgrid/locale-tr.min.js +7 -7
  43. data/templates/jqgrid/i18n/jqgrid/locale-ua.min.js +16 -16
  44. data/templates/jqgrid/jquery.jqGrid.js +10477 -10471
  45. data/templates/jqgrid/jquery.jqGrid.min.js +430 -430
  46. data/templates/jqgrid/jquery.ui/jqGrid.scss +669 -669
  47. data/templates/jqgrid/manifest.rb +66 -66
  48. data/templates/jqtouch/jqtouch/iphone-emulator.scss +21 -21
  49. data/templates/jqtouch/jqtouch/jqt.apple.scss +584 -584
  50. data/templates/jqtouch/jqtouch/jqt.jqt.scss +528 -528
  51. data/templates/jqtouch/jqtouch/jqtouch.scss +310 -310
  52. data/templates/jqtouch/jquery.jqtouch.js +1026 -1026
  53. data/templates/jqtouch/jquery.jqtouch.min.js +26 -26
  54. data/templates/jqtouch/manifest.rb +52 -52
  55. data/templates/jrails-1.3/config/initializers/jrails.rb +28 -28
  56. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ar.js +19 -19
  57. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ar.min.js +4 -4
  58. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-bg.js +20 -20
  59. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-bg.min.js +4 -4
  60. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ca.js +18 -18
  61. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ca.min.js +2 -2
  62. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-cs.js +19 -19
  63. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-cs.min.js +2 -2
  64. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-da.js +19 -19
  65. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-da.min.js +2 -2
  66. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-de.js +19 -19
  67. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-de.min.js +2 -2
  68. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-el.js +18 -18
  69. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-el.min.js +4 -4
  70. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-eo.js +19 -19
  71. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-eo.min.js +2 -2
  72. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-es.js +18 -18
  73. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-es.min.js +2 -2
  74. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-fa.js +18 -18
  75. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-fa.min.js +3 -3
  76. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-fi.js +19 -19
  77. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-fi.min.js +2 -2
  78. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-fr.js +18 -18
  79. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-fr.min.js +2 -2
  80. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-he.js +19 -19
  81. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-he.min.js +3 -3
  82. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-hr.js +18 -18
  83. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-hr.min.js +2 -2
  84. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-hu.js +19 -19
  85. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-hu.min.js +2 -2
  86. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-hy.js +18 -18
  87. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-hy.min.js +4 -4
  88. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-id.js +18 -18
  89. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-id.min.js +2 -2
  90. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-is.js +18 -18
  91. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-is.min.js +2 -2
  92. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-it.js +19 -19
  93. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-it.min.js +2 -2
  94. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ja.js +19 -19
  95. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ja.min.js +2 -2
  96. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ko.js +18 -18
  97. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ko.min.js +2 -2
  98. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-lt.js +18 -18
  99. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-lt.min.js +2 -2
  100. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-lv.js +18 -18
  101. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-lv.min.js +2 -2
  102. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ms.js +18 -18
  103. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ms.min.js +2 -2
  104. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-nl.js +18 -18
  105. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-nl.min.js +2 -2
  106. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-no.js +19 -19
  107. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-no.min.js +2 -2
  108. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-pl.js +19 -19
  109. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-pl.min.js +2 -2
  110. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-pt-BR.js +18 -18
  111. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-pt-BR.min.js +2 -2
  112. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ro.js +22 -22
  113. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ro.min.js +2 -2
  114. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ru.js +18 -18
  115. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-ru.min.js +4 -4
  116. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sk.js +19 -19
  117. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sk.min.js +2 -2
  118. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sl.js +20 -20
  119. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sl.min.js +2 -2
  120. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sq.js +19 -19
  121. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sq.min.js +2 -2
  122. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sr-SR.js +19 -19
  123. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sr-SR.min.js +2 -2
  124. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sr.js +19 -19
  125. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sr.min.js +3 -3
  126. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sv.js +19 -19
  127. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-sv.min.js +2 -2
  128. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-th.js +18 -18
  129. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-th.min.js +4 -4
  130. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-tr.js +18 -18
  131. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-tr.min.js +2 -2
  132. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-uk.js +24 -24
  133. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-uk.min.js +4 -4
  134. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-zh-CN.js +19 -19
  135. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-zh-CN.min.js +2 -2
  136. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-zh-TW.js +19 -19
  137. data/templates/jrails-1.3/i18n/jquery.ui/datepicker-zh-TW.min.js +2 -2
  138. data/templates/jrails-1.3/jquery-1.3.2.js +7637 -7637
  139. data/templates/jrails-1.3/jquery-1.3.2.min.js +178 -178
  140. data/templates/jrails-1.3/jquery-ui-1.7.2.js +18316 -18316
  141. data/templates/jrails-1.3/jquery-ui-1.7.2.min.js +688 -688
  142. data/templates/jrails-1.3/jquery.contextMenu.js +210 -210
  143. data/templates/jrails-1.3/jquery.contextMenu.min.js +8 -8
  144. data/templates/jrails-1.3/jquery.haml.js +293 -293
  145. data/templates/jrails-1.3/jquery.haml.min.js +5 -5
  146. data/templates/jrails-1.3/jquery.pngFix.js +10 -10
  147. data/templates/jrails-1.3/jquery.pngFix.min.js +2 -2
  148. data/templates/jrails-1.3/jquery.themeswitchertool.js +190 -190
  149. data/templates/jrails-1.3/jquery.themeswitchertool.min.js +8 -8
  150. data/templates/jrails-1.3/jquery.ui/_theme.scss +1281 -1281
  151. data/templates/jrails-1.3/jquery.ui/base.scss +85 -85
  152. data/templates/jrails-1.3/jquery.ui/black-tie.scss +85 -85
  153. data/templates/jrails-1.3/jquery.ui/blitzer.scss +85 -85
  154. data/templates/jrails-1.3/jquery.ui/contextMenu.scss +49 -49
  155. data/templates/jrails-1.3/jquery.ui/cupertino.scss +85 -85
  156. data/templates/jrails-1.3/jquery.ui/dark-hive.scss +85 -85
  157. data/templates/jrails-1.3/jquery.ui/dot-luv.scss +85 -85
  158. data/templates/jrails-1.3/jquery.ui/eggplant.scss +85 -85
  159. data/templates/jrails-1.3/jquery.ui/excite-bike.scss +85 -85
  160. data/templates/jrails-1.3/jquery.ui/flick.scss +85 -85
  161. data/templates/jrails-1.3/jquery.ui/hot-sneaks.scss +85 -85
  162. data/templates/jrails-1.3/jquery.ui/humanity.scss +85 -85
  163. data/templates/jrails-1.3/jquery.ui/le-frog.scss +85 -85
  164. data/templates/jrails-1.3/jquery.ui/mint-choc.scss +85 -85
  165. data/templates/jrails-1.3/jquery.ui/overcast.scss +85 -85
  166. data/templates/jrails-1.3/jquery.ui/pepper-grinder.scss +85 -85
  167. data/templates/jrails-1.3/jquery.ui/redmond.scss +85 -85
  168. data/templates/jrails-1.3/jquery.ui/smoothness.scss +85 -85
  169. data/templates/jrails-1.3/jquery.ui/south-street.scss +85 -85
  170. data/templates/jrails-1.3/jquery.ui/sunny.scss +85 -85
  171. data/templates/jrails-1.3/jquery.ui/swanky-purse.scss +85 -85
  172. data/templates/jrails-1.3/jquery.ui/trontastic.scss +85 -85
  173. data/templates/jrails-1.3/jquery.ui/ui-darkness.scss +85 -85
  174. data/templates/jrails-1.3/jquery.ui/ui-lightness.scss +85 -85
  175. data/templates/jrails-1.3/jquery.ui/vader.scss +85 -85
  176. data/templates/jrails-1.3/jrails.js +197 -197
  177. data/templates/jrails-1.3/jrails.min.js +8 -8
  178. data/templates/jrails-1.3/manifest.rb +496 -496
  179. data/templates/jrails-1.4/config/initializers/jrails.rb +30 -30
  180. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-af.js +23 -23
  181. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-af.min.js +2 -2
  182. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ar.js +23 -23
  183. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ar.min.js +4 -4
  184. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-az.js +22 -22
  185. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-az.min.js +2 -2
  186. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-bg.js +24 -24
  187. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-bg.min.js +4 -4
  188. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-bs.js +22 -22
  189. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-bs.min.js +2 -2
  190. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ca.js +22 -22
  191. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ca.min.js +2 -2
  192. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-cs.js +23 -23
  193. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-cs.min.js +2 -2
  194. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-da.js +23 -23
  195. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-da.min.js +2 -2
  196. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-de.js +23 -23
  197. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-de.min.js +2 -2
  198. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-el.js +22 -22
  199. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-el.min.js +4 -4
  200. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-en-GB.js +23 -23
  201. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-en-GB.min.js +2 -2
  202. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-eo.js +23 -23
  203. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-eo.min.js +2 -2
  204. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-es.js +22 -22
  205. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-es.min.js +2 -2
  206. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-et.js +22 -22
  207. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-et.min.js +2 -2
  208. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-eu.js +22 -22
  209. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-eu.min.js +2 -2
  210. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fa.js +22 -22
  211. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fa.min.js +3 -3
  212. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fi.js +23 -23
  213. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fi.min.js +2 -2
  214. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fo.js +23 -23
  215. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fo.min.js +2 -2
  216. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fr-CH.js +22 -22
  217. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fr-CH.min.js +2 -2
  218. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fr.js +22 -22
  219. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-fr.min.js +2 -2
  220. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-he.js +23 -23
  221. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-he.min.js +3 -3
  222. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-hr.js +22 -22
  223. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-hr.min.js +2 -2
  224. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-hu.js +23 -23
  225. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-hu.min.js +2 -2
  226. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-hy.js +22 -22
  227. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-hy.min.js +4 -4
  228. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-id.js +22 -22
  229. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-id.min.js +2 -2
  230. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-is.js +22 -22
  231. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-is.min.js +2 -2
  232. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-it.js +23 -23
  233. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-it.min.js +2 -2
  234. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ja.js +22 -22
  235. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ja.min.js +2 -2
  236. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ko.js +22 -22
  237. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ko.min.js +2 -2
  238. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-lt.js +22 -22
  239. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-lt.min.js +2 -2
  240. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-lv.js +22 -22
  241. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-lv.min.js +2 -2
  242. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ms.js +22 -22
  243. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ms.min.js +2 -2
  244. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-nl.js +22 -22
  245. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-nl.min.js +2 -2
  246. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-no.js +23 -23
  247. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-no.min.js +2 -2
  248. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-pl.js +23 -23
  249. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-pl.min.js +2 -2
  250. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-pt-BR.js +22 -22
  251. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-pt-BR.min.js +2 -2
  252. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ro.js +26 -26
  253. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ro.min.js +2 -2
  254. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ru.js +22 -22
  255. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ru.min.js +4 -4
  256. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sk.js +23 -23
  257. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sk.min.js +2 -2
  258. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sl.js +24 -24
  259. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sl.min.js +2 -2
  260. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sq.js +23 -23
  261. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sq.min.js +2 -2
  262. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sr-SR.js +23 -23
  263. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sr-SR.min.js +2 -2
  264. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sr.js +23 -23
  265. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sr.min.js +4 -4
  266. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sv.js +23 -23
  267. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-sv.min.js +2 -2
  268. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ta.js +23 -23
  269. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-ta.min.js +4 -4
  270. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-th.js +22 -22
  271. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-th.min.js +4 -4
  272. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-tr.js +22 -22
  273. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-tr.min.js +2 -2
  274. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-uk.js +22 -22
  275. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-uk.min.js +4 -4
  276. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-vi.js +23 -23
  277. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-vi.min.js +2 -2
  278. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-zh-CN.js +23 -23
  279. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-zh-CN.min.js +2 -2
  280. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-zh-HK.js +23 -23
  281. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-zh-HK.min.js +2 -2
  282. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-zh-TW.js +23 -23
  283. data/templates/jrails-1.4/i18n/jquery.ui/datepicker-zh-TW.min.js +2 -2
  284. data/templates/jrails-1.4/jquery-1.4.2.js +9501 -9501
  285. data/templates/jrails-1.4/jquery-1.4.2.min.js +210 -210
  286. data/templates/jrails-1.4/jquery-ui-1.8.js +21904 -21904
  287. data/templates/jrails-1.4/jquery-ui-1.8.min.js +766 -766
  288. data/templates/jrails-1.4/jquery.bgiframe.js +9 -9
  289. data/templates/jrails-1.4/jquery.bgiframe.min.js +2 -2
  290. data/templates/jrails-1.4/jquery.compat-1.3.js +291 -291
  291. data/templates/jrails-1.4/jquery.compat-1.3.min.js +6 -6
  292. data/templates/jrails-1.4/jquery.contextMenu.js +210 -210
  293. data/templates/jrails-1.4/jquery.contextMenu.min.js +8 -8
  294. data/templates/jrails-1.4/jquery.haml.js +293 -293
  295. data/templates/jrails-1.4/jquery.haml.min.js +5 -5
  296. data/templates/jrails-1.4/jquery.metadata.js +121 -121
  297. data/templates/jrails-1.4/jquery.metadata.min.js +2 -2
  298. data/templates/jrails-1.4/jquery.pngFix.js +10 -10
  299. data/templates/jrails-1.4/jquery.pngFix.min.js +2 -2
  300. data/templates/jrails-1.4/jquery.themeswitchertool.js +190 -190
  301. data/templates/jrails-1.4/jquery.themeswitchertool.min.js +8 -8
  302. data/templates/jrails-1.4/jquery.ui/_theme.scss +1433 -1433
  303. data/templates/jrails-1.4/jquery.ui/base.scss +90 -90
  304. data/templates/jrails-1.4/jquery.ui/black-tie.scss +90 -90
  305. data/templates/jrails-1.4/jquery.ui/blitzer.scss +90 -90
  306. data/templates/jrails-1.4/jquery.ui/contextMenu.scss +49 -49
  307. data/templates/jrails-1.4/jquery.ui/cupertino.scss +90 -90
  308. data/templates/jrails-1.4/jquery.ui/dark-hive.scss +90 -90
  309. data/templates/jrails-1.4/jquery.ui/dot-luv.scss +90 -90
  310. data/templates/jrails-1.4/jquery.ui/eggplant.scss +90 -90
  311. data/templates/jrails-1.4/jquery.ui/excite-bike.scss +90 -90
  312. data/templates/jrails-1.4/jquery.ui/flick.scss +90 -90
  313. data/templates/jrails-1.4/jquery.ui/hot-sneaks.scss +90 -90
  314. data/templates/jrails-1.4/jquery.ui/humanity.scss +90 -90
  315. data/templates/jrails-1.4/jquery.ui/le-frog.scss +90 -90
  316. data/templates/jrails-1.4/jquery.ui/mint-choc.scss +90 -90
  317. data/templates/jrails-1.4/jquery.ui/overcast.scss +90 -90
  318. data/templates/jrails-1.4/jquery.ui/pepper-grinder.scss +90 -90
  319. data/templates/jrails-1.4/jquery.ui/redmond.scss +90 -90
  320. data/templates/jrails-1.4/jquery.ui/smoothness.scss +90 -90
  321. data/templates/jrails-1.4/jquery.ui/south-street.scss +90 -90
  322. data/templates/jrails-1.4/jquery.ui/start.scss +90 -90
  323. data/templates/jrails-1.4/jquery.ui/sunny.scss +90 -90
  324. data/templates/jrails-1.4/jquery.ui/swanky-purse.scss +90 -90
  325. data/templates/jrails-1.4/jquery.ui/trontastic.scss +90 -90
  326. data/templates/jrails-1.4/jquery.ui/ui-darkness.scss +90 -90
  327. data/templates/jrails-1.4/jquery.ui/ui-lightness.scss +90 -90
  328. data/templates/jrails-1.4/jquery.ui/vader.scss +90 -90
  329. data/templates/jrails-1.4/jrails.js +197 -197
  330. data/templates/jrails-1.4/jrails.min.js +8 -8
  331. data/templates/jrails-1.4/manifest.rb +568 -568
  332. data/templates/ribbon/config/initializers/ribbon.rb +3 -3
  333. data/templates/ribbon/jquery.ribbon.js +225 -225
  334. data/templates/ribbon/jquery.ribbon.min.js +14 -14
  335. data/templates/ribbon/jquery.ui/ribbon.simple.scss +271 -271
  336. data/templates/ribbon/jquery.ui/ribbon.windows7.scss +454 -454
  337. data/templates/ribbon/manifest.rb +52 -52
  338. data/templates/secret_sauce/app/views/ui/_ui_grid_for_without_block.js.haml +144 -144
  339. data/templates/secret_sauce/config/initializers/secret_sauce.rb +6 -6
  340. data/templates/secret_sauce/jquery.ui/secret_sauce.scss +33 -33
  341. data/templates/secret_sauce/manifest.rb +10 -10
  342. data/templates/secret_sauce/secret_sauce.js +11 -11
  343. data/templates/secret_sauce/secret_sauce.min.js +1 -1
  344. metadata +3 -3
@@ -1,2036 +1,2036 @@
1
- /*************************************************************************
2
- jquery.dynatree.js
3
- Dynamic tree view control, with support for lazy loading of branches.
4
-
5
- Copyright (c) 2008-2010 Martin Wendt (http://wwWendt.de)
6
- Licensed under the MIT License (MIT-License.txt)
7
-
8
- A current version and some documentation is available at
9
- http://dynatree.googlecode.com/
10
-
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$
15
-
16
- @depends: jquery.js
17
- @depends: ui.core.js
18
- @depends: jquery.cookie.js
19
- *************************************************************************/
20
-
21
-
22
- /*************************************************************************
23
- * Debug functions
24
- */
25
-
26
- var _canLog = true;
27
-
28
- function _log(mode, msg) {
29
- /**
30
- * Usage: logMsg("%o was toggled", this);
31
- */
32
- if( !_canLog )
33
- return;
34
- // Remove first argument
35
- var args = Array.prototype.slice.apply(arguments, [1]);
36
- // Prepend timestamp
37
- var dt = new Date();
38
- var tag = dt.getHours()+":"+dt.getMinutes()+":"+dt.getSeconds()+"."+dt.getMilliseconds();
39
- args[0] = tag + " - " + args[0];
40
-
41
- try {
42
- switch( mode ) {
43
- case "info":
44
- window.console.info.apply(window.console, args);
45
- break;
46
- case "warn":
47
- window.console.warn.apply(window.console, args);
48
- break;
49
- default:
50
- window.console.log.apply(window.console, args);
51
- }
52
- } catch(e) {
53
- if( !window.console )
54
- _canLog = false; // Permanently disable, when logging is not supported by the browser
55
- }
56
- }
57
-
58
- function logMsg(msg) {
59
- Array.prototype.unshift.apply(arguments, ["debug"]);
60
- _log.apply(this, arguments);
61
- }
62
-
63
-
64
- // Forward declaration
65
- var getDynaTreePersistData = undefined;
66
-
67
-
68
-
69
- /*************************************************************************
70
- * Constants
71
- */
72
- var DTNodeStatus_Error = -1;
73
- var DTNodeStatus_Loading = 1;
74
- var DTNodeStatus_Ok = 0;
75
-
76
-
77
- // Start of local namespace
78
- ;(function($) {
79
-
80
- /*************************************************************************
81
- * Common tool functions.
82
- */
83
-
84
- var Class = {
85
- create: function() {
86
- return function() {
87
- this.initialize.apply(this, arguments);
88
- }
89
- }
90
- }
91
-
92
- /*************************************************************************
93
- * Class DynaTreeNode
94
- */
95
- var DynaTreeNode = Class.create();
96
-
97
- DynaTreeNode.prototype = {
98
- initialize: function(parent, tree, data) {
99
- /**
100
- * @constructor
101
- */
102
- this.parent = parent;
103
- this.tree = tree;
104
- if ( typeof data == "string" )
105
- data = { title: data };
106
- if( data.key == undefined )
107
- data.key = "_" + tree._nodeCount++;
108
- this.data = $.extend({}, $.ui.dynatree.nodedatadefaults, data);
109
- this.div = null; // not yet created
110
- this.span = null; // not yet created
111
- this.childList = null; // no subnodes yet
112
- // this.isRead = false; // Lazy content not yet read
113
- this.isLoading = false; // Lazy content is being loaded
114
- this.hasSubSel = false;
115
- },
116
-
117
- toString: function() {
118
- return "dtnode<" + this.data.key + ">: '" + this.data.title + "'";
119
- },
120
-
121
- toDict: function(recursive, callback) {
122
- var dict = $.extend({}, this.data);
123
- dict.activate = ( this.tree.activeNode === this );
124
- dict.focus = ( this.tree.focusNode === this );
125
- dict.expand = this.bExpanded;
126
- dict.select = this.bSelected;
127
- if( callback )
128
- callback(dict);
129
- if( recursive && this.childList ) {
130
- dict.children = [];
131
- for(var i=0; i<this.childList.length; i++ )
132
- dict.children.push(this.childList[i].toDict(true, callback));
133
- } else {
134
- delete dict.children;
135
- }
136
- return dict;
137
- },
138
-
139
- _getInnerHtml: function() {
140
- var opts = this.tree.options;
141
- var cache = this.tree.cache;
142
- // 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
-
147
- var res = "";
148
- var p = this.parent;
149
- while( p ) {
150
- // Suppress first connector column, if visible top level is always expanded
151
- if ( bHideFirstConnector && p==rootParent )
152
- break;
153
- res = ( p.isLastSibling() ? cache.tagEmpty : cache.tagVline) + res;
154
- p = p.parent;
155
- }
156
-
157
- // connector (expanded, expandable or simple)
158
- if( bHideFirstExpander && this.parent==rootParent ) {
159
- // skip connector
160
- } else if ( this.childList || this.data.isLazy ) {
161
- res += cache.tagExpander;
162
- } else {
163
- res += cache.tagConnector;
164
- }
165
-
166
- // Checkbox mode
167
- if( opts.checkbox && this.data.hideCheckbox!=true && !this.data.isStatusNode ) {
168
- res += cache.tagCheckbox;
169
- }
170
-
171
- // folder or doctype icon
172
- if ( this.data.icon ) {
173
- res += "<img src='" + opts.imagePath + this.data.icon + "' alt='' />";
174
- } else if ( this.data.icon == false ) {
175
- // icon == false means 'no icon'
176
- } else {
177
- // icon == null means 'default icon'
178
- res += cache.tagNodeIcon;
179
- }
180
-
181
- // node name
182
- var tooltip = ( this.data && typeof this.data.tooltip == "string" ) ? " title='" + this.data.tooltip + "'" : "";
183
- res += "<a href='#' class='" + opts.classNames.title + "'" + tooltip + ">" + this.data.title + "</a>";
184
- return res;
185
- },
186
-
187
- _fixOrder: function() {
188
- /**
189
- * Make sure, that <div> order matches childList order.
190
- */
191
- var cl = this.childList;
192
- if( !cl )
193
- return;
194
- var childDiv = this.div.firstChild.nextSibling;
195
- for(var i=0; i<cl.length-1; i++) {
196
- var childNode1 = cl[i];
197
- var childNode2 = childDiv.firstChild.dtnode;
198
- if( childNode1 !== childNode2 ) {
199
- //
200
- this.tree.logDebug("_fixOrder: mismatch at index " + i + ": " + childNode1 + " != " + childNode2);
201
- this.div.insertBefore(childNode1.div, childNode2.div);
202
- } else {
203
- childDiv = childDiv.nextSibling;
204
- }
205
- }
206
- },
207
-
208
- render: function(bDeep, bHidden) {
209
- /**
210
- * Create HTML markup for this node.
211
- *
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>
217
- */
218
- // this.tree.logDebug("%o.render()", this);
219
- var opts = this.tree.options;
220
- var cn = opts.classNames;
221
- 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);
233
- }
234
-
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) ) {
277
- for(var i=0; i<this.childList.length; i++) {
278
- this.childList[i].render(bDeep, bHidden)
279
- }
280
- this._fixOrder();
281
- }
282
- },
283
-
284
- hasChildren: function() {
285
- return this.childList != null;
286
- },
287
-
288
- isLastSibling: function() {
289
- var p = this.parent;
290
- if ( !p ) return true;
291
- return p.childList[p.childList.length-1] === this;
292
- },
293
-
294
- prevSibling: function() {
295
- if( !this.parent ) return null;
296
- var ac = this.parent.childList;
297
- for(var i=1; i<ac.length; i++) // start with 1, so prev(first) = null
298
- if( ac[i] === this )
299
- return ac[i-1];
300
- return null;
301
- },
302
-
303
- nextSibling: function() {
304
- if( !this.parent ) return null;
305
- var ac = this.parent.childList;
306
- for(var i=0; i<ac.length-1; i++) // up to length-2, so next(last) = null
307
- if( ac[i] === this )
308
- return ac[i+1];
309
- return null;
310
- },
311
-
312
- _setStatusNode: function(data) {
313
- // Create, modify or remove the status child node (pass 'null', to remove it).
314
- var firstChild = ( this.childList ? this.childList[0] : null );
315
- if( !data ) {
316
- if ( firstChild ) {
317
- this.div.removeChild(firstChild.div);
318
- if( this.childList.length == 1 )
319
- this.childList = null;
320
- else
321
- this.childList.shift();
322
- }
323
- } else if ( firstChild ) {
324
- data.isStatusNode = true;
325
- firstChild.data = data;
326
- firstChild.render(false, false);
327
- } else {
328
- data.isStatusNode = true;
329
- firstChild = this.addChild(data);
330
- }
331
- },
332
-
333
- setLazyNodeStatus: function(lts, opts) {
334
- var tooltip = (opts && opts.tooltip) ? opts.tooltip : null;
335
- var info = (opts && opts.info) ? " (" + opts.info + ")" : "";
336
- switch( lts ) {
337
- case DTNodeStatus_Ok:
338
- this._setStatusNode(null);
339
- // this.isRead = true;
340
- this.isLoading = false;
341
- this.render(false, false);
342
- if( this.tree.options.autoFocus ) {
343
- if( this === this.tree.tnRoot && !this.tree.options.rootVisible && this.childList ) {
344
- // special case: using ajaxInit
345
- this.childList[0].focus();
346
- } else {
347
- this.focus();
348
- }
349
- }
350
- break;
351
- case DTNodeStatus_Loading:
352
- this.isLoading = true;
353
- this._setStatusNode({
354
- title: this.tree.options.strings.loading + info,
355
- tooltip: tooltip,
356
- addClass: this.tree.options.classNames.nodeWait
357
- });
358
- break;
359
- case DTNodeStatus_Error:
360
- this.isLoading = false;
361
- this._setStatusNode({
362
- title: this.tree.options.strings.loadError + info,
363
- tooltip: tooltip,
364
- addClass: this.tree.options.classNames.nodeError
365
- });
366
- break;
367
- default:
368
- throw "Bad LazyNodeStatus: '" + lts + "'.";
369
- }
370
- },
371
-
372
- _parentList: function(includeRoot, includeSelf) {
373
- var l = [];
374
- var dtn = includeSelf ? this : this.parent;
375
- while( dtn ) {
376
- if( includeRoot || dtn.parent )
377
- l.unshift(dtn);
378
- dtn = dtn.parent;
379
- };
380
- return l;
381
- },
382
-
383
- getLevel: function() {
384
- var level = 0;
385
- var dtn = this.parent;
386
- while( dtn ) {
387
- level++;
388
- dtn = dtn.parent;
389
- };
390
- return level;
391
- },
392
-
393
- _getTypeForOuterNodeEvent: function(event) {
394
- /** Return the inner node span (title, checkbox or expander) if
395
- * event.target points to the outer span.
396
- * This function should fix issue #93:
397
- * FF2 ignores empty spans, when generating events (returning the parent instead).
398
- */
399
- var cns = this.tree.options.classNames;
400
- var target = event.target;
401
- // 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 ) {
404
- return null
405
- }
406
- // Event coordinates, relative to outer node span:
407
- var eventX = event.pageX - target.offsetLeft;
408
- var eventY = event.pageY - target.offsetTop;
409
-
410
- for(var i=0; i<target.childNodes.length; i++) {
411
- var cn = target.childNodes[i];
412
- var x = cn.offsetLeft - target.offsetLeft;
413
- var y = cn.offsetTop - target.offsetTop;
414
- var nx = cn.clientWidth, ny = cn.clientHeight;
415
- // alert (cn.className + ": " + x + ", " + y + ", s:" + nx + ", " + ny);
416
- if( eventX>=x && eventX<=(x+nx) && eventY>=y && eventY<=(y+ny) ) {
417
- // alert("HIT "+ cn.className);
418
- if( cn.className==cns.title )
419
- return "title";
420
- else if( cn.className==cns.expander )
421
- return "expander";
422
- else if( cn.className==cns.checkbox )
423
- return "checkbox";
424
- else if( cn.className==cns.nodeIcon )
425
- return "icon";
426
- }
427
- }
428
- return "prefix";
429
- },
430
-
431
- getEventTargetType: function(event) {
432
- // 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.
434
- var tcn = event && event.target ? event.target.className : "";
435
- var cns = this.tree.options.classNames;
436
-
437
- if( tcn == cns.title )
438
- return "title";
439
- else if( tcn==cns.expander )
440
- return "expander";
441
- else if( tcn==cns.checkbox )
442
- return "checkbox";
443
- else if( tcn==cns.nodeIcon )
444
- return "icon";
445
- else if( tcn==cns.empty || tcn==cns.vline || tcn==cns.connector )
446
- return "prefix";
447
- else if( tcn.indexOf(cns.folder)>=0 || tcn.indexOf(cns.document)>=0 )
448
- // FIX issue #93
449
- return this._getTypeForOuterNodeEvent(event);
450
- return null;
451
- },
452
-
453
- isVisible: function() {
454
- // Return true, if all parents are expanded.
455
- var parents = this._parentList(true, false);
456
- for(var i=0; i<parents.length; i++)
457
- if( ! parents[i].bExpanded ) return false;
458
- return true;
459
- },
460
-
461
- makeVisible: function() {
462
- // Make sure, all parents are expanded
463
- var parents = this._parentList(true, false);
464
- for(var i=0; i<parents.length; i++)
465
- parents[i]._expand(true);
466
- },
467
-
468
- focus: function() {
469
- // TODO: check, if we already have focus
470
- // this.tree.logDebug("dtnode.focus(): %o", this);
471
- this.makeVisible();
472
- try {
473
- $(this.span).find(">a").focus();
474
- } catch(e) { }
475
- },
476
-
477
- _activate: function(flag, fireEvents) {
478
- // (De)Activate - but not focus - this node.
479
- this.tree.logDebug("dtnode._activate(%o, fireEvents=%o) - %o", flag, fireEvents, this);
480
- var opts = this.tree.options;
481
- if( this.data.isStatusNode )
482
- return;
483
- if ( fireEvents && opts.onQueryActivate && opts.onQueryActivate.call(this.span, flag, this) == false )
484
- return; // Callback returned false
485
-
486
- if( flag ) {
487
- // Activate
488
- if( this.tree.activeNode ) {
489
- if( this.tree.activeNode === this )
490
- return;
491
- this.tree.activeNode.deactivate();
492
- }
493
- if( opts.activeVisible )
494
- this.makeVisible();
495
- this.tree.activeNode = this;
496
- if( opts.persist )
497
- $.cookie(opts.cookieId+"-active", this.data.key, opts.cookie);
498
- this.tree.persistence.activeKey = this.data.key;
499
- $(this.span).addClass(opts.classNames.active);
500
- if ( fireEvents && opts.onActivate ) // Pass element as 'this' (jQuery convention)
501
- opts.onActivate.call(this.span, this);
502
- } else {
503
- // Deactivate
504
- if( this.tree.activeNode === this ) {
505
- var opts = this.tree.options;
506
- if ( opts.onQueryActivate && opts.onQueryActivate.call(this.span, false, this) == false )
507
- return; // Callback returned false
508
- $(this.span).removeClass(opts.classNames.active);
509
- if( opts.persist ) {
510
- // Note: we don't pass null, but ''. So the cookie is not deleted.
511
- // If we pass null, we also have to pass a COPY of opts, because $cookie will override opts.expires (issue 84)
512
- $.cookie(opts.cookieId+"-active", "", opts.cookie);
513
- }
514
- this.tree.persistence.activeKey = null;
515
- this.tree.activeNode = null;
516
- if ( fireEvents && opts.onDeactivate )
517
- opts.onDeactivate.call(this.span, this);
518
- }
519
- }
520
- },
521
-
522
- activate: function() {
523
- // Select - but not focus - this node.
524
- // this.tree.logDebug("dtnode.activate(): %o", this);
525
- this._activate(true, true);
526
- },
527
-
528
- deactivate: function() {
529
- // this.tree.logDebug("dtnode.deactivate(): %o", this);
530
- this._activate(false, true);
531
- },
532
-
533
- isActive: function() {
534
- return (this.tree.activeNode === this);
535
- },
536
-
537
- _userActivate: function() {
538
- // Handle user click / [space] / [enter], according to clickFolderMode.
539
- var activate = true;
540
- var expand = false;
541
- if ( this.data.isFolder ) {
542
- switch( this.tree.options.clickFolderMode ) {
543
- case 2:
544
- activate = false;
545
- expand = true;
546
- break;
547
- case 3:
548
- activate = expand = true;
549
- break;
550
- }
551
- }
552
- if( this.parent == null && this.tree.options.minExpandLevel>0 ) {
553
- expand = false;
554
- }
555
- if( expand ) {
556
- this.toggleExpand();
557
- this.focus();
558
- }
559
- if( activate ) {
560
- this.activate();
561
- }
562
- },
563
-
564
- _setSubSel: function(hasSubSel) {
565
- if( hasSubSel ) {
566
- this.hasSubSel = true;
567
- $(this.span).addClass(this.tree.options.classNames.partsel);
568
- } else {
569
- this.hasSubSel = false;
570
- $(this.span).removeClass(this.tree.options.classNames.partsel);
571
- }
572
- },
573
-
574
- _fixSelectionState: function() {
575
- // fix selection status, for multi-hier mode
576
- // this.tree.logDebug("_fixSelectionState(%o) - %o", this.bSelected, this);
577
- if( this.bSelected ) {
578
- // Select all children
579
- this.visit(function(dtnode){
580
- dtnode.parent._setSubSel(true);
581
- dtnode._select(true, false, false);
582
- });
583
- // Select parents, if all children are selected
584
- var p = this.parent;
585
- while( p ) {
586
- p._setSubSel(true);
587
- var allChildsSelected = true;
588
- for(var i=0; i<p.childList.length; i++) {
589
- var n = p.childList[i];
590
- if( !n.bSelected && !n.data.isStatusNode ) {
591
- allChildsSelected = false;
592
- break;
593
- }
594
- }
595
- if( allChildsSelected )
596
- p._select(true, false, false);
597
- p = p.parent;
598
- }
599
- } else {
600
- // Deselect all children
601
- this._setSubSel(false);
602
- this.visit(function(dtnode){
603
- dtnode._setSubSel(false);
604
- dtnode._select(false, false, false);
605
- });
606
- // Deselect parents, and recalc hasSubSel
607
- var p = this.parent;
608
- while( p ) {
609
- p._select(false, false, false);
610
- var isPartSel = false;
611
- for(var i=0; i<p.childList.length; i++) {
612
- if( p.childList[i].bSelected || p.childList[i].hasSubSel ) {
613
- isPartSel = true;
614
- break;
615
- }
616
- }
617
- p._setSubSel(isPartSel);
618
- p = p.parent;
619
- }
620
- }
621
- },
622
-
623
- _select: function(sel, fireEvents, deep) {
624
- // Select - but not focus - this node.
625
- // this.tree.logDebug("dtnode._select(%o) - %o", sel, this);
626
- var opts = this.tree.options;
627
- if( this.data.isStatusNode )
628
- return;
629
- //
630
- if( this.bSelected == sel ) {
631
- // this.tree.logDebug("dtnode._select(%o) IGNORED - %o", sel, this);
632
- return;
633
- }
634
- // Allow event listener to abort selection
635
- if ( fireEvents && opts.onQuerySelect && opts.onQuerySelect.call(this.span, sel, this) == false )
636
- return; // Callback returned false
637
-
638
- // Force single-selection
639
- if( opts.selectMode==1 && sel ) {
640
- this.tree.visit(function(dtnode){
641
- if( dtnode.bSelected ) {
642
- // Deselect; assuming that in selectMode:1 there's max. one other selected node
643
- dtnode._select(false, false, false);
644
- return false;
645
- }
646
- });
647
- }
648
-
649
- this.bSelected = sel;
650
- // this.tree._changeNodeList("select", this, sel);
651
-
652
- if( sel ) {
653
- if( opts.persist )
654
- this.tree.persistence.addSelect(this.data.key);
655
-
656
- $(this.span).addClass(opts.classNames.selected);
657
-
658
- if( deep && opts.selectMode==3 )
659
- this._fixSelectionState();
660
-
661
- if ( fireEvents && opts.onSelect )
662
- opts.onSelect.call(this.span, true, this);
663
-
664
- } else {
665
- if( opts.persist )
666
- this.tree.persistence.clearSelect(this.data.key);
667
-
668
- $(this.span).removeClass(opts.classNames.selected);
669
-
670
- if( deep && opts.selectMode==3 )
671
- this._fixSelectionState();
672
-
673
- if ( fireEvents && opts.onSelect )
674
- opts.onSelect.call(this.span, false, this);
675
- }
676
- },
677
-
678
- select: function(sel) {
679
- // Select - but not focus - this node.
680
- // this.tree.logDebug("dtnode.select(%o) - %o", sel, this);
681
- if( this.data.unselectable )
682
- return this.bSelected;
683
- return this._select(sel!=false, true, true);
684
- },
685
-
686
- toggleSelect: function() {
687
- // this.tree.logDebug("dtnode.toggleSelect() - %o", this);
688
- return this.select(!this.bSelected);
689
- },
690
-
691
- isSelected: function() {
692
- return this.bSelected;
693
- },
694
-
695
- _loadContent: function() {
696
- try {
697
- var opts = this.tree.options;
698
- this.tree.logDebug("_loadContent: start - %o", this);
699
- this.setLazyNodeStatus(DTNodeStatus_Loading);
700
- if( true == opts.onLazyRead.call(this.span, this) ) {
701
- // If function returns 'true', we assume that the loading is done:
702
- this.setLazyNodeStatus(DTNodeStatus_Ok);
703
- // Otherwise (i.e. if the loading was started as an asynchronous process)
704
- // the onLazyRead(dtnode) handler is expected to call dtnode.setLazyNodeStatus(DTNodeStatus_Ok/_Error) when done.
705
- this.tree.logDebug("_loadContent: succeeded - %o", this);
706
- }
707
- } catch(e) {
708
- // alert(e);
709
- this.setLazyNodeStatus(DTNodeStatus_Error);
710
- this.tree.logWarning("_loadContent: failed - %o", e);
711
- }
712
- },
713
-
714
- _expand: function(bExpand) {
715
- // this.tree.logDebug("dtnode._expand(%o) - %o", bExpand, this);
716
- if( this.bExpanded == bExpand ) {
717
- // this.tree.logDebug("dtnode._expand(%o) IGNORED - %o", bExpand, this);
718
- return;
719
- }
720
- var opts = this.tree.options;
721
- if( !bExpand && this.getLevel()<opts.minExpandLevel ) {
722
- this.tree.logDebug("dtnode._expand(%o) forced expand - %o", bExpand, this);
723
- return;
724
- }
725
- if ( opts.onQueryExpand && opts.onQueryExpand.call(this.span, bExpand, this) == false )
726
- return; // Callback returned false
727
- this.bExpanded = bExpand;
728
-
729
- // Persist expand state
730
- if( opts.persist ) {
731
- if( bExpand )
732
- this.tree.persistence.addExpand(this.data.key);
733
- else
734
- this.tree.persistence.clearExpand(this.data.key);
735
- }
736
-
737
- this.render(false);
738
-
739
- // Auto-collapse mode: collapse all siblings
740
- if( this.bExpanded && this.parent && opts.autoCollapse ) {
741
- var parents = this._parentList(false, true);
742
- for(var i=0; i<parents.length; i++)
743
- parents[i].collapseSiblings();
744
- }
745
-
746
- // If the currently active node is now hidden, deactivate it
747
- if( opts.activeVisible && this.tree.activeNode && ! this.tree.activeNode.isVisible() ) {
748
- this.tree.activeNode.deactivate();
749
- }
750
- // Expanding a lazy node: set 'loading...' and call callback
751
- if( bExpand && this.data.isLazy && this.childList==null && !this.isLoading ) {
752
- this._loadContent();
753
- return;
754
- }
755
- // 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
-
778
- if( opts.fx ) {
779
- var duration = opts.fx.duration || 200;
780
- // $(">DIV", this.div).animate(opts.fx, duration);
781
- $(filter, this.div).animate(opts.fx, duration);
782
- } 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();
787
- }
788
- //*/
789
- // this.tree.logDebug("_expand: end div toggle - %o", this);
790
-
791
- if ( opts.onExpand )
792
- opts.onExpand.call(this.span, bExpand, this);
793
- },
794
-
795
- expand: function(flag) {
796
- if( !this.childList && !this.data.isLazy && flag )
797
- return; // Prevent expanding empty nodes
798
- if( this.parent == null && this.tree.options.minExpandLevel>0 && !flag )
799
- return; // Prevent collapsing the root
800
- this._expand(flag);
801
- },
802
-
803
- toggleExpand: function() {
804
- this.expand(!this.bExpanded);
805
- },
806
-
807
- collapseSiblings: function() {
808
- if( this.parent == null )
809
- return;
810
- var ac = this.parent.childList;
811
- for (var i=0; i<ac.length; i++) {
812
- if ( ac[i] !== this && ac[i].bExpanded )
813
- ac[i]._expand(false);
814
- }
815
- },
816
-
817
- onClick: function(event) {
818
- // this.tree.logDebug("dtnode.onClick(" + event.type + "): dtnode:" + this + ", button:" + event.button + ", which: " + event.which);
819
- var targetType = this.getEventTargetType(event);
820
- if( targetType == "expander" ) {
821
- // Clicking the expander icon always expands/collapses
822
- this.toggleExpand();
823
- this.focus(); // issue 95
824
- } else if( targetType == "checkbox" ) {
825
- // Clicking the checkbox always (de)selects
826
- this.toggleSelect();
827
- this.focus(); // issue 95
828
- } else {
829
- this._userActivate();
830
- // Chrome and Safari don't focus the a-tag on click
831
- this.span.getElementsByTagName("a")[0].focus();
832
- }
833
- // Make sure that clicks stop, otherwise <a href='#'> jumps to the top
834
- return false;
835
- },
836
-
837
- onDblClick: function(event) {
838
- // this.tree.logDebug("dtnode.onDblClick(" + event.type + "): dtnode:" + this + ", button:" + event.button + ", which: " + event.which);
839
- },
840
-
841
- onKeydown: function(event) {
842
- // this.tree.logDebug("dtnode.onKeydown(" + event.type + "): dtnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which);
843
- var handled = true;
844
- // alert("keyDown" + event.which);
845
-
846
- switch( event.which ) {
847
- // charCodes:
848
- // case 43: // '+'
849
- case 107: // '+'
850
- case 187: // '+' @ Chrome, Safari
851
- if( !this.bExpanded ) this.toggleExpand();
852
- break;
853
- // case 45: // '-'
854
- case 109: // '-'
855
- case 189: // '+' @ Chrome, Safari
856
- if( this.bExpanded ) this.toggleExpand();
857
- break;
858
- //~ case 42: // '*'
859
- //~ break;
860
- //~ case 47: // '/'
861
- //~ break;
862
- // case 13: // <enter>
863
- // <enter> on a focused <a> tag seems to generate a click-event.
864
- // this._userActivate();
865
- // break;
866
- case 32: // <space>
867
- this._userActivate();
868
- break;
869
- case 8: // <backspace>
870
- if( this.parent )
871
- this.parent.focus();
872
- break;
873
- case 37: // <left>
874
- if( this.bExpanded ) {
875
- this.toggleExpand();
876
- this.focus();
877
- } else if( this.parent && (this.tree.options.rootVisible || this.parent.parent) ) {
878
- this.parent.focus();
879
- }
880
- break;
881
- case 39: // <right>
882
- if( !this.bExpanded && (this.childList || this.data.isLazy) ) {
883
- this.toggleExpand();
884
- this.focus();
885
- } else if( this.childList ) {
886
- this.childList[0].focus();
887
- }
888
- break;
889
- case 38: // <up>
890
- var sib = this.prevSibling();
891
- while( sib && sib.bExpanded && sib.childList )
892
- sib = sib.childList[sib.childList.length-1];
893
- if( !sib && this.parent && (this.tree.options.rootVisible || this.parent.parent) )
894
- sib = this.parent;
895
- if( sib ) sib.focus();
896
- break;
897
- case 40: // <down>
898
- var sib;
899
- if( this.bExpanded && this.childList ) {
900
- sib = this.childList[0];
901
- } else {
902
- var parents = this._parentList(false, true);
903
- for(var i=parents.length-1; i>=0; i--) {
904
- sib = parents[i].nextSibling();
905
- if( sib ) break;
906
- }
907
- }
908
- if( sib ) sib.focus();
909
- break;
910
- default:
911
- handled = false;
912
- }
913
- // Return false, if handled, to prevent default processing
914
- return !handled;
915
- },
916
-
917
- onKeypress: function(event) {
918
- // onKeypress is only hooked to allow user callbacks.
919
- // We don't process it, because IE and Safari don't fire keypress for cursor keys.
920
- // this.tree.logDebug("dtnode.onKeypress(" + event.type + "): dtnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which);
921
- },
922
-
923
- onFocus: function(event) {
924
- // Handles blur and focus events.
925
- // this.tree.logDebug("dtnode.onFocus(%o): %o", event, this);
926
- var opts = this.tree.options;
927
- if ( event.type=="blur" || event.type=="focusout" ) {
928
- if ( opts.onBlur ) // Pass element as 'this' (jQuery convention)
929
- opts.onBlur.call(this.span, this);
930
- if( this.tree.tnFocused )
931
- $(this.tree.tnFocused.span).removeClass(opts.classNames.focused);
932
- this.tree.tnFocused = null;
933
- if( opts.persist )
934
- $.cookie(opts.cookieId+"-focus", "", opts.cookie);
935
- } else if ( event.type=="focus" || event.type=="focusin") {
936
- // Fix: sometimes the blur event is not generated
937
- if( this.tree.tnFocused && this.tree.tnFocused !== this ) {
938
- this.tree.logDebug("dtnode.onFocus: out of sync: curFocus: %o", this.tree.tnFocused);
939
- $(this.tree.tnFocused.span).removeClass(opts.classNames.focused);
940
- }
941
- this.tree.tnFocused = this;
942
- if ( opts.onFocus ) // Pass element as 'this' (jQuery convention)
943
- opts.onFocus.call(this.span, this);
944
- $(this.tree.tnFocused.span).addClass(opts.classNames.focused);
945
- if( opts.persist )
946
- $.cookie(opts.cookieId+"-focus", this.data.key, opts.cookie);
947
- }
948
- // TODO: return anything?
949
- // return false;
950
- },
951
-
952
- visit: function(fn, data, includeSelf) {
953
- // Call fn(dtnode, data) for all child nodes. Stop iteration, if fn() returns false.
954
- var n = 0;
955
- if( includeSelf == true ) {
956
- if( fn(this, data) == false )
957
- return 1;
958
- n++;
959
- }
960
- if ( this.childList )
961
- for (var i=0; i<this.childList.length; i++)
962
- n += this.childList[i].visit(fn, data, true);
963
- return n;
964
- },
965
-
966
- remove: function() {
967
- // Remove this node
968
- // this.tree.logDebug ("%o.remove()", this);
969
- if ( this === this.tree.root )
970
- return false;
971
- return this.parent.removeChild(this);
972
- },
973
-
974
- removeChild: function(tn) {
975
- // Remove tn from list of direct children.
976
- var ac = this.childList;
977
- if( ac.length == 1 ) {
978
- if( tn !== ac[0] )
979
- throw "removeChild: invalid child";
980
- return this.removeChildren();
981
- }
982
- if( tn === this.tree.activeNode )
983
- tn.deactivate();
984
- if( this.tree.options.persist ) {
985
- if( tn.bSelected )
986
- this.tree.persistence.clearSelect(tn.data.key);
987
- if ( tn.bExpanded )
988
- this.tree.persistence.clearExpand(tn.data.key);
989
- }
990
- tn.removeChildren(true);
991
- this.div.removeChild(tn.div);
992
- for(var i=0; i<ac.length; i++) {
993
- if( ac[i] === tn ) {
994
- this.childList.splice(i, 1);
995
- delete tn;
996
- break;
997
- }
998
- }
999
- },
1000
-
1001
- removeChildren: function(isRecursiveCall, retainPersistence) {
1002
- // Remove all child nodes (more efficiently than recursive remove())
1003
- // this.tree.logDebug ("%o.removeChildren(%o)", this, isRecursiveCall);
1004
- var tree = this.tree;
1005
- var ac = this.childList;
1006
- if( ac ) {
1007
- for(var i=0; i<ac.length; i++) {
1008
- var tn=ac[i];
1009
- // this.tree.logDebug ("del %o", tn);
1010
- if ( tn === tree.activeNode && !retainPersistence )
1011
- tn.deactivate();
1012
- if( this.tree.options.persist && !retainPersistence ) {
1013
- if( tn.bSelected )
1014
- this.tree.persistence.clearSelect(tn.data.key);
1015
- if ( tn.bExpanded )
1016
- this.tree.persistence.clearExpand(tn.data.key);
1017
- }
1018
- tn.removeChildren(true, retainPersistence);
1019
- this.div.removeChild(tn.div);
1020
- delete tn;
1021
- }
1022
- this.childList = null;
1023
- }
1024
- if( ! isRecursiveCall ) {
1025
- // this._expand(false);
1026
- // this.isRead = false;
1027
- this.isLoading = false;
1028
- this.render(false, false);
1029
- }
1030
- },
1031
-
1032
- reload: function(force) {
1033
- // Discard lazy content (and reload, if node was expanded).
1034
- if( this.parent == null )
1035
- return this.tree.reload();
1036
-
1037
- if( ! this.data.isLazy )
1038
- throw "node.reload() requires lazy nodes.";
1039
- if( this.bExpanded ) {
1040
- this.expand(false);
1041
- this.removeChildren();
1042
- this.expand(true);
1043
- } else {
1044
- this.removeChildren();
1045
- if( force )
1046
- this._loadContent();
1047
- }
1048
- },
1049
-
1050
- _addChildNode: function(dtnode, beforeNode) {
1051
- /**
1052
- * Internal function to add one single DynatreeNode as a child.
1053
- *
1054
- */
1055
- var tree = this.tree;
1056
- var opts = tree.options;
1057
- var pers = tree.persistence;
1058
-
1059
- // tree.logDebug("%o._addChildNode(%o)", this, dtnode);
1060
-
1061
- // --- Update and fix dtnode attributes if necessary
1062
- dtnode.parent = this;
1063
- // if( beforeNode && (beforeNode.parent !== this || beforeNode === dtnode ) )
1064
- // throw "<beforeNode> must be another child of <this>";
1065
-
1066
- // --- Add dtnode as a child
1067
- if ( this.childList==null ) {
1068
- this.childList = [];
1069
- } else if( ! beforeNode ) {
1070
- // Fix 'lastsib'
1071
- $(this.childList[this.childList.length-1].span).removeClass(opts.classNames.lastsib);
1072
- }
1073
- if( beforeNode ) {
1074
- var iBefore = $.inArray(beforeNode, this.childList);
1075
- if( iBefore < 0 )
1076
- throw "<beforeNode> must be a child of <this>";
1077
- this.childList.splice(iBefore, 0, dtnode);
1078
- // alert(this.childList);
1079
- } else {
1080
- // Append node
1081
- this.childList.push(dtnode);
1082
- }
1083
-
1084
- // --- Handle persistence
1085
- // Initial status is read from cookies, if persistence is active and
1086
- // cookies are already present.
1087
- // Otherwise the status is read from the data attributes and then persisted.
1088
- var isInitializing = tree.isInitializing();
1089
- if( opts.persist && pers.cookiesFound && isInitializing ) {
1090
- // Init status from cookies
1091
- // tree.logDebug("init from cookie, pa=%o, dk=%o", pers.activeKey, dtnode.data.key);
1092
- if( pers.activeKey == dtnode.data.key )
1093
- tree.activeNode = dtnode;
1094
- if( pers.focusedKey == dtnode.data.key )
1095
- tree.focusNode = dtnode;
1096
- dtnode.bExpanded = ($.inArray(dtnode.data.key, pers.expandedKeyList) >= 0);
1097
- dtnode.bSelected = ($.inArray(dtnode.data.key, pers.selectedKeyList) >= 0);
1098
- // tree.logDebug(" key=%o, bSelected=%o", dtnode.data.key, dtnode.bSelected);
1099
- } else {
1100
- // Init status from data (Note: we write the cookies after the init phase)
1101
- // tree.logDebug("init from data");
1102
- if( dtnode.data.activate ) {
1103
- tree.activeNode = dtnode;
1104
- if( opts.persist )
1105
- pers.activeKey = dtnode.data.key;
1106
- }
1107
- if( dtnode.data.focus ) {
1108
- tree.focusNode = dtnode;
1109
- if( opts.persist )
1110
- pers.focusedKey = dtnode.data.key;
1111
- }
1112
- dtnode.bExpanded = ( dtnode.data.expand == true ); // Collapsed by default
1113
- if( dtnode.bExpanded && opts.persist )
1114
- pers.addExpand(dtnode.data.key);
1115
- dtnode.bSelected = ( dtnode.data.select == true ); // Deselected by default
1116
- /*
1117
- Doesn't work, cause pers.selectedKeyList may be null
1118
- if( dtnode.bSelected && opts.selectMode==1
1119
- && pers.selectedKeyList && pers.selectedKeyList.length>0 ) {
1120
- tree.logWarning("Ignored multi-selection in single-mode for %o", dtnode);
1121
- dtnode.bSelected = false; // Fixing bad input data (multi selection for mode:1)
1122
- }
1123
- */
1124
- if( dtnode.bSelected && opts.persist )
1125
- pers.addSelect(dtnode.data.key);
1126
- }
1127
-
1128
- // Always expand, if it's below minExpandLevel
1129
- // tree.logDebug ("%o._addChildNode(%o), l=%o", this, dtnode, dtnode.getLevel());
1130
- if ( opts.minExpandLevel >= dtnode.getLevel() ) {
1131
- // tree.logDebug ("Force expand for %o", dtnode);
1132
- this.bExpanded = true;
1133
- }
1134
-
1135
- // In multi-hier mode, update the parents selection state
1136
- // issue #82: only if not initializing, because the children may not exist yet
1137
- // if( !dtnode.data.isStatusNode && opts.selectMode==3 && !isInitializing )
1138
- // dtnode._fixSelectionState();
1139
-
1140
- // In multi-hier mode, update the parents selection state
1141
- if( dtnode.bSelected && opts.selectMode==3 ) {
1142
- var p = this;
1143
- while( p ) {
1144
- if( !p.hasSubSel )
1145
- p._setSubSel(true);
1146
- p = p.parent;
1147
- }
1148
- }
1149
- // render this node and the new child
1150
- if ( tree.bEnableUpdate )
1151
- this.render(true, true);
1152
-
1153
- return dtnode;
1154
- },
1155
-
1156
- addChild: function(obj, beforeNode) {
1157
- /**
1158
- * Add a node object as child.
1159
- *
1160
- * This should be the only place, where a DynaTreeNode is constructed!
1161
- * (Except for the root node creation in the tree constructor)
1162
- *
1163
- * @param obj A JS object (may be recursive) or an array of those.
1164
- * @param {DynaTreeNode} beforeNode (optional) sibling node.
1165
- *
1166
- * Data format: array of node objects, with optional 'children' attributes.
1167
- * [
1168
- * { title: "t1", isFolder: true, ... }
1169
- * { title: "t2", isFolder: true, ...,
1170
- * children: [
1171
- * {title: "t2.1", ..},
1172
- * {..}
1173
- * ]
1174
- * }
1175
- * ]
1176
- * A simple object is also accepted instead of an array.
1177
- *
1178
- */
1179
- // this.tree.logDebug("%o.addChild(%o, %o)", this, obj, beforeNode);
1180
- if( !obj || obj.length==0 ) // Passed null or undefined or empty array
1181
- return;
1182
- if( obj instanceof DynaTreeNode )
1183
- return this._addChildNode(obj, beforeNode);
1184
- if( !obj.length ) // Passed a single data object
1185
- obj = [ obj ];
1186
-
1187
- var prevFlag = this.tree.enableUpdate(false);
1188
-
1189
- var tnFirst = null;
1190
- for (var i=0; i<obj.length; i++) {
1191
- var data = obj[i];
1192
- var dtnode = this._addChildNode(new DynaTreeNode(this, this.tree, data), beforeNode);
1193
- if( !tnFirst ) tnFirst = dtnode;
1194
- // Add child nodes recursively
1195
- if( data.children )
1196
- dtnode.addChild(data.children, null);
1197
- }
1198
- this.tree.enableUpdate(prevFlag);
1199
- return tnFirst;
1200
- },
1201
-
1202
- append: function(obj) {
1203
- this.tree.logWarning("node.append() is deprecated (use node.addChild() instead).");
1204
- return this.addChild(obj, null);
1205
- },
1206
-
1207
- appendAjax: function(ajaxOptions) {
1208
- this.removeChildren(false, true);
1209
- this.setLazyNodeStatus(DTNodeStatus_Loading);
1210
- // Ajax option inheritance: $.ajaxSetup < $.ui.dynatree.defaults.ajaxDefaults < tree.options.ajaxDefaults < ajaxOptions
1211
- var self = this;
1212
- var orgSuccess = ajaxOptions.success;
1213
- var orgError = ajaxOptions.error;
1214
- var options = $.extend({}, this.tree.options.ajaxDefaults, ajaxOptions, {
1215
- /*
1216
- complete: function(req, textStatus){
1217
- alert("ajax complete");
1218
- },
1219
- timeout: 5000, // 5 sec
1220
- */
1221
- success: function(data, textStatus){
1222
- // <this> is the request options
1223
- // self.tree.logDebug("appendAjax().success");
1224
- var prevPhase = self.tree.phase;
1225
- self.tree.phase = "init";
1226
- // self.append(data);
1227
- self.addChild(data, null);
1228
- self.tree.phase = "postInit";
1229
- self.setLazyNodeStatus(DTNodeStatus_Ok);
1230
- if( orgSuccess )
1231
- orgSuccess.call(options, self);
1232
- self.tree.phase = prevPhase;
1233
- },
1234
- error: function(XMLHttpRequest, textStatus, errorThrown){
1235
- // <this> is the request options
1236
- // self.tree.logWarning("appendAjax failed: %o:\n%o\n%o", textStatus, XMLHttpRequest, errorThrown);
1237
- self.tree.logWarning("appendAjax failed:", textStatus, ":\n", XMLHttpRequest, "\n", errorThrown);
1238
- self.setLazyNodeStatus(DTNodeStatus_Error, {info: textStatus, tooltip: ""+errorThrown});
1239
- if( orgError )
1240
- orgError.call(options, self, XMLHttpRequest, textStatus, errorThrown);
1241
- }
1242
- });
1243
- $.ajax(options);
1244
- },
1245
- // --- end of class
1246
- lastentry: undefined
1247
- }
1248
-
1249
- /*************************************************************************
1250
- * class DynaTreeStatus
1251
- */
1252
-
1253
- var DynaTreeStatus = Class.create();
1254
-
1255
-
1256
- DynaTreeStatus._getTreePersistData = function(cookieId, cookieOpts) {
1257
- // Static member: Return persistence information from cookies
1258
- var ts = new DynaTreeStatus(cookieId, cookieOpts);
1259
- ts.read();
1260
- return ts.toDict();
1261
- }
1262
- // Make available in global scope
1263
- getDynaTreePersistData = DynaTreeStatus._getTreePersistData;
1264
-
1265
-
1266
- DynaTreeStatus.prototype = {
1267
- // Constructor
1268
- initialize: function(cookieId, cookieOpts) {
1269
- this._log("DynaTreeStatus: initialize");
1270
- if( cookieId === undefined )
1271
- cookieId = $.ui.dynatree.defaults.cookieId;
1272
- cookieOpts = $.extend({}, $.ui.dynatree.defaults.cookie, cookieOpts);
1273
-
1274
- this.cookieId = cookieId;
1275
- this.cookieOpts = cookieOpts;
1276
- this.cookiesFound = undefined;
1277
- this.activeKey = null;
1278
- this.focusedKey = null;
1279
- this.expandedKeyList = null;
1280
- this.selectedKeyList = null;
1281
- },
1282
- // member functions
1283
- _log: function(msg) {
1284
- // this.logDebug("_changeNodeList(%o): nodeList:%o, idx:%o", mode, nodeList, idx);
1285
- Array.prototype.unshift.apply(arguments, ["debug"]);
1286
- _log.apply(this, arguments);
1287
- },
1288
- read: function() {
1289
- this._log("DynaTreeStatus: read");
1290
- // Read or init cookies.
1291
- this.cookiesFound = false;
1292
-
1293
- var cookie = $.cookie(this.cookieId + "-active");
1294
- this.activeKey = ( cookie == null ) ? "" : cookie;
1295
- if( cookie != null ) this.cookiesFound = true;
1296
-
1297
- cookie = $.cookie(this.cookieId + "-focus");
1298
- this.focusedKey = ( cookie == null ) ? "" : cookie;
1299
- if( cookie != null ) this.cookiesFound = true;
1300
-
1301
- cookie = $.cookie(this.cookieId + "-expand");
1302
- this.expandedKeyList = ( cookie == null ) ? [] : cookie.split(",");
1303
- if( cookie != null ) this.cookiesFound = true;
1304
-
1305
- cookie = $.cookie(this.cookieId + "-select");
1306
- this.selectedKeyList = ( cookie == null ) ? [] : cookie.split(",");
1307
- if( cookie != null ) this.cookiesFound = true;
1308
- },
1309
- write: function() {
1310
- this._log("DynaTreeStatus: write");
1311
- $.cookie(this.cookieId + "-active", ( this.activeKey == null ) ? "" : this.activeKey, this.cookieOpts);
1312
- $.cookie(this.cookieId + "-focus", ( this.focusedKey == null ) ? "" : this.focusedKey, this.cookieOpts);
1313
- $.cookie(this.cookieId + "-expand", ( this.expandedKeyList == null ) ? "" : this.expandedKeyList.join(","), this.cookieOpts);
1314
- $.cookie(this.cookieId + "-select", ( this.selectedKeyList == null ) ? "" : this.selectedKeyList.join(","), this.cookieOpts);
1315
- },
1316
- addExpand: function(key) {
1317
- this._log("addExpand(%o)", key);
1318
- if( $.inArray(key, this.expandedKeyList) < 0 ) {
1319
- this.expandedKeyList.push(key);
1320
- $.cookie(this.cookieId + "-expand", this.expandedKeyList.join(","), this.cookieOpts);
1321
- }
1322
- },
1323
- clearExpand: function(key) {
1324
- this._log("clearExpand(%o)", key);
1325
- var idx = $.inArray(key, this.expandedKeyList);
1326
- if( idx >= 0 ) {
1327
- this.expandedKeyList.splice(idx, 1);
1328
- $.cookie(this.cookieId + "-expand", this.expandedKeyList.join(","), this.cookieOpts);
1329
- }
1330
- },
1331
- addSelect: function(key) {
1332
- this._log("addSelect(%o)", key);
1333
- if( $.inArray(key, this.selectedKeyList) < 0 ) {
1334
- this.selectedKeyList.push(key);
1335
- $.cookie(this.cookieId + "-select", this.selectedKeyList.join(","), this.cookieOpts);
1336
- }
1337
- },
1338
- clearSelect: function(key) {
1339
- this._log("clearSelect(%o)", key);
1340
- var idx = $.inArray(key, this.selectedKeyList);
1341
- if( idx >= 0 ) {
1342
- this.selectedKeyList.splice(idx, 1);
1343
- $.cookie(this.cookieId + "-select", this.selectedKeyList.join(","), this.cookieOpts);
1344
- }
1345
- },
1346
- isReloading: function() {
1347
- return this.cookiesFound == true;
1348
- },
1349
- toDict: function() {
1350
- return {
1351
- cookiesFound: this.cookiesFound,
1352
- activeKey: this.activeKey,
1353
- focusedKey: this.activeKey,
1354
- expandedKeyList: this.expandedKeyList,
1355
- selectedKeyList: this.selectedKeyList
1356
- };
1357
- },
1358
- // --- end of class
1359
- lastentry: undefined
1360
- };
1361
-
1362
-
1363
- /*************************************************************************
1364
- * class DynaTree
1365
- */
1366
-
1367
- var DynaTree = Class.create();
1368
-
1369
- // --- Static members ----------------------------------------------------------
1370
-
1371
- DynaTree.version = "$Version: 0.5.3$";
1372
- /*
1373
- DynaTree._initTree = function() {
1374
- };
1375
-
1376
- DynaTree._bind = function() {
1377
- };
1378
- */
1379
- //--- Class members ------------------------------------------------------------
1380
-
1381
- DynaTree.prototype = {
1382
- // Constructor
1383
- // initialize: function(divContainer, options) {
1384
- initialize: function($widget) {
1385
- // instance members
1386
- this.phase = "init";
1387
- this.$widget = $widget;
1388
- this.options = $widget.options;
1389
- this.$tree = $widget.element;
1390
- // find container element
1391
- this.divTree = this.$tree.get(0);
1392
- },
1393
-
1394
- // member functions
1395
-
1396
- _load: function() {
1397
- var $widget = this.$widget;
1398
- var opts = this.options;
1399
- this.bEnableUpdate = true;
1400
- this._nodeCount = 1;
1401
- this.activeNode = null;
1402
- this.focusNode = null;
1403
-
1404
- // If a 'options.classNames' dictionary was passed, still use defaults
1405
- // for undefined classes:
1406
- if( opts.classNames !== $.ui.dynatree.defaults.classNames ) {
1407
- opts.classNames = $.extend({}, $.ui.dynatree.defaults.classNames, opts.classNames);
1408
- }
1409
- // Guess skin path, if not specified
1410
- if(!opts.imagePath) {
1411
- $("script").each( function () {
1412
- // Eclipse syntax parser breaks on this expression, so put it at the bottom:
1413
- if( this.src.search(_rexDtLibName) >= 0 ) {
1414
- if( this.src.indexOf("/")>=0 ) // issue #47
1415
- opts.imagePath = this.src.slice(0, this.src.lastIndexOf("/")) + "/skin/";
1416
- else
1417
- opts.imagePath = "skin/";
1418
- // logMsg("Guessing imagePath from '%s': '%s'", this.src, opts.imagePath);
1419
- return false; // first match
1420
- }
1421
- });
1422
- }
1423
-
1424
- this.persistence = new DynaTreeStatus(opts.cookieId, opts.cookie);
1425
- if( opts.persist ) {
1426
- if( !$.cookie )
1427
- _log("warn", "Please include jquery.cookie.js to use persistence.");
1428
- this.persistence.read();
1429
- }
1430
- this.logDebug("DynaTree.persistence: %o", this.persistence.toDict());
1431
-
1432
- // Cached tag strings
1433
- this.cache = {
1434
- tagEmpty: "<span class='" + opts.classNames.empty + "'></span>",
1435
- tagVline: "<span class='" + opts.classNames.vline + "'></span>",
1436
- tagExpander: "<span class='" + opts.classNames.expander + "'></span>",
1437
- tagConnector: "<span class='" + opts.classNames.connector + "'></span>",
1438
- tagNodeIcon: "<span class='" + opts.classNames.nodeIcon + "'></span>",
1439
- tagCheckbox: "<span class='" + opts.classNames.checkbox + "'></span>",
1440
- lastentry: undefined
1441
- };
1442
-
1443
- // Clear container, in case it contained some 'waiting' or 'error' text
1444
- // for clients that don't support JS.
1445
- // We don't do this however, if we try to load from an embedded UL element.
1446
- if( opts.children || (opts.initAjax && opts.initAjax.url) || opts.initId )
1447
- $(this.divTree).empty();
1448
- else if( this.divRoot )
1449
- $(this.divRoot).remove();
1450
-
1451
- // create the root element
1452
- this.tnRoot = new DynaTreeNode(null, this, {title: opts.title, key: "root"});
1453
- this.tnRoot.data.isFolder = true;
1454
- this.tnRoot.render(false, false);
1455
- this.divRoot = this.tnRoot.div;
1456
- this.divRoot.className = opts.classNames.container;
1457
- // add root to container
1458
- // TODO: this should be delayed until all children have been created for performance reasons
1459
- this.divTree.appendChild(this.divRoot);
1460
-
1461
- var root = this.tnRoot;
1462
- var isReloading = ( opts.persist && this.persistence.isReloading() );
1463
- var isLazy = false;
1464
- var prevFlag = this.enableUpdate(false);
1465
-
1466
- this.logDebug("Dynatree._load(): read tree structure...");
1467
-
1468
- // Init tree structure
1469
- if( opts.children ) {
1470
- // Read structure from node array
1471
- root.addChild(opts.children);
1472
-
1473
- } else if( opts.initAjax && opts.initAjax.url ) {
1474
- // Init tree from AJAX request
1475
- isLazy = true;
1476
- root.data.isLazy = true;
1477
- this._reloadAjax();
1478
-
1479
- } else if( opts.initId ) {
1480
- // Init tree from another UL element
1481
- this._createFromTag(root, $("#"+opts.initId));
1482
-
1483
- } else {
1484
- // Init tree from the first UL element inside the container <div>
1485
- var $ul = this.$tree.find(">ul").hide();
1486
- this._createFromTag(root, $ul);
1487
- $ul.remove();
1488
- }
1489
-
1490
- this._checkConsistency();
1491
- // Render html markup
1492
- this.logDebug("Dynatree._load(): render nodes...");
1493
- this.enableUpdate(prevFlag);
1494
-
1495
- // bind event handlers
1496
- this.logDebug("Dynatree._load(): bind events...");
1497
- this.$widget.bind();
1498
-
1499
- // --- Post-load processing
1500
- this.logDebug("Dynatree._load(): postInit...");
1501
- this.phase = "postInit";
1502
-
1503
- // In persist mode, make sure that cookies are written, even if they are empty
1504
- if( opts.persist ) {
1505
- this.persistence.write();
1506
- }
1507
-
1508
- // Set focus, if possible (this will also fire an event and write a cookie)
1509
- if( this.focusNode && this.focusNode.isVisible() ) {
1510
- this.logDebug("Focus on init: %o", this.focusNode);
1511
- this.focusNode.focus();
1512
- }
1513
-
1514
- if( !isLazy && opts.onPostInit ) {
1515
- opts.onPostInit.call(this, isReloading, false);
1516
- }
1517
-
1518
- this.phase = "idle";
1519
- },
1520
-
1521
- _reloadAjax: function() {
1522
- // Reload
1523
- var opts = this.options;
1524
- if( ! opts.initAjax || ! opts.initAjax.url )
1525
- throw "tree.reload() requires 'initAjax' mode.";
1526
- var pers = this.persistence;
1527
- var ajaxOpts = $.extend({}, opts.initAjax);
1528
- // Append cookie info to the request
1529
- // this.logDebug("reloadAjax: key=%o, an.key:%o", pers.activeKey, this.activeNode?this.activeNode.data.key:"?");
1530
- if( ajaxOpts.addActiveKey )
1531
- ajaxOpts.data.activeKey = pers.activeKey;
1532
- if( ajaxOpts.addFocusedKey )
1533
- ajaxOpts.data.focusedKey = pers.focusedKey;
1534
- if( ajaxOpts.addExpandedKeyList )
1535
- ajaxOpts.data.expandedKeyList = pers.expandedKeyList.join(",");
1536
- if( ajaxOpts.addSelectedKeyList )
1537
- ajaxOpts.data.selectedKeyList = pers.selectedKeyList.join(",");
1538
-
1539
- // Set up onPostInit callback to be called when Ajax returns
1540
- if( opts.onPostInit ) {
1541
- if( ajaxOpts.success )
1542
- this.tree.logWarning("initAjax: success callback is ignored when onPostInit was specified.");
1543
- if( ajaxOpts.error )
1544
- this.tree.logWarning("initAjax: error callback is ignored when onPostInit was specified.");
1545
- var isReloading = pers.isReloading();
1546
- ajaxOpts["success"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, false); };
1547
- ajaxOpts["error"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, true); };
1548
- }
1549
- this.logDebug("Dynatree._init(): send Ajax request...");
1550
- this.tnRoot.appendAjax(ajaxOpts);
1551
- },
1552
-
1553
- toString: function() {
1554
- return "DynaTree '" + this.options.title + "'";
1555
- },
1556
-
1557
- toDict: function() {
1558
- return this.tnRoot.toDict(true);
1559
- },
1560
-
1561
- getPersistData: function() {
1562
- return this.persistence.toDict();
1563
- },
1564
-
1565
- logDebug: function(msg) {
1566
- if( this.options.debugLevel >= 2 ) {
1567
- Array.prototype.unshift.apply(arguments, ["debug"]);
1568
- _log.apply(this, arguments);
1569
- }
1570
- },
1571
-
1572
- logInfo: function(msg) {
1573
- if( this.options.debugLevel >= 1 ) {
1574
- Array.prototype.unshift.apply(arguments, ["info"]);
1575
- _log.apply(this, arguments);
1576
- }
1577
- },
1578
-
1579
- logWarning: function(msg) {
1580
- Array.prototype.unshift.apply(arguments, ["warn"]);
1581
- _log.apply(this, arguments);
1582
- },
1583
-
1584
- isInitializing: function() {
1585
- return ( this.phase=="init" || this.phase=="postInit" );
1586
- },
1587
- isReloading: function() {
1588
- return ( this.phase=="init" || this.phase=="postInit" ) && this.options.persist && this.persistence.cookiesFound;
1589
- },
1590
- isUserEvent: function() {
1591
- return ( this.phase=="userEvent" );
1592
- },
1593
-
1594
- redraw: function() {
1595
- this.logDebug("dynatree.redraw()...");
1596
- this.tnRoot.render(true, true);
1597
- this.logDebug("dynatree.redraw() done.");
1598
- },
1599
-
1600
- reloadAjax: function() {
1601
- this.logWarning("tree.reloadAjax() is deprecated since v0.5.2 (use reload() instead).");
1602
- },
1603
-
1604
- reload: function() {
1605
- this._load();
1606
- },
1607
-
1608
- getRoot: function() {
1609
- return this.tnRoot;
1610
- },
1611
-
1612
- getNodeByKey: function(key) {
1613
- // $("#...") has problems, if the key contains '.', so we use getElementById()
1614
- // return $("#" + this.options.idPrefix + key).attr("dtnode");
1615
- var el = document.getElementById(this.options.idPrefix + key);
1616
- return ( el && el.dtnode ) ? el.dtnode : null;
1617
- },
1618
-
1619
- getActiveNode: function() {
1620
- return this.activeNode;
1621
- },
1622
-
1623
- reactivate: function(setFocus) {
1624
- // Re-fire onQueryActivate and onActivate events.
1625
- var node = this.activeNode;
1626
- // this.logDebug("reactivate %o", node);
1627
- if( node ) {
1628
- this.activeNode = null; // Force re-activating
1629
- node.activate();
1630
- if( setFocus )
1631
- node.focus();
1632
- }
1633
- },
1634
-
1635
- getSelectedNodes: function(stopOnParents) {
1636
- var nodeList = [];
1637
- this.tnRoot.visit(function(dtnode){
1638
- if( dtnode.bSelected ) {
1639
- nodeList.push(dtnode);
1640
- if( stopOnParents == true )
1641
- return false; // stop processing this branch
1642
- }
1643
- });
1644
- return nodeList;
1645
- },
1646
-
1647
- activateKey: function(key) {
1648
- var dtnode = (key === null) ? null : this.getNodeByKey(key);
1649
- if( !dtnode ) {
1650
- if( this.activeNode )
1651
- this.activeNode.deactivate();
1652
- this.activeNode = null;
1653
- return null;
1654
- }
1655
- dtnode.focus();
1656
- dtnode.activate();
1657
- return dtnode;
1658
- },
1659
-
1660
- selectKey: function(key, select) {
1661
- var dtnode = this.getNodeByKey(key);
1662
- if( !dtnode )
1663
- return null;
1664
- dtnode.select(select);
1665
- return dtnode;
1666
- },
1667
-
1668
- enableUpdate: function(bEnable) {
1669
- if ( this.bEnableUpdate==bEnable )
1670
- return bEnable;
1671
- this.bEnableUpdate = bEnable;
1672
- if ( bEnable )
1673
- this.redraw();
1674
- return !bEnable; // return previous value
1675
- },
1676
-
1677
- visit: function(fn, data, includeRoot) {
1678
- return this.tnRoot.visit(fn, data, includeRoot);
1679
- },
1680
-
1681
- _createFromTag: function(parentTreeNode, $ulParent) {
1682
- // Convert a <UL>...</UL> list into children of the parent tree node.
1683
- var self = this;
1684
- /*
1685
- TODO: better?
1686
- this.$lis = $("li:has(a[href])", this.element);
1687
- this.$tabs = this.$lis.map(function() { return $("a", this)[0]; });
1688
- */
1689
- $ulParent.find(">li").each(function() {
1690
- var $li = $(this);
1691
- var $liSpan = $li.find(">span:first");
1692
- var title;
1693
- if( $liSpan.length ) {
1694
- // If a <li><span> tag is specified, use it literally.
1695
- title = $liSpan.html();
1696
- } else {
1697
- // If only a <li> tag is specified, use the trimmed string up to the next child <ul> tag.
1698
- title = $li.html();
1699
- var iPos = title.search(/<ul/i);
1700
- if( iPos>=0 )
1701
- title = $.trim(title.substring(0, iPos));
1702
- else
1703
- title = $.trim(title);
1704
- // self.logDebug("%o", title);
1705
- }
1706
- // Parse node options from ID, title and class attributes
1707
- var data = {
1708
- title: title,
1709
- isFolder: $li.hasClass("folder"),
1710
- isLazy: $li.hasClass("lazy"),
1711
- expand: $li.hasClass("expanded"),
1712
- select: $li.hasClass("selected"),
1713
- activate: $li.hasClass("active"),
1714
- focus: $li.hasClass("focused")
1715
- };
1716
- if( $li.attr("title") )
1717
- data.tooltip = $li.attr("title");
1718
- if( $li.attr("id") )
1719
- data.key = $li.attr("id");
1720
- // If a data attribute is present, evaluate as a JavaScript object
1721
- if( $li.attr("data") ) {
1722
- var dataAttr = $.trim($li.attr("data"));
1723
- if( dataAttr ) {
1724
- if( dataAttr.charAt(0) != "{" )
1725
- dataAttr = "{" + dataAttr + "}"
1726
- try {
1727
- $.extend(data, eval("(" + dataAttr + ")"));
1728
- } catch(e) {
1729
- throw ("Error parsing node data: " + e + "\ndata:\n'" + dataAttr + "'");
1730
- }
1731
- }
1732
- }
1733
- childNode = parentTreeNode.addChild(data);
1734
- // Recursive reading of child nodes, if LI tag contains an UL tag
1735
- var $ul = $li.find(">ul:first");
1736
- if( $ul.length ) {
1737
- self._createFromTag(childNode, $ul); // must use 'self', because 'this' is the each() context
1738
- }
1739
- });
1740
- },
1741
-
1742
- _checkConsistency: function() {
1743
- // this.logDebug("tree._checkConsistency() NOT IMPLEMENTED - %o", this);
1744
- },
1745
-
1746
- // --- end of class
1747
- lastentry: undefined
1748
- };
1749
-
1750
- /*************************************************************************
1751
- * widget $(..).dynatree
1752
- */
1753
-
1754
- $.widget("ui.dynatree", {
1755
- init: function() {
1756
- // 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.");
1758
- return this._init();
1759
- },
1760
-
1761
- _init: function() {
1762
- if( parseFloat($.ui.version) < 1.8 ) {
1763
- // jquery.ui.core 1.8 renamed _init() to _create(): this stub assures backward compatibility
1764
- _log("warn", "ui.dynatree._init() was called; you should upgrade to jquery.ui.core.js v1.8 or higher.");
1765
- return this._create();
1766
- }
1767
- // jquery.ui.core 1.8 still uses _init() to perform "default functionality"
1768
- _log("debug", "ui.dynatree._init() was called; no current default functionality.");
1769
- },
1770
-
1771
- _create: function() {
1772
- if( parseFloat($.ui.version) >= 1.8 ) {
1773
- this.options = $.extend(true, $[this.namespace][this.widgetName].defaults, this.options);
1774
- }
1775
- logMsg("Dynatree._create(): version='%s', debugLevel=%o.", DynaTree.version, this.options.debugLevel);
1776
- var opts = this.options;
1777
- // The widget framework supplies this.element and this.options.
1778
- this.options.event += ".dynatree"; // namespace event
1779
-
1780
- var divTree = this.element.get(0);
1781
- /* // Clear container, in case it contained some 'waiting' or 'error' text
1782
- // for clients that don't support JS
1783
- if( opts.children || (opts.initAjax && opts.initAjax.url) || opts.initId )
1784
- $(divTree).empty();
1785
- */
1786
- // Create the DynaTree object
1787
- this.tree = new DynaTree(this);
1788
- this.tree._load();
1789
- this.tree.logDebug("Dynatree._create(): done.");
1790
- },
1791
-
1792
- bind: function() {
1793
- var $this = this.element;
1794
- var o = this.options;
1795
-
1796
- // Prevent duplicate binding
1797
- this.unbind();
1798
-
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
- var eventNames = "click.dynatree dblclick.dynatree";
1810
- if( o.keyboard ) // Note: leading ' '!
1811
- eventNames += " keypress.dynatree keydown.dynatree";
1812
- $this.bind(eventNames, function(event){
1813
- var dtnode = __getNodeFromElement(event.target);
1814
- if( !dtnode )
1815
- return true; // Allow bubbling of other events
1816
- var prevPhase = dtnode.tree.phase;
1817
- dtnode.tree.phase = "userEvent";
1818
- try {
1819
- dtnode.tree.logDebug("bind(%o): dtnode: %o", event, dtnode);
1820
-
1821
- switch(event.type) {
1822
- case "click":
1823
- return ( o.onClick && o.onClick(dtnode, event)===false ) ? false : dtnode.onClick(event);
1824
- case "dblclick":
1825
- return ( o.onDblClick && o.onDblClick(dtnode, event)===false ) ? false : dtnode.onDblClick(event);
1826
- case "keydown":
1827
- return ( o.onKeydown && o.onKeydown(dtnode, event)===false ) ? false : dtnode.onKeydown(event);
1828
- case "keypress":
1829
- return ( o.onKeypress && o.onKeypress(dtnode, event)===false ) ? false : dtnode.onKeypress(event);
1830
- };
1831
- } catch(e) {
1832
- var _ = null; // issue 117
1833
- // dtnode.tree.logError("bind(%o): dtnode: %o", event, dtnode);
1834
- } finally {
1835
- dtnode.tree.phase = prevPhase;
1836
- }
1837
- });
1838
-
1839
- // focus/blur don't bubble, i.e. are not delegated to parent <div> tags,
1840
- // so we use the addEventListener capturing phase.
1841
- // See http://www.howtocreate.co.uk/tutorials/javascript/domevents
1842
- function __focusHandler(event) {
1843
- // Handles blur and focus.
1844
- // Fix event for IE:
1845
- event = arguments[0] = $.event.fix( event || window.event );
1846
- var dtnode = __getNodeFromElement(event.target);
1847
- return dtnode ? dtnode.onFocus(event) : false;
1848
- }
1849
- var div = this.tree.divTree;
1850
- if( div.addEventListener ) {
1851
- div.addEventListener("focus", __focusHandler, true);
1852
- div.addEventListener("blur", __focusHandler, true);
1853
- } else {
1854
- div.onfocusin = div.onfocusout = __focusHandler;
1855
- }
1856
- // EVENTS
1857
- // disable click if event is configured to something else
1858
- // if (!(/^click/).test(o.event))
1859
- // this.$tabs.bind("click.tabs", function() { return false; });
1860
-
1861
- },
1862
-
1863
- unbind: function() {
1864
- this.element.unbind(".dynatree");
1865
- },
1866
-
1867
- /* TODO: we could handle option changes during runtime here (maybe to re-render, ...)
1868
- setData: function(key, value) {
1869
- this.tree.logDebug("dynatree.setData('" + key + "', '" + value + "')");
1870
- },
1871
- */
1872
- enable: function() {
1873
- this.bind();
1874
- // Call default disable(): remove -disabled from css:
1875
- $.widget.prototype.enable.apply(this, arguments);
1876
- },
1877
-
1878
- disable: function() {
1879
- this.unbind();
1880
- // Call default disable(): add -disabled to css:
1881
- $.widget.prototype.disable.apply(this, arguments);
1882
- },
1883
-
1884
- // --- getter methods (i.e. NOT returning a reference to $)
1885
- getTree: function() {
1886
- return this.tree;
1887
- },
1888
-
1889
- getRoot: function() {
1890
- return this.tree.getRoot();
1891
- },
1892
-
1893
- getActiveNode: function() {
1894
- return this.tree.getActiveNode();
1895
- },
1896
-
1897
- getSelectedNodes: function() {
1898
- return this.tree.getSelectedNodes();
1899
- },
1900
-
1901
- // ------------------------------------------------------------------------
1902
- lastentry: undefined
1903
- });
1904
-
1905
-
1906
- // The following methods return a value (thus breaking the jQuery call chain):
1907
-
1908
- $.ui.dynatree.getter = "getTree getRoot getActiveNode getSelectedNodes";
1909
-
1910
-
1911
- // Plugin default options:
1912
-
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.
1916
- minExpandLevel: 1, // 1: root node is not collapsible
1917
- imagePath: null, // Path to a folder containing icons. Defaults to 'skin/' subdirectory.
1918
- children: null, // Init tree structure from this object array.
1919
- initId: null, // Init tree structure from a <ul> element with this ID.
1920
- initAjax: null, // Ajax options used to initialize the tree strucuture.
1921
- autoFocus: true, // Set focus to first child, when expanding or lazy-loading.
1922
- keyboard: true, // Support keyboard navigation.
1923
- persist: false, // Persist expand-status to a cookie
1924
- autoCollapse: false, // Automatically collapse all siblings, when a node is expanded.
1925
- clickFolderMode: 3, // 1:activate, 2:expand, 3:activate and expand
1926
- activeVisible: true, // Make sure, active nodes are visible (expanded).
1927
- checkbox: false, // Show checkboxes.
1928
- selectMode: 2, // 1:single, 2:multi, 3:multi-hier
1929
- fx: null, // Animations, e.g. null or { height: "toggle", duration: 200 }
1930
-
1931
- // Low level event handlers: onEvent(dtnode, event): return false, to stop default processing
1932
- onClick: null, // null: generate focus, expand, activate, select events.
1933
- onDblClick: null, // (No default actions.)
1934
- onKeydown: null, // null: generate keyboard navigation (focus, expand, activate).
1935
- onKeypress: null, // (No default actions.)
1936
- onFocus: null, // null: set focus to node.
1937
- onBlur: null, // null: remove focus from node.
1938
-
1939
- // Pre-event handlers onQueryEvent(flag, dtnode): return false, to stop processing
1940
- onQueryActivate: null, // Callback(flag, dtnode) before a node is (de)activated.
1941
- onQuerySelect: null, // Callback(flag, dtnode) before a node is (de)selected.
1942
- onQueryExpand: null, // Callback(flag, dtnode) before a node is expanded/collpsed.
1943
-
1944
- // High level event handlers
1945
- onPostInit: null, // Callback(isReloading, isError) when tree was (re)loaded.
1946
- onActivate: null, // Callback(dtnode) when a node is activated.
1947
- onDeactivate: null, // Callback(dtnode) when a node is deactivated.
1948
- onSelect: null, // Callback(flag, dtnode) when a node is (de)selected.
1949
- onExpand: null, // Callback(dtnode) when a node is expanded/collapsed.
1950
- onLazyRead: null, // Callback(dtnode) when a lazy node is expanded for the first time.
1951
-
1952
- ajaxDefaults: { // Used by initAjax option
1953
- cache: false, // false: Append random '_' argument to the request url to prevent caching.
1954
- dataType: "json" // Expect json format and pass json object to callbacks.
1955
- },
1956
- strings: {
1957
- loading: "Loading&#8230;",
1958
- loadError: "Load error!"
1959
- },
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.
1962
- cookieId: "dynatree", // Choose a more unique name, to allow multiple trees.
1963
- cookie: {
1964
- expires: null //7, // Days or Date; null: session cookie
1965
- // path: "/", // Defaults to current page
1966
- // domain: "jquery.com",
1967
- // secure: true
1968
- },
1969
- // Class names used, when rendering the HTML markup.
1970
- // Note: if only single entries are passed for options.classNames, all other
1971
- // values are still set to default.
1972
- classNames: {
1973
- container: "ui-dynatree-container",
1974
- folder: "ui-dynatree-folder",
1975
- document: "ui-dynatree-document",
1976
-
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",
1984
-
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,
2001
-
2002
- // ------------------------------------------------------------------------
2003
- lastentry: undefined
2004
- };
2005
-
2006
- /**
2007
- * Reserved data attributes for a tree node.
2008
- */
2009
- $.ui.dynatree.nodedatadefaults = {
2010
- title: null, // (required) Displayed name of the node (html is allowed here)
2011
- key: null, // May be used with activate(), select(), find(), ...
2012
- isFolder: false, // Use a folder icon. Also the node is expandable but not selectable.
2013
- isLazy: false, // Call onLazyRead(), when the node is expanded for the first time to allow for delayed creation of children.
2014
- tooltip: null, // Show this popup text.
2015
- icon: null, // Use a custom image (filename relative to tree.options.imagePath). 'null' for default icon, 'false' for no icon.
2016
- addClass: null, // Class name added to the node's span tag.
2017
- activate: false, // Initial active status.
2018
- focus: false, // Initial focused status.
2019
- expand: false, // Initial expanded status.
2020
- select: false, // Initial selected status.
2021
- hideCheckbox: false, // Suppress checkbox display for this node.
2022
- unselectable: false, // Prevent selection.
2023
- // disabled: false,
2024
- // The following attributes are only valid if passed to some functions:
2025
- children: null, // Array of child nodes.
2026
- // NOTE: we can also add custom attributes here.
2027
- // This may then also be used in the onActivate(), onSelect() or onLazyTree() callbacks.
2028
- // ------------------------------------------------------------------------
2029
- lastentry: undefined
2030
- };
2031
-
2032
- // ---------------------------------------------------------------------------
2033
- })(jQuery);
2034
-
2035
- // Eclipse syntax parser breaks on this expression, so we put it at the bottom.
2036
- var _rexDtLibName = /.*dynatree[^/]*\.js$/i;
1
+ /*************************************************************************
2
+ jquery.dynatree.js
3
+ Dynamic tree view control, with support for lazy loading of branches.
4
+
5
+ Copyright (c) 2008-2010 Martin Wendt (http://wwWendt.de)
6
+ Licensed under the MIT License (MIT-License.txt)
7
+
8
+ A current version and some documentation is available at
9
+ http://dynatree.googlecode.com/
10
+
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$
15
+
16
+ @depends: jquery.js
17
+ @depends: ui.core.js
18
+ @depends: jquery.cookie.js
19
+ *************************************************************************/
20
+
21
+
22
+ /*************************************************************************
23
+ * Debug functions
24
+ */
25
+
26
+ var _canLog = true;
27
+
28
+ function _log(mode, msg) {
29
+ /**
30
+ * Usage: logMsg("%o was toggled", this);
31
+ */
32
+ if( !_canLog )
33
+ return;
34
+ // Remove first argument
35
+ var args = Array.prototype.slice.apply(arguments, [1]);
36
+ // Prepend timestamp
37
+ var dt = new Date();
38
+ var tag = dt.getHours()+":"+dt.getMinutes()+":"+dt.getSeconds()+"."+dt.getMilliseconds();
39
+ args[0] = tag + " - " + args[0];
40
+
41
+ try {
42
+ switch( mode ) {
43
+ case "info":
44
+ window.console.info.apply(window.console, args);
45
+ break;
46
+ case "warn":
47
+ window.console.warn.apply(window.console, args);
48
+ break;
49
+ default:
50
+ window.console.log.apply(window.console, args);
51
+ }
52
+ } catch(e) {
53
+ if( !window.console )
54
+ _canLog = false; // Permanently disable, when logging is not supported by the browser
55
+ }
56
+ }
57
+
58
+ function logMsg(msg) {
59
+ Array.prototype.unshift.apply(arguments, ["debug"]);
60
+ _log.apply(this, arguments);
61
+ }
62
+
63
+
64
+ // Forward declaration
65
+ var getDynaTreePersistData = undefined;
66
+
67
+
68
+
69
+ /*************************************************************************
70
+ * Constants
71
+ */
72
+ var DTNodeStatus_Error = -1;
73
+ var DTNodeStatus_Loading = 1;
74
+ var DTNodeStatus_Ok = 0;
75
+
76
+
77
+ // Start of local namespace
78
+ ;(function($) {
79
+
80
+ /*************************************************************************
81
+ * Common tool functions.
82
+ */
83
+
84
+ var Class = {
85
+ create: function() {
86
+ return function() {
87
+ this.initialize.apply(this, arguments);
88
+ }
89
+ }
90
+ }
91
+
92
+ /*************************************************************************
93
+ * Class DynaTreeNode
94
+ */
95
+ var DynaTreeNode = Class.create();
96
+
97
+ DynaTreeNode.prototype = {
98
+ initialize: function(parent, tree, data) {
99
+ /**
100
+ * @constructor
101
+ */
102
+ this.parent = parent;
103
+ this.tree = tree;
104
+ if ( typeof data == "string" )
105
+ data = { title: data };
106
+ if( data.key == undefined )
107
+ data.key = "_" + tree._nodeCount++;
108
+ this.data = $.extend({}, $.ui.dynatree.nodedatadefaults, data);
109
+ this.div = null; // not yet created
110
+ this.span = null; // not yet created
111
+ this.childList = null; // no subnodes yet
112
+ // this.isRead = false; // Lazy content not yet read
113
+ this.isLoading = false; // Lazy content is being loaded
114
+ this.hasSubSel = false;
115
+ },
116
+
117
+ toString: function() {
118
+ return "dtnode<" + this.data.key + ">: '" + this.data.title + "'";
119
+ },
120
+
121
+ toDict: function(recursive, callback) {
122
+ var dict = $.extend({}, this.data);
123
+ dict.activate = ( this.tree.activeNode === this );
124
+ dict.focus = ( this.tree.focusNode === this );
125
+ dict.expand = this.bExpanded;
126
+ dict.select = this.bSelected;
127
+ if( callback )
128
+ callback(dict);
129
+ if( recursive && this.childList ) {
130
+ dict.children = [];
131
+ for(var i=0; i<this.childList.length; i++ )
132
+ dict.children.push(this.childList[i].toDict(true, callback));
133
+ } else {
134
+ delete dict.children;
135
+ }
136
+ return dict;
137
+ },
138
+
139
+ _getInnerHtml: function() {
140
+ var opts = this.tree.options;
141
+ var cache = this.tree.cache;
142
+ // 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
+
147
+ var res = "";
148
+ var p = this.parent;
149
+ while( p ) {
150
+ // Suppress first connector column, if visible top level is always expanded
151
+ if ( bHideFirstConnector && p==rootParent )
152
+ break;
153
+ res = ( p.isLastSibling() ? cache.tagEmpty : cache.tagVline) + res;
154
+ p = p.parent;
155
+ }
156
+
157
+ // connector (expanded, expandable or simple)
158
+ if( bHideFirstExpander && this.parent==rootParent ) {
159
+ // skip connector
160
+ } else if ( this.childList || this.data.isLazy ) {
161
+ res += cache.tagExpander;
162
+ } else {
163
+ res += cache.tagConnector;
164
+ }
165
+
166
+ // Checkbox mode
167
+ if( opts.checkbox && this.data.hideCheckbox!=true && !this.data.isStatusNode ) {
168
+ res += cache.tagCheckbox;
169
+ }
170
+
171
+ // folder or doctype icon
172
+ if ( this.data.icon ) {
173
+ res += "<img src='" + opts.imagePath + this.data.icon + "' alt='' />";
174
+ } else if ( this.data.icon == false ) {
175
+ // icon == false means 'no icon'
176
+ } else {
177
+ // icon == null means 'default icon'
178
+ res += cache.tagNodeIcon;
179
+ }
180
+
181
+ // node name
182
+ var tooltip = ( this.data && typeof this.data.tooltip == "string" ) ? " title='" + this.data.tooltip + "'" : "";
183
+ res += "<a href='#' class='" + opts.classNames.title + "'" + tooltip + ">" + this.data.title + "</a>";
184
+ return res;
185
+ },
186
+
187
+ _fixOrder: function() {
188
+ /**
189
+ * Make sure, that <div> order matches childList order.
190
+ */
191
+ var cl = this.childList;
192
+ if( !cl )
193
+ return;
194
+ var childDiv = this.div.firstChild.nextSibling;
195
+ for(var i=0; i<cl.length-1; i++) {
196
+ var childNode1 = cl[i];
197
+ var childNode2 = childDiv.firstChild.dtnode;
198
+ if( childNode1 !== childNode2 ) {
199
+ //
200
+ this.tree.logDebug("_fixOrder: mismatch at index " + i + ": " + childNode1 + " != " + childNode2);
201
+ this.div.insertBefore(childNode1.div, childNode2.div);
202
+ } else {
203
+ childDiv = childDiv.nextSibling;
204
+ }
205
+ }
206
+ },
207
+
208
+ render: function(bDeep, bHidden) {
209
+ /**
210
+ * Create HTML markup for this node.
211
+ *
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>
217
+ */
218
+ // this.tree.logDebug("%o.render()", this);
219
+ var opts = this.tree.options;
220
+ var cn = opts.classNames;
221
+ 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);
233
+ }
234
+
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) ) {
277
+ for(var i=0; i<this.childList.length; i++) {
278
+ this.childList[i].render(bDeep, bHidden)
279
+ }
280
+ this._fixOrder();
281
+ }
282
+ },
283
+
284
+ hasChildren: function() {
285
+ return this.childList != null;
286
+ },
287
+
288
+ isLastSibling: function() {
289
+ var p = this.parent;
290
+ if ( !p ) return true;
291
+ return p.childList[p.childList.length-1] === this;
292
+ },
293
+
294
+ prevSibling: function() {
295
+ if( !this.parent ) return null;
296
+ var ac = this.parent.childList;
297
+ for(var i=1; i<ac.length; i++) // start with 1, so prev(first) = null
298
+ if( ac[i] === this )
299
+ return ac[i-1];
300
+ return null;
301
+ },
302
+
303
+ nextSibling: function() {
304
+ if( !this.parent ) return null;
305
+ var ac = this.parent.childList;
306
+ for(var i=0; i<ac.length-1; i++) // up to length-2, so next(last) = null
307
+ if( ac[i] === this )
308
+ return ac[i+1];
309
+ return null;
310
+ },
311
+
312
+ _setStatusNode: function(data) {
313
+ // Create, modify or remove the status child node (pass 'null', to remove it).
314
+ var firstChild = ( this.childList ? this.childList[0] : null );
315
+ if( !data ) {
316
+ if ( firstChild ) {
317
+ this.div.removeChild(firstChild.div);
318
+ if( this.childList.length == 1 )
319
+ this.childList = null;
320
+ else
321
+ this.childList.shift();
322
+ }
323
+ } else if ( firstChild ) {
324
+ data.isStatusNode = true;
325
+ firstChild.data = data;
326
+ firstChild.render(false, false);
327
+ } else {
328
+ data.isStatusNode = true;
329
+ firstChild = this.addChild(data);
330
+ }
331
+ },
332
+
333
+ setLazyNodeStatus: function(lts, opts) {
334
+ var tooltip = (opts && opts.tooltip) ? opts.tooltip : null;
335
+ var info = (opts && opts.info) ? " (" + opts.info + ")" : "";
336
+ switch( lts ) {
337
+ case DTNodeStatus_Ok:
338
+ this._setStatusNode(null);
339
+ // this.isRead = true;
340
+ this.isLoading = false;
341
+ this.render(false, false);
342
+ if( this.tree.options.autoFocus ) {
343
+ if( this === this.tree.tnRoot && !this.tree.options.rootVisible && this.childList ) {
344
+ // special case: using ajaxInit
345
+ this.childList[0].focus();
346
+ } else {
347
+ this.focus();
348
+ }
349
+ }
350
+ break;
351
+ case DTNodeStatus_Loading:
352
+ this.isLoading = true;
353
+ this._setStatusNode({
354
+ title: this.tree.options.strings.loading + info,
355
+ tooltip: tooltip,
356
+ addClass: this.tree.options.classNames.nodeWait
357
+ });
358
+ break;
359
+ case DTNodeStatus_Error:
360
+ this.isLoading = false;
361
+ this._setStatusNode({
362
+ title: this.tree.options.strings.loadError + info,
363
+ tooltip: tooltip,
364
+ addClass: this.tree.options.classNames.nodeError
365
+ });
366
+ break;
367
+ default:
368
+ throw "Bad LazyNodeStatus: '" + lts + "'.";
369
+ }
370
+ },
371
+
372
+ _parentList: function(includeRoot, includeSelf) {
373
+ var l = [];
374
+ var dtn = includeSelf ? this : this.parent;
375
+ while( dtn ) {
376
+ if( includeRoot || dtn.parent )
377
+ l.unshift(dtn);
378
+ dtn = dtn.parent;
379
+ };
380
+ return l;
381
+ },
382
+
383
+ getLevel: function() {
384
+ var level = 0;
385
+ var dtn = this.parent;
386
+ while( dtn ) {
387
+ level++;
388
+ dtn = dtn.parent;
389
+ };
390
+ return level;
391
+ },
392
+
393
+ _getTypeForOuterNodeEvent: function(event) {
394
+ /** Return the inner node span (title, checkbox or expander) if
395
+ * event.target points to the outer span.
396
+ * This function should fix issue #93:
397
+ * FF2 ignores empty spans, when generating events (returning the parent instead).
398
+ */
399
+ var cns = this.tree.options.classNames;
400
+ var target = event.target;
401
+ // 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 ) {
404
+ return null
405
+ }
406
+ // Event coordinates, relative to outer node span:
407
+ var eventX = event.pageX - target.offsetLeft;
408
+ var eventY = event.pageY - target.offsetTop;
409
+
410
+ for(var i=0; i<target.childNodes.length; i++) {
411
+ var cn = target.childNodes[i];
412
+ var x = cn.offsetLeft - target.offsetLeft;
413
+ var y = cn.offsetTop - target.offsetTop;
414
+ var nx = cn.clientWidth, ny = cn.clientHeight;
415
+ // alert (cn.className + ": " + x + ", " + y + ", s:" + nx + ", " + ny);
416
+ if( eventX>=x && eventX<=(x+nx) && eventY>=y && eventY<=(y+ny) ) {
417
+ // alert("HIT "+ cn.className);
418
+ if( cn.className==cns.title )
419
+ return "title";
420
+ else if( cn.className==cns.expander )
421
+ return "expander";
422
+ else if( cn.className==cns.checkbox )
423
+ return "checkbox";
424
+ else if( cn.className==cns.nodeIcon )
425
+ return "icon";
426
+ }
427
+ }
428
+ return "prefix";
429
+ },
430
+
431
+ getEventTargetType: function(event) {
432
+ // 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.
434
+ var tcn = event && event.target ? event.target.className : "";
435
+ var cns = this.tree.options.classNames;
436
+
437
+ if( tcn == cns.title )
438
+ return "title";
439
+ else if( tcn==cns.expander )
440
+ return "expander";
441
+ else if( tcn==cns.checkbox )
442
+ return "checkbox";
443
+ else if( tcn==cns.nodeIcon )
444
+ return "icon";
445
+ else if( tcn==cns.empty || tcn==cns.vline || tcn==cns.connector )
446
+ return "prefix";
447
+ else if( tcn.indexOf(cns.folder)>=0 || tcn.indexOf(cns.document)>=0 )
448
+ // FIX issue #93
449
+ return this._getTypeForOuterNodeEvent(event);
450
+ return null;
451
+ },
452
+
453
+ isVisible: function() {
454
+ // Return true, if all parents are expanded.
455
+ var parents = this._parentList(true, false);
456
+ for(var i=0; i<parents.length; i++)
457
+ if( ! parents[i].bExpanded ) return false;
458
+ return true;
459
+ },
460
+
461
+ makeVisible: function() {
462
+ // Make sure, all parents are expanded
463
+ var parents = this._parentList(true, false);
464
+ for(var i=0; i<parents.length; i++)
465
+ parents[i]._expand(true);
466
+ },
467
+
468
+ focus: function() {
469
+ // TODO: check, if we already have focus
470
+ // this.tree.logDebug("dtnode.focus(): %o", this);
471
+ this.makeVisible();
472
+ try {
473
+ $(this.span).find(">a").focus();
474
+ } catch(e) { }
475
+ },
476
+
477
+ _activate: function(flag, fireEvents) {
478
+ // (De)Activate - but not focus - this node.
479
+ this.tree.logDebug("dtnode._activate(%o, fireEvents=%o) - %o", flag, fireEvents, this);
480
+ var opts = this.tree.options;
481
+ if( this.data.isStatusNode )
482
+ return;
483
+ if ( fireEvents && opts.onQueryActivate && opts.onQueryActivate.call(this.span, flag, this) == false )
484
+ return; // Callback returned false
485
+
486
+ if( flag ) {
487
+ // Activate
488
+ if( this.tree.activeNode ) {
489
+ if( this.tree.activeNode === this )
490
+ return;
491
+ this.tree.activeNode.deactivate();
492
+ }
493
+ if( opts.activeVisible )
494
+ this.makeVisible();
495
+ this.tree.activeNode = this;
496
+ if( opts.persist )
497
+ $.cookie(opts.cookieId+"-active", this.data.key, opts.cookie);
498
+ this.tree.persistence.activeKey = this.data.key;
499
+ $(this.span).addClass(opts.classNames.active);
500
+ if ( fireEvents && opts.onActivate ) // Pass element as 'this' (jQuery convention)
501
+ opts.onActivate.call(this.span, this);
502
+ } else {
503
+ // Deactivate
504
+ if( this.tree.activeNode === this ) {
505
+ var opts = this.tree.options;
506
+ if ( opts.onQueryActivate && opts.onQueryActivate.call(this.span, false, this) == false )
507
+ return; // Callback returned false
508
+ $(this.span).removeClass(opts.classNames.active);
509
+ if( opts.persist ) {
510
+ // Note: we don't pass null, but ''. So the cookie is not deleted.
511
+ // If we pass null, we also have to pass a COPY of opts, because $cookie will override opts.expires (issue 84)
512
+ $.cookie(opts.cookieId+"-active", "", opts.cookie);
513
+ }
514
+ this.tree.persistence.activeKey = null;
515
+ this.tree.activeNode = null;
516
+ if ( fireEvents && opts.onDeactivate )
517
+ opts.onDeactivate.call(this.span, this);
518
+ }
519
+ }
520
+ },
521
+
522
+ activate: function() {
523
+ // Select - but not focus - this node.
524
+ // this.tree.logDebug("dtnode.activate(): %o", this);
525
+ this._activate(true, true);
526
+ },
527
+
528
+ deactivate: function() {
529
+ // this.tree.logDebug("dtnode.deactivate(): %o", this);
530
+ this._activate(false, true);
531
+ },
532
+
533
+ isActive: function() {
534
+ return (this.tree.activeNode === this);
535
+ },
536
+
537
+ _userActivate: function() {
538
+ // Handle user click / [space] / [enter], according to clickFolderMode.
539
+ var activate = true;
540
+ var expand = false;
541
+ if ( this.data.isFolder ) {
542
+ switch( this.tree.options.clickFolderMode ) {
543
+ case 2:
544
+ activate = false;
545
+ expand = true;
546
+ break;
547
+ case 3:
548
+ activate = expand = true;
549
+ break;
550
+ }
551
+ }
552
+ if( this.parent == null && this.tree.options.minExpandLevel>0 ) {
553
+ expand = false;
554
+ }
555
+ if( expand ) {
556
+ this.toggleExpand();
557
+ this.focus();
558
+ }
559
+ if( activate ) {
560
+ this.activate();
561
+ }
562
+ },
563
+
564
+ _setSubSel: function(hasSubSel) {
565
+ if( hasSubSel ) {
566
+ this.hasSubSel = true;
567
+ $(this.span).addClass(this.tree.options.classNames.partsel);
568
+ } else {
569
+ this.hasSubSel = false;
570
+ $(this.span).removeClass(this.tree.options.classNames.partsel);
571
+ }
572
+ },
573
+
574
+ _fixSelectionState: function() {
575
+ // fix selection status, for multi-hier mode
576
+ // this.tree.logDebug("_fixSelectionState(%o) - %o", this.bSelected, this);
577
+ if( this.bSelected ) {
578
+ // Select all children
579
+ this.visit(function(dtnode){
580
+ dtnode.parent._setSubSel(true);
581
+ dtnode._select(true, false, false);
582
+ });
583
+ // Select parents, if all children are selected
584
+ var p = this.parent;
585
+ while( p ) {
586
+ p._setSubSel(true);
587
+ var allChildsSelected = true;
588
+ for(var i=0; i<p.childList.length; i++) {
589
+ var n = p.childList[i];
590
+ if( !n.bSelected && !n.data.isStatusNode ) {
591
+ allChildsSelected = false;
592
+ break;
593
+ }
594
+ }
595
+ if( allChildsSelected )
596
+ p._select(true, false, false);
597
+ p = p.parent;
598
+ }
599
+ } else {
600
+ // Deselect all children
601
+ this._setSubSel(false);
602
+ this.visit(function(dtnode){
603
+ dtnode._setSubSel(false);
604
+ dtnode._select(false, false, false);
605
+ });
606
+ // Deselect parents, and recalc hasSubSel
607
+ var p = this.parent;
608
+ while( p ) {
609
+ p._select(false, false, false);
610
+ var isPartSel = false;
611
+ for(var i=0; i<p.childList.length; i++) {
612
+ if( p.childList[i].bSelected || p.childList[i].hasSubSel ) {
613
+ isPartSel = true;
614
+ break;
615
+ }
616
+ }
617
+ p._setSubSel(isPartSel);
618
+ p = p.parent;
619
+ }
620
+ }
621
+ },
622
+
623
+ _select: function(sel, fireEvents, deep) {
624
+ // Select - but not focus - this node.
625
+ // this.tree.logDebug("dtnode._select(%o) - %o", sel, this);
626
+ var opts = this.tree.options;
627
+ if( this.data.isStatusNode )
628
+ return;
629
+ //
630
+ if( this.bSelected == sel ) {
631
+ // this.tree.logDebug("dtnode._select(%o) IGNORED - %o", sel, this);
632
+ return;
633
+ }
634
+ // Allow event listener to abort selection
635
+ if ( fireEvents && opts.onQuerySelect && opts.onQuerySelect.call(this.span, sel, this) == false )
636
+ return; // Callback returned false
637
+
638
+ // Force single-selection
639
+ if( opts.selectMode==1 && sel ) {
640
+ this.tree.visit(function(dtnode){
641
+ if( dtnode.bSelected ) {
642
+ // Deselect; assuming that in selectMode:1 there's max. one other selected node
643
+ dtnode._select(false, false, false);
644
+ return false;
645
+ }
646
+ });
647
+ }
648
+
649
+ this.bSelected = sel;
650
+ // this.tree._changeNodeList("select", this, sel);
651
+
652
+ if( sel ) {
653
+ if( opts.persist )
654
+ this.tree.persistence.addSelect(this.data.key);
655
+
656
+ $(this.span).addClass(opts.classNames.selected);
657
+
658
+ if( deep && opts.selectMode==3 )
659
+ this._fixSelectionState();
660
+
661
+ if ( fireEvents && opts.onSelect )
662
+ opts.onSelect.call(this.span, true, this);
663
+
664
+ } else {
665
+ if( opts.persist )
666
+ this.tree.persistence.clearSelect(this.data.key);
667
+
668
+ $(this.span).removeClass(opts.classNames.selected);
669
+
670
+ if( deep && opts.selectMode==3 )
671
+ this._fixSelectionState();
672
+
673
+ if ( fireEvents && opts.onSelect )
674
+ opts.onSelect.call(this.span, false, this);
675
+ }
676
+ },
677
+
678
+ select: function(sel) {
679
+ // Select - but not focus - this node.
680
+ // this.tree.logDebug("dtnode.select(%o) - %o", sel, this);
681
+ if( this.data.unselectable )
682
+ return this.bSelected;
683
+ return this._select(sel!=false, true, true);
684
+ },
685
+
686
+ toggleSelect: function() {
687
+ // this.tree.logDebug("dtnode.toggleSelect() - %o", this);
688
+ return this.select(!this.bSelected);
689
+ },
690
+
691
+ isSelected: function() {
692
+ return this.bSelected;
693
+ },
694
+
695
+ _loadContent: function() {
696
+ try {
697
+ var opts = this.tree.options;
698
+ this.tree.logDebug("_loadContent: start - %o", this);
699
+ this.setLazyNodeStatus(DTNodeStatus_Loading);
700
+ if( true == opts.onLazyRead.call(this.span, this) ) {
701
+ // If function returns 'true', we assume that the loading is done:
702
+ this.setLazyNodeStatus(DTNodeStatus_Ok);
703
+ // Otherwise (i.e. if the loading was started as an asynchronous process)
704
+ // the onLazyRead(dtnode) handler is expected to call dtnode.setLazyNodeStatus(DTNodeStatus_Ok/_Error) when done.
705
+ this.tree.logDebug("_loadContent: succeeded - %o", this);
706
+ }
707
+ } catch(e) {
708
+ // alert(e);
709
+ this.setLazyNodeStatus(DTNodeStatus_Error);
710
+ this.tree.logWarning("_loadContent: failed - %o", e);
711
+ }
712
+ },
713
+
714
+ _expand: function(bExpand) {
715
+ // this.tree.logDebug("dtnode._expand(%o) - %o", bExpand, this);
716
+ if( this.bExpanded == bExpand ) {
717
+ // this.tree.logDebug("dtnode._expand(%o) IGNORED - %o", bExpand, this);
718
+ return;
719
+ }
720
+ var opts = this.tree.options;
721
+ if( !bExpand && this.getLevel()<opts.minExpandLevel ) {
722
+ this.tree.logDebug("dtnode._expand(%o) forced expand - %o", bExpand, this);
723
+ return;
724
+ }
725
+ if ( opts.onQueryExpand && opts.onQueryExpand.call(this.span, bExpand, this) == false )
726
+ return; // Callback returned false
727
+ this.bExpanded = bExpand;
728
+
729
+ // Persist expand state
730
+ if( opts.persist ) {
731
+ if( bExpand )
732
+ this.tree.persistence.addExpand(this.data.key);
733
+ else
734
+ this.tree.persistence.clearExpand(this.data.key);
735
+ }
736
+
737
+ this.render(false);
738
+
739
+ // Auto-collapse mode: collapse all siblings
740
+ if( this.bExpanded && this.parent && opts.autoCollapse ) {
741
+ var parents = this._parentList(false, true);
742
+ for(var i=0; i<parents.length; i++)
743
+ parents[i].collapseSiblings();
744
+ }
745
+
746
+ // If the currently active node is now hidden, deactivate it
747
+ if( opts.activeVisible && this.tree.activeNode && ! this.tree.activeNode.isVisible() ) {
748
+ this.tree.activeNode.deactivate();
749
+ }
750
+ // Expanding a lazy node: set 'loading...' and call callback
751
+ if( bExpand && this.data.isLazy && this.childList==null && !this.isLoading ) {
752
+ this._loadContent();
753
+ return;
754
+ }
755
+ // 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
+
778
+ if( opts.fx ) {
779
+ var duration = opts.fx.duration || 200;
780
+ // $(">DIV", this.div).animate(opts.fx, duration);
781
+ $(filter, this.div).animate(opts.fx, duration);
782
+ } 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();
787
+ }
788
+ //*/
789
+ // this.tree.logDebug("_expand: end div toggle - %o", this);
790
+
791
+ if ( opts.onExpand )
792
+ opts.onExpand.call(this.span, bExpand, this);
793
+ },
794
+
795
+ expand: function(flag) {
796
+ if( !this.childList && !this.data.isLazy && flag )
797
+ return; // Prevent expanding empty nodes
798
+ if( this.parent == null && this.tree.options.minExpandLevel>0 && !flag )
799
+ return; // Prevent collapsing the root
800
+ this._expand(flag);
801
+ },
802
+
803
+ toggleExpand: function() {
804
+ this.expand(!this.bExpanded);
805
+ },
806
+
807
+ collapseSiblings: function() {
808
+ if( this.parent == null )
809
+ return;
810
+ var ac = this.parent.childList;
811
+ for (var i=0; i<ac.length; i++) {
812
+ if ( ac[i] !== this && ac[i].bExpanded )
813
+ ac[i]._expand(false);
814
+ }
815
+ },
816
+
817
+ onClick: function(event) {
818
+ // this.tree.logDebug("dtnode.onClick(" + event.type + "): dtnode:" + this + ", button:" + event.button + ", which: " + event.which);
819
+ var targetType = this.getEventTargetType(event);
820
+ if( targetType == "expander" ) {
821
+ // Clicking the expander icon always expands/collapses
822
+ this.toggleExpand();
823
+ this.focus(); // issue 95
824
+ } else if( targetType == "checkbox" ) {
825
+ // Clicking the checkbox always (de)selects
826
+ this.toggleSelect();
827
+ this.focus(); // issue 95
828
+ } else {
829
+ this._userActivate();
830
+ // Chrome and Safari don't focus the a-tag on click
831
+ this.span.getElementsByTagName("a")[0].focus();
832
+ }
833
+ // Make sure that clicks stop, otherwise <a href='#'> jumps to the top
834
+ return false;
835
+ },
836
+
837
+ onDblClick: function(event) {
838
+ // this.tree.logDebug("dtnode.onDblClick(" + event.type + "): dtnode:" + this + ", button:" + event.button + ", which: " + event.which);
839
+ },
840
+
841
+ onKeydown: function(event) {
842
+ // this.tree.logDebug("dtnode.onKeydown(" + event.type + "): dtnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which);
843
+ var handled = true;
844
+ // alert("keyDown" + event.which);
845
+
846
+ switch( event.which ) {
847
+ // charCodes:
848
+ // case 43: // '+'
849
+ case 107: // '+'
850
+ case 187: // '+' @ Chrome, Safari
851
+ if( !this.bExpanded ) this.toggleExpand();
852
+ break;
853
+ // case 45: // '-'
854
+ case 109: // '-'
855
+ case 189: // '+' @ Chrome, Safari
856
+ if( this.bExpanded ) this.toggleExpand();
857
+ break;
858
+ //~ case 42: // '*'
859
+ //~ break;
860
+ //~ case 47: // '/'
861
+ //~ break;
862
+ // case 13: // <enter>
863
+ // <enter> on a focused <a> tag seems to generate a click-event.
864
+ // this._userActivate();
865
+ // break;
866
+ case 32: // <space>
867
+ this._userActivate();
868
+ break;
869
+ case 8: // <backspace>
870
+ if( this.parent )
871
+ this.parent.focus();
872
+ break;
873
+ case 37: // <left>
874
+ if( this.bExpanded ) {
875
+ this.toggleExpand();
876
+ this.focus();
877
+ } else if( this.parent && (this.tree.options.rootVisible || this.parent.parent) ) {
878
+ this.parent.focus();
879
+ }
880
+ break;
881
+ case 39: // <right>
882
+ if( !this.bExpanded && (this.childList || this.data.isLazy) ) {
883
+ this.toggleExpand();
884
+ this.focus();
885
+ } else if( this.childList ) {
886
+ this.childList[0].focus();
887
+ }
888
+ break;
889
+ case 38: // <up>
890
+ var sib = this.prevSibling();
891
+ while( sib && sib.bExpanded && sib.childList )
892
+ sib = sib.childList[sib.childList.length-1];
893
+ if( !sib && this.parent && (this.tree.options.rootVisible || this.parent.parent) )
894
+ sib = this.parent;
895
+ if( sib ) sib.focus();
896
+ break;
897
+ case 40: // <down>
898
+ var sib;
899
+ if( this.bExpanded && this.childList ) {
900
+ sib = this.childList[0];
901
+ } else {
902
+ var parents = this._parentList(false, true);
903
+ for(var i=parents.length-1; i>=0; i--) {
904
+ sib = parents[i].nextSibling();
905
+ if( sib ) break;
906
+ }
907
+ }
908
+ if( sib ) sib.focus();
909
+ break;
910
+ default:
911
+ handled = false;
912
+ }
913
+ // Return false, if handled, to prevent default processing
914
+ return !handled;
915
+ },
916
+
917
+ onKeypress: function(event) {
918
+ // onKeypress is only hooked to allow user callbacks.
919
+ // We don't process it, because IE and Safari don't fire keypress for cursor keys.
920
+ // this.tree.logDebug("dtnode.onKeypress(" + event.type + "): dtnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which);
921
+ },
922
+
923
+ onFocus: function(event) {
924
+ // Handles blur and focus events.
925
+ // this.tree.logDebug("dtnode.onFocus(%o): %o", event, this);
926
+ var opts = this.tree.options;
927
+ if ( event.type=="blur" || event.type=="focusout" ) {
928
+ if ( opts.onBlur ) // Pass element as 'this' (jQuery convention)
929
+ opts.onBlur.call(this.span, this);
930
+ if( this.tree.tnFocused )
931
+ $(this.tree.tnFocused.span).removeClass(opts.classNames.focused);
932
+ this.tree.tnFocused = null;
933
+ if( opts.persist )
934
+ $.cookie(opts.cookieId+"-focus", "", opts.cookie);
935
+ } else if ( event.type=="focus" || event.type=="focusin") {
936
+ // Fix: sometimes the blur event is not generated
937
+ if( this.tree.tnFocused && this.tree.tnFocused !== this ) {
938
+ this.tree.logDebug("dtnode.onFocus: out of sync: curFocus: %o", this.tree.tnFocused);
939
+ $(this.tree.tnFocused.span).removeClass(opts.classNames.focused);
940
+ }
941
+ this.tree.tnFocused = this;
942
+ if ( opts.onFocus ) // Pass element as 'this' (jQuery convention)
943
+ opts.onFocus.call(this.span, this);
944
+ $(this.tree.tnFocused.span).addClass(opts.classNames.focused);
945
+ if( opts.persist )
946
+ $.cookie(opts.cookieId+"-focus", this.data.key, opts.cookie);
947
+ }
948
+ // TODO: return anything?
949
+ // return false;
950
+ },
951
+
952
+ visit: function(fn, data, includeSelf) {
953
+ // Call fn(dtnode, data) for all child nodes. Stop iteration, if fn() returns false.
954
+ var n = 0;
955
+ if( includeSelf == true ) {
956
+ if( fn(this, data) == false )
957
+ return 1;
958
+ n++;
959
+ }
960
+ if ( this.childList )
961
+ for (var i=0; i<this.childList.length; i++)
962
+ n += this.childList[i].visit(fn, data, true);
963
+ return n;
964
+ },
965
+
966
+ remove: function() {
967
+ // Remove this node
968
+ // this.tree.logDebug ("%o.remove()", this);
969
+ if ( this === this.tree.root )
970
+ return false;
971
+ return this.parent.removeChild(this);
972
+ },
973
+
974
+ removeChild: function(tn) {
975
+ // Remove tn from list of direct children.
976
+ var ac = this.childList;
977
+ if( ac.length == 1 ) {
978
+ if( tn !== ac[0] )
979
+ throw "removeChild: invalid child";
980
+ return this.removeChildren();
981
+ }
982
+ if( tn === this.tree.activeNode )
983
+ tn.deactivate();
984
+ if( this.tree.options.persist ) {
985
+ if( tn.bSelected )
986
+ this.tree.persistence.clearSelect(tn.data.key);
987
+ if ( tn.bExpanded )
988
+ this.tree.persistence.clearExpand(tn.data.key);
989
+ }
990
+ tn.removeChildren(true);
991
+ this.div.removeChild(tn.div);
992
+ for(var i=0; i<ac.length; i++) {
993
+ if( ac[i] === tn ) {
994
+ this.childList.splice(i, 1);
995
+ delete tn;
996
+ break;
997
+ }
998
+ }
999
+ },
1000
+
1001
+ removeChildren: function(isRecursiveCall, retainPersistence) {
1002
+ // Remove all child nodes (more efficiently than recursive remove())
1003
+ // this.tree.logDebug ("%o.removeChildren(%o)", this, isRecursiveCall);
1004
+ var tree = this.tree;
1005
+ var ac = this.childList;
1006
+ if( ac ) {
1007
+ for(var i=0; i<ac.length; i++) {
1008
+ var tn=ac[i];
1009
+ // this.tree.logDebug ("del %o", tn);
1010
+ if ( tn === tree.activeNode && !retainPersistence )
1011
+ tn.deactivate();
1012
+ if( this.tree.options.persist && !retainPersistence ) {
1013
+ if( tn.bSelected )
1014
+ this.tree.persistence.clearSelect(tn.data.key);
1015
+ if ( tn.bExpanded )
1016
+ this.tree.persistence.clearExpand(tn.data.key);
1017
+ }
1018
+ tn.removeChildren(true, retainPersistence);
1019
+ this.div.removeChild(tn.div);
1020
+ delete tn;
1021
+ }
1022
+ this.childList = null;
1023
+ }
1024
+ if( ! isRecursiveCall ) {
1025
+ // this._expand(false);
1026
+ // this.isRead = false;
1027
+ this.isLoading = false;
1028
+ this.render(false, false);
1029
+ }
1030
+ },
1031
+
1032
+ reload: function(force) {
1033
+ // Discard lazy content (and reload, if node was expanded).
1034
+ if( this.parent == null )
1035
+ return this.tree.reload();
1036
+
1037
+ if( ! this.data.isLazy )
1038
+ throw "node.reload() requires lazy nodes.";
1039
+ if( this.bExpanded ) {
1040
+ this.expand(false);
1041
+ this.removeChildren();
1042
+ this.expand(true);
1043
+ } else {
1044
+ this.removeChildren();
1045
+ if( force )
1046
+ this._loadContent();
1047
+ }
1048
+ },
1049
+
1050
+ _addChildNode: function(dtnode, beforeNode) {
1051
+ /**
1052
+ * Internal function to add one single DynatreeNode as a child.
1053
+ *
1054
+ */
1055
+ var tree = this.tree;
1056
+ var opts = tree.options;
1057
+ var pers = tree.persistence;
1058
+
1059
+ // tree.logDebug("%o._addChildNode(%o)", this, dtnode);
1060
+
1061
+ // --- Update and fix dtnode attributes if necessary
1062
+ dtnode.parent = this;
1063
+ // if( beforeNode && (beforeNode.parent !== this || beforeNode === dtnode ) )
1064
+ // throw "<beforeNode> must be another child of <this>";
1065
+
1066
+ // --- Add dtnode as a child
1067
+ if ( this.childList==null ) {
1068
+ this.childList = [];
1069
+ } else if( ! beforeNode ) {
1070
+ // Fix 'lastsib'
1071
+ $(this.childList[this.childList.length-1].span).removeClass(opts.classNames.lastsib);
1072
+ }
1073
+ if( beforeNode ) {
1074
+ var iBefore = $.inArray(beforeNode, this.childList);
1075
+ if( iBefore < 0 )
1076
+ throw "<beforeNode> must be a child of <this>";
1077
+ this.childList.splice(iBefore, 0, dtnode);
1078
+ // alert(this.childList);
1079
+ } else {
1080
+ // Append node
1081
+ this.childList.push(dtnode);
1082
+ }
1083
+
1084
+ // --- Handle persistence
1085
+ // Initial status is read from cookies, if persistence is active and
1086
+ // cookies are already present.
1087
+ // Otherwise the status is read from the data attributes and then persisted.
1088
+ var isInitializing = tree.isInitializing();
1089
+ if( opts.persist && pers.cookiesFound && isInitializing ) {
1090
+ // Init status from cookies
1091
+ // tree.logDebug("init from cookie, pa=%o, dk=%o", pers.activeKey, dtnode.data.key);
1092
+ if( pers.activeKey == dtnode.data.key )
1093
+ tree.activeNode = dtnode;
1094
+ if( pers.focusedKey == dtnode.data.key )
1095
+ tree.focusNode = dtnode;
1096
+ dtnode.bExpanded = ($.inArray(dtnode.data.key, pers.expandedKeyList) >= 0);
1097
+ dtnode.bSelected = ($.inArray(dtnode.data.key, pers.selectedKeyList) >= 0);
1098
+ // tree.logDebug(" key=%o, bSelected=%o", dtnode.data.key, dtnode.bSelected);
1099
+ } else {
1100
+ // Init status from data (Note: we write the cookies after the init phase)
1101
+ // tree.logDebug("init from data");
1102
+ if( dtnode.data.activate ) {
1103
+ tree.activeNode = dtnode;
1104
+ if( opts.persist )
1105
+ pers.activeKey = dtnode.data.key;
1106
+ }
1107
+ if( dtnode.data.focus ) {
1108
+ tree.focusNode = dtnode;
1109
+ if( opts.persist )
1110
+ pers.focusedKey = dtnode.data.key;
1111
+ }
1112
+ dtnode.bExpanded = ( dtnode.data.expand == true ); // Collapsed by default
1113
+ if( dtnode.bExpanded && opts.persist )
1114
+ pers.addExpand(dtnode.data.key);
1115
+ dtnode.bSelected = ( dtnode.data.select == true ); // Deselected by default
1116
+ /*
1117
+ Doesn't work, cause pers.selectedKeyList may be null
1118
+ if( dtnode.bSelected && opts.selectMode==1
1119
+ && pers.selectedKeyList && pers.selectedKeyList.length>0 ) {
1120
+ tree.logWarning("Ignored multi-selection in single-mode for %o", dtnode);
1121
+ dtnode.bSelected = false; // Fixing bad input data (multi selection for mode:1)
1122
+ }
1123
+ */
1124
+ if( dtnode.bSelected && opts.persist )
1125
+ pers.addSelect(dtnode.data.key);
1126
+ }
1127
+
1128
+ // Always expand, if it's below minExpandLevel
1129
+ // tree.logDebug ("%o._addChildNode(%o), l=%o", this, dtnode, dtnode.getLevel());
1130
+ if ( opts.minExpandLevel >= dtnode.getLevel() ) {
1131
+ // tree.logDebug ("Force expand for %o", dtnode);
1132
+ this.bExpanded = true;
1133
+ }
1134
+
1135
+ // In multi-hier mode, update the parents selection state
1136
+ // issue #82: only if not initializing, because the children may not exist yet
1137
+ // if( !dtnode.data.isStatusNode && opts.selectMode==3 && !isInitializing )
1138
+ // dtnode._fixSelectionState();
1139
+
1140
+ // In multi-hier mode, update the parents selection state
1141
+ if( dtnode.bSelected && opts.selectMode==3 ) {
1142
+ var p = this;
1143
+ while( p ) {
1144
+ if( !p.hasSubSel )
1145
+ p._setSubSel(true);
1146
+ p = p.parent;
1147
+ }
1148
+ }
1149
+ // render this node and the new child
1150
+ if ( tree.bEnableUpdate )
1151
+ this.render(true, true);
1152
+
1153
+ return dtnode;
1154
+ },
1155
+
1156
+ addChild: function(obj, beforeNode) {
1157
+ /**
1158
+ * Add a node object as child.
1159
+ *
1160
+ * This should be the only place, where a DynaTreeNode is constructed!
1161
+ * (Except for the root node creation in the tree constructor)
1162
+ *
1163
+ * @param obj A JS object (may be recursive) or an array of those.
1164
+ * @param {DynaTreeNode} beforeNode (optional) sibling node.
1165
+ *
1166
+ * Data format: array of node objects, with optional 'children' attributes.
1167
+ * [
1168
+ * { title: "t1", isFolder: true, ... }
1169
+ * { title: "t2", isFolder: true, ...,
1170
+ * children: [
1171
+ * {title: "t2.1", ..},
1172
+ * {..}
1173
+ * ]
1174
+ * }
1175
+ * ]
1176
+ * A simple object is also accepted instead of an array.
1177
+ *
1178
+ */
1179
+ // this.tree.logDebug("%o.addChild(%o, %o)", this, obj, beforeNode);
1180
+ if( !obj || obj.length==0 ) // Passed null or undefined or empty array
1181
+ return;
1182
+ if( obj instanceof DynaTreeNode )
1183
+ return this._addChildNode(obj, beforeNode);
1184
+ if( !obj.length ) // Passed a single data object
1185
+ obj = [ obj ];
1186
+
1187
+ var prevFlag = this.tree.enableUpdate(false);
1188
+
1189
+ var tnFirst = null;
1190
+ for (var i=0; i<obj.length; i++) {
1191
+ var data = obj[i];
1192
+ var dtnode = this._addChildNode(new DynaTreeNode(this, this.tree, data), beforeNode);
1193
+ if( !tnFirst ) tnFirst = dtnode;
1194
+ // Add child nodes recursively
1195
+ if( data.children )
1196
+ dtnode.addChild(data.children, null);
1197
+ }
1198
+ this.tree.enableUpdate(prevFlag);
1199
+ return tnFirst;
1200
+ },
1201
+
1202
+ append: function(obj) {
1203
+ this.tree.logWarning("node.append() is deprecated (use node.addChild() instead).");
1204
+ return this.addChild(obj, null);
1205
+ },
1206
+
1207
+ appendAjax: function(ajaxOptions) {
1208
+ this.removeChildren(false, true);
1209
+ this.setLazyNodeStatus(DTNodeStatus_Loading);
1210
+ // Ajax option inheritance: $.ajaxSetup < $.ui.dynatree.defaults.ajaxDefaults < tree.options.ajaxDefaults < ajaxOptions
1211
+ var self = this;
1212
+ var orgSuccess = ajaxOptions.success;
1213
+ var orgError = ajaxOptions.error;
1214
+ var options = $.extend({}, this.tree.options.ajaxDefaults, ajaxOptions, {
1215
+ /*
1216
+ complete: function(req, textStatus){
1217
+ alert("ajax complete");
1218
+ },
1219
+ timeout: 5000, // 5 sec
1220
+ */
1221
+ success: function(data, textStatus){
1222
+ // <this> is the request options
1223
+ // self.tree.logDebug("appendAjax().success");
1224
+ var prevPhase = self.tree.phase;
1225
+ self.tree.phase = "init";
1226
+ // self.append(data);
1227
+ self.addChild(data, null);
1228
+ self.tree.phase = "postInit";
1229
+ self.setLazyNodeStatus(DTNodeStatus_Ok);
1230
+ if( orgSuccess )
1231
+ orgSuccess.call(options, self);
1232
+ self.tree.phase = prevPhase;
1233
+ },
1234
+ error: function(XMLHttpRequest, textStatus, errorThrown){
1235
+ // <this> is the request options
1236
+ // self.tree.logWarning("appendAjax failed: %o:\n%o\n%o", textStatus, XMLHttpRequest, errorThrown);
1237
+ self.tree.logWarning("appendAjax failed:", textStatus, ":\n", XMLHttpRequest, "\n", errorThrown);
1238
+ self.setLazyNodeStatus(DTNodeStatus_Error, {info: textStatus, tooltip: ""+errorThrown});
1239
+ if( orgError )
1240
+ orgError.call(options, self, XMLHttpRequest, textStatus, errorThrown);
1241
+ }
1242
+ });
1243
+ $.ajax(options);
1244
+ },
1245
+ // --- end of class
1246
+ lastentry: undefined
1247
+ }
1248
+
1249
+ /*************************************************************************
1250
+ * class DynaTreeStatus
1251
+ */
1252
+
1253
+ var DynaTreeStatus = Class.create();
1254
+
1255
+
1256
+ DynaTreeStatus._getTreePersistData = function(cookieId, cookieOpts) {
1257
+ // Static member: Return persistence information from cookies
1258
+ var ts = new DynaTreeStatus(cookieId, cookieOpts);
1259
+ ts.read();
1260
+ return ts.toDict();
1261
+ }
1262
+ // Make available in global scope
1263
+ getDynaTreePersistData = DynaTreeStatus._getTreePersistData;
1264
+
1265
+
1266
+ DynaTreeStatus.prototype = {
1267
+ // Constructor
1268
+ initialize: function(cookieId, cookieOpts) {
1269
+ this._log("DynaTreeStatus: initialize");
1270
+ if( cookieId === undefined )
1271
+ cookieId = $.ui.dynatree.defaults.cookieId;
1272
+ cookieOpts = $.extend({}, $.ui.dynatree.defaults.cookie, cookieOpts);
1273
+
1274
+ this.cookieId = cookieId;
1275
+ this.cookieOpts = cookieOpts;
1276
+ this.cookiesFound = undefined;
1277
+ this.activeKey = null;
1278
+ this.focusedKey = null;
1279
+ this.expandedKeyList = null;
1280
+ this.selectedKeyList = null;
1281
+ },
1282
+ // member functions
1283
+ _log: function(msg) {
1284
+ // this.logDebug("_changeNodeList(%o): nodeList:%o, idx:%o", mode, nodeList, idx);
1285
+ Array.prototype.unshift.apply(arguments, ["debug"]);
1286
+ _log.apply(this, arguments);
1287
+ },
1288
+ read: function() {
1289
+ this._log("DynaTreeStatus: read");
1290
+ // Read or init cookies.
1291
+ this.cookiesFound = false;
1292
+
1293
+ var cookie = $.cookie(this.cookieId + "-active");
1294
+ this.activeKey = ( cookie == null ) ? "" : cookie;
1295
+ if( cookie != null ) this.cookiesFound = true;
1296
+
1297
+ cookie = $.cookie(this.cookieId + "-focus");
1298
+ this.focusedKey = ( cookie == null ) ? "" : cookie;
1299
+ if( cookie != null ) this.cookiesFound = true;
1300
+
1301
+ cookie = $.cookie(this.cookieId + "-expand");
1302
+ this.expandedKeyList = ( cookie == null ) ? [] : cookie.split(",");
1303
+ if( cookie != null ) this.cookiesFound = true;
1304
+
1305
+ cookie = $.cookie(this.cookieId + "-select");
1306
+ this.selectedKeyList = ( cookie == null ) ? [] : cookie.split(",");
1307
+ if( cookie != null ) this.cookiesFound = true;
1308
+ },
1309
+ write: function() {
1310
+ this._log("DynaTreeStatus: write");
1311
+ $.cookie(this.cookieId + "-active", ( this.activeKey == null ) ? "" : this.activeKey, this.cookieOpts);
1312
+ $.cookie(this.cookieId + "-focus", ( this.focusedKey == null ) ? "" : this.focusedKey, this.cookieOpts);
1313
+ $.cookie(this.cookieId + "-expand", ( this.expandedKeyList == null ) ? "" : this.expandedKeyList.join(","), this.cookieOpts);
1314
+ $.cookie(this.cookieId + "-select", ( this.selectedKeyList == null ) ? "" : this.selectedKeyList.join(","), this.cookieOpts);
1315
+ },
1316
+ addExpand: function(key) {
1317
+ this._log("addExpand(%o)", key);
1318
+ if( $.inArray(key, this.expandedKeyList) < 0 ) {
1319
+ this.expandedKeyList.push(key);
1320
+ $.cookie(this.cookieId + "-expand", this.expandedKeyList.join(","), this.cookieOpts);
1321
+ }
1322
+ },
1323
+ clearExpand: function(key) {
1324
+ this._log("clearExpand(%o)", key);
1325
+ var idx = $.inArray(key, this.expandedKeyList);
1326
+ if( idx >= 0 ) {
1327
+ this.expandedKeyList.splice(idx, 1);
1328
+ $.cookie(this.cookieId + "-expand", this.expandedKeyList.join(","), this.cookieOpts);
1329
+ }
1330
+ },
1331
+ addSelect: function(key) {
1332
+ this._log("addSelect(%o)", key);
1333
+ if( $.inArray(key, this.selectedKeyList) < 0 ) {
1334
+ this.selectedKeyList.push(key);
1335
+ $.cookie(this.cookieId + "-select", this.selectedKeyList.join(","), this.cookieOpts);
1336
+ }
1337
+ },
1338
+ clearSelect: function(key) {
1339
+ this._log("clearSelect(%o)", key);
1340
+ var idx = $.inArray(key, this.selectedKeyList);
1341
+ if( idx >= 0 ) {
1342
+ this.selectedKeyList.splice(idx, 1);
1343
+ $.cookie(this.cookieId + "-select", this.selectedKeyList.join(","), this.cookieOpts);
1344
+ }
1345
+ },
1346
+ isReloading: function() {
1347
+ return this.cookiesFound == true;
1348
+ },
1349
+ toDict: function() {
1350
+ return {
1351
+ cookiesFound: this.cookiesFound,
1352
+ activeKey: this.activeKey,
1353
+ focusedKey: this.activeKey,
1354
+ expandedKeyList: this.expandedKeyList,
1355
+ selectedKeyList: this.selectedKeyList
1356
+ };
1357
+ },
1358
+ // --- end of class
1359
+ lastentry: undefined
1360
+ };
1361
+
1362
+
1363
+ /*************************************************************************
1364
+ * class DynaTree
1365
+ */
1366
+
1367
+ var DynaTree = Class.create();
1368
+
1369
+ // --- Static members ----------------------------------------------------------
1370
+
1371
+ DynaTree.version = "$Version: 0.5.3$";
1372
+ /*
1373
+ DynaTree._initTree = function() {
1374
+ };
1375
+
1376
+ DynaTree._bind = function() {
1377
+ };
1378
+ */
1379
+ //--- Class members ------------------------------------------------------------
1380
+
1381
+ DynaTree.prototype = {
1382
+ // Constructor
1383
+ // initialize: function(divContainer, options) {
1384
+ initialize: function($widget) {
1385
+ // instance members
1386
+ this.phase = "init";
1387
+ this.$widget = $widget;
1388
+ this.options = $widget.options;
1389
+ this.$tree = $widget.element;
1390
+ // find container element
1391
+ this.divTree = this.$tree.get(0);
1392
+ },
1393
+
1394
+ // member functions
1395
+
1396
+ _load: function() {
1397
+ var $widget = this.$widget;
1398
+ var opts = this.options;
1399
+ this.bEnableUpdate = true;
1400
+ this._nodeCount = 1;
1401
+ this.activeNode = null;
1402
+ this.focusNode = null;
1403
+
1404
+ // If a 'options.classNames' dictionary was passed, still use defaults
1405
+ // for undefined classes:
1406
+ if( opts.classNames !== $.ui.dynatree.defaults.classNames ) {
1407
+ opts.classNames = $.extend({}, $.ui.dynatree.defaults.classNames, opts.classNames);
1408
+ }
1409
+ // Guess skin path, if not specified
1410
+ if(!opts.imagePath) {
1411
+ $("script").each( function () {
1412
+ // Eclipse syntax parser breaks on this expression, so put it at the bottom:
1413
+ if( this.src.search(_rexDtLibName) >= 0 ) {
1414
+ if( this.src.indexOf("/")>=0 ) // issue #47
1415
+ opts.imagePath = this.src.slice(0, this.src.lastIndexOf("/")) + "/skin/";
1416
+ else
1417
+ opts.imagePath = "skin/";
1418
+ // logMsg("Guessing imagePath from '%s': '%s'", this.src, opts.imagePath);
1419
+ return false; // first match
1420
+ }
1421
+ });
1422
+ }
1423
+
1424
+ this.persistence = new DynaTreeStatus(opts.cookieId, opts.cookie);
1425
+ if( opts.persist ) {
1426
+ if( !$.cookie )
1427
+ _log("warn", "Please include jquery.cookie.js to use persistence.");
1428
+ this.persistence.read();
1429
+ }
1430
+ this.logDebug("DynaTree.persistence: %o", this.persistence.toDict());
1431
+
1432
+ // Cached tag strings
1433
+ this.cache = {
1434
+ tagEmpty: "<span class='" + opts.classNames.empty + "'></span>",
1435
+ tagVline: "<span class='" + opts.classNames.vline + "'></span>",
1436
+ tagExpander: "<span class='" + opts.classNames.expander + "'></span>",
1437
+ tagConnector: "<span class='" + opts.classNames.connector + "'></span>",
1438
+ tagNodeIcon: "<span class='" + opts.classNames.nodeIcon + "'></span>",
1439
+ tagCheckbox: "<span class='" + opts.classNames.checkbox + "'></span>",
1440
+ lastentry: undefined
1441
+ };
1442
+
1443
+ // Clear container, in case it contained some 'waiting' or 'error' text
1444
+ // for clients that don't support JS.
1445
+ // We don't do this however, if we try to load from an embedded UL element.
1446
+ if( opts.children || (opts.initAjax && opts.initAjax.url) || opts.initId )
1447
+ $(this.divTree).empty();
1448
+ else if( this.divRoot )
1449
+ $(this.divRoot).remove();
1450
+
1451
+ // create the root element
1452
+ this.tnRoot = new DynaTreeNode(null, this, {title: opts.title, key: "root"});
1453
+ this.tnRoot.data.isFolder = true;
1454
+ this.tnRoot.render(false, false);
1455
+ this.divRoot = this.tnRoot.div;
1456
+ this.divRoot.className = opts.classNames.container;
1457
+ // add root to container
1458
+ // TODO: this should be delayed until all children have been created for performance reasons
1459
+ this.divTree.appendChild(this.divRoot);
1460
+
1461
+ var root = this.tnRoot;
1462
+ var isReloading = ( opts.persist && this.persistence.isReloading() );
1463
+ var isLazy = false;
1464
+ var prevFlag = this.enableUpdate(false);
1465
+
1466
+ this.logDebug("Dynatree._load(): read tree structure...");
1467
+
1468
+ // Init tree structure
1469
+ if( opts.children ) {
1470
+ // Read structure from node array
1471
+ root.addChild(opts.children);
1472
+
1473
+ } else if( opts.initAjax && opts.initAjax.url ) {
1474
+ // Init tree from AJAX request
1475
+ isLazy = true;
1476
+ root.data.isLazy = true;
1477
+ this._reloadAjax();
1478
+
1479
+ } else if( opts.initId ) {
1480
+ // Init tree from another UL element
1481
+ this._createFromTag(root, $("#"+opts.initId));
1482
+
1483
+ } else {
1484
+ // Init tree from the first UL element inside the container <div>
1485
+ var $ul = this.$tree.find(">ul").hide();
1486
+ this._createFromTag(root, $ul);
1487
+ $ul.remove();
1488
+ }
1489
+
1490
+ this._checkConsistency();
1491
+ // Render html markup
1492
+ this.logDebug("Dynatree._load(): render nodes...");
1493
+ this.enableUpdate(prevFlag);
1494
+
1495
+ // bind event handlers
1496
+ this.logDebug("Dynatree._load(): bind events...");
1497
+ this.$widget.bind();
1498
+
1499
+ // --- Post-load processing
1500
+ this.logDebug("Dynatree._load(): postInit...");
1501
+ this.phase = "postInit";
1502
+
1503
+ // In persist mode, make sure that cookies are written, even if they are empty
1504
+ if( opts.persist ) {
1505
+ this.persistence.write();
1506
+ }
1507
+
1508
+ // Set focus, if possible (this will also fire an event and write a cookie)
1509
+ if( this.focusNode && this.focusNode.isVisible() ) {
1510
+ this.logDebug("Focus on init: %o", this.focusNode);
1511
+ this.focusNode.focus();
1512
+ }
1513
+
1514
+ if( !isLazy && opts.onPostInit ) {
1515
+ opts.onPostInit.call(this, isReloading, false);
1516
+ }
1517
+
1518
+ this.phase = "idle";
1519
+ },
1520
+
1521
+ _reloadAjax: function() {
1522
+ // Reload
1523
+ var opts = this.options;
1524
+ if( ! opts.initAjax || ! opts.initAjax.url )
1525
+ throw "tree.reload() requires 'initAjax' mode.";
1526
+ var pers = this.persistence;
1527
+ var ajaxOpts = $.extend({}, opts.initAjax);
1528
+ // Append cookie info to the request
1529
+ // this.logDebug("reloadAjax: key=%o, an.key:%o", pers.activeKey, this.activeNode?this.activeNode.data.key:"?");
1530
+ if( ajaxOpts.addActiveKey )
1531
+ ajaxOpts.data.activeKey = pers.activeKey;
1532
+ if( ajaxOpts.addFocusedKey )
1533
+ ajaxOpts.data.focusedKey = pers.focusedKey;
1534
+ if( ajaxOpts.addExpandedKeyList )
1535
+ ajaxOpts.data.expandedKeyList = pers.expandedKeyList.join(",");
1536
+ if( ajaxOpts.addSelectedKeyList )
1537
+ ajaxOpts.data.selectedKeyList = pers.selectedKeyList.join(",");
1538
+
1539
+ // Set up onPostInit callback to be called when Ajax returns
1540
+ if( opts.onPostInit ) {
1541
+ if( ajaxOpts.success )
1542
+ this.tree.logWarning("initAjax: success callback is ignored when onPostInit was specified.");
1543
+ if( ajaxOpts.error )
1544
+ this.tree.logWarning("initAjax: error callback is ignored when onPostInit was specified.");
1545
+ var isReloading = pers.isReloading();
1546
+ ajaxOpts["success"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, false); };
1547
+ ajaxOpts["error"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, true); };
1548
+ }
1549
+ this.logDebug("Dynatree._init(): send Ajax request...");
1550
+ this.tnRoot.appendAjax(ajaxOpts);
1551
+ },
1552
+
1553
+ toString: function() {
1554
+ return "DynaTree '" + this.options.title + "'";
1555
+ },
1556
+
1557
+ toDict: function() {
1558
+ return this.tnRoot.toDict(true);
1559
+ },
1560
+
1561
+ getPersistData: function() {
1562
+ return this.persistence.toDict();
1563
+ },
1564
+
1565
+ logDebug: function(msg) {
1566
+ if( this.options.debugLevel >= 2 ) {
1567
+ Array.prototype.unshift.apply(arguments, ["debug"]);
1568
+ _log.apply(this, arguments);
1569
+ }
1570
+ },
1571
+
1572
+ logInfo: function(msg) {
1573
+ if( this.options.debugLevel >= 1 ) {
1574
+ Array.prototype.unshift.apply(arguments, ["info"]);
1575
+ _log.apply(this, arguments);
1576
+ }
1577
+ },
1578
+
1579
+ logWarning: function(msg) {
1580
+ Array.prototype.unshift.apply(arguments, ["warn"]);
1581
+ _log.apply(this, arguments);
1582
+ },
1583
+
1584
+ isInitializing: function() {
1585
+ return ( this.phase=="init" || this.phase=="postInit" );
1586
+ },
1587
+ isReloading: function() {
1588
+ return ( this.phase=="init" || this.phase=="postInit" ) && this.options.persist && this.persistence.cookiesFound;
1589
+ },
1590
+ isUserEvent: function() {
1591
+ return ( this.phase=="userEvent" );
1592
+ },
1593
+
1594
+ redraw: function() {
1595
+ this.logDebug("dynatree.redraw()...");
1596
+ this.tnRoot.render(true, true);
1597
+ this.logDebug("dynatree.redraw() done.");
1598
+ },
1599
+
1600
+ reloadAjax: function() {
1601
+ this.logWarning("tree.reloadAjax() is deprecated since v0.5.2 (use reload() instead).");
1602
+ },
1603
+
1604
+ reload: function() {
1605
+ this._load();
1606
+ },
1607
+
1608
+ getRoot: function() {
1609
+ return this.tnRoot;
1610
+ },
1611
+
1612
+ getNodeByKey: function(key) {
1613
+ // $("#...") has problems, if the key contains '.', so we use getElementById()
1614
+ // return $("#" + this.options.idPrefix + key).attr("dtnode");
1615
+ var el = document.getElementById(this.options.idPrefix + key);
1616
+ return ( el && el.dtnode ) ? el.dtnode : null;
1617
+ },
1618
+
1619
+ getActiveNode: function() {
1620
+ return this.activeNode;
1621
+ },
1622
+
1623
+ reactivate: function(setFocus) {
1624
+ // Re-fire onQueryActivate and onActivate events.
1625
+ var node = this.activeNode;
1626
+ // this.logDebug("reactivate %o", node);
1627
+ if( node ) {
1628
+ this.activeNode = null; // Force re-activating
1629
+ node.activate();
1630
+ if( setFocus )
1631
+ node.focus();
1632
+ }
1633
+ },
1634
+
1635
+ getSelectedNodes: function(stopOnParents) {
1636
+ var nodeList = [];
1637
+ this.tnRoot.visit(function(dtnode){
1638
+ if( dtnode.bSelected ) {
1639
+ nodeList.push(dtnode);
1640
+ if( stopOnParents == true )
1641
+ return false; // stop processing this branch
1642
+ }
1643
+ });
1644
+ return nodeList;
1645
+ },
1646
+
1647
+ activateKey: function(key) {
1648
+ var dtnode = (key === null) ? null : this.getNodeByKey(key);
1649
+ if( !dtnode ) {
1650
+ if( this.activeNode )
1651
+ this.activeNode.deactivate();
1652
+ this.activeNode = null;
1653
+ return null;
1654
+ }
1655
+ dtnode.focus();
1656
+ dtnode.activate();
1657
+ return dtnode;
1658
+ },
1659
+
1660
+ selectKey: function(key, select) {
1661
+ var dtnode = this.getNodeByKey(key);
1662
+ if( !dtnode )
1663
+ return null;
1664
+ dtnode.select(select);
1665
+ return dtnode;
1666
+ },
1667
+
1668
+ enableUpdate: function(bEnable) {
1669
+ if ( this.bEnableUpdate==bEnable )
1670
+ return bEnable;
1671
+ this.bEnableUpdate = bEnable;
1672
+ if ( bEnable )
1673
+ this.redraw();
1674
+ return !bEnable; // return previous value
1675
+ },
1676
+
1677
+ visit: function(fn, data, includeRoot) {
1678
+ return this.tnRoot.visit(fn, data, includeRoot);
1679
+ },
1680
+
1681
+ _createFromTag: function(parentTreeNode, $ulParent) {
1682
+ // Convert a <UL>...</UL> list into children of the parent tree node.
1683
+ var self = this;
1684
+ /*
1685
+ TODO: better?
1686
+ this.$lis = $("li:has(a[href])", this.element);
1687
+ this.$tabs = this.$lis.map(function() { return $("a", this)[0]; });
1688
+ */
1689
+ $ulParent.find(">li").each(function() {
1690
+ var $li = $(this);
1691
+ var $liSpan = $li.find(">span:first");
1692
+ var title;
1693
+ if( $liSpan.length ) {
1694
+ // If a <li><span> tag is specified, use it literally.
1695
+ title = $liSpan.html();
1696
+ } else {
1697
+ // If only a <li> tag is specified, use the trimmed string up to the next child <ul> tag.
1698
+ title = $li.html();
1699
+ var iPos = title.search(/<ul/i);
1700
+ if( iPos>=0 )
1701
+ title = $.trim(title.substring(0, iPos));
1702
+ else
1703
+ title = $.trim(title);
1704
+ // self.logDebug("%o", title);
1705
+ }
1706
+ // Parse node options from ID, title and class attributes
1707
+ var data = {
1708
+ title: title,
1709
+ isFolder: $li.hasClass("folder"),
1710
+ isLazy: $li.hasClass("lazy"),
1711
+ expand: $li.hasClass("expanded"),
1712
+ select: $li.hasClass("selected"),
1713
+ activate: $li.hasClass("active"),
1714
+ focus: $li.hasClass("focused")
1715
+ };
1716
+ if( $li.attr("title") )
1717
+ data.tooltip = $li.attr("title");
1718
+ if( $li.attr("id") )
1719
+ data.key = $li.attr("id");
1720
+ // If a data attribute is present, evaluate as a JavaScript object
1721
+ if( $li.attr("data") ) {
1722
+ var dataAttr = $.trim($li.attr("data"));
1723
+ if( dataAttr ) {
1724
+ if( dataAttr.charAt(0) != "{" )
1725
+ dataAttr = "{" + dataAttr + "}"
1726
+ try {
1727
+ $.extend(data, eval("(" + dataAttr + ")"));
1728
+ } catch(e) {
1729
+ throw ("Error parsing node data: " + e + "\ndata:\n'" + dataAttr + "'");
1730
+ }
1731
+ }
1732
+ }
1733
+ childNode = parentTreeNode.addChild(data);
1734
+ // Recursive reading of child nodes, if LI tag contains an UL tag
1735
+ var $ul = $li.find(">ul:first");
1736
+ if( $ul.length ) {
1737
+ self._createFromTag(childNode, $ul); // must use 'self', because 'this' is the each() context
1738
+ }
1739
+ });
1740
+ },
1741
+
1742
+ _checkConsistency: function() {
1743
+ // this.logDebug("tree._checkConsistency() NOT IMPLEMENTED - %o", this);
1744
+ },
1745
+
1746
+ // --- end of class
1747
+ lastentry: undefined
1748
+ };
1749
+
1750
+ /*************************************************************************
1751
+ * widget $(..).dynatree
1752
+ */
1753
+
1754
+ $.widget("ui.dynatree", {
1755
+ init: function() {
1756
+ // 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.");
1758
+ return this._init();
1759
+ },
1760
+
1761
+ _init: function() {
1762
+ if( parseFloat($.ui.version) < 1.8 ) {
1763
+ // jquery.ui.core 1.8 renamed _init() to _create(): this stub assures backward compatibility
1764
+ _log("warn", "ui.dynatree._init() was called; you should upgrade to jquery.ui.core.js v1.8 or higher.");
1765
+ return this._create();
1766
+ }
1767
+ // jquery.ui.core 1.8 still uses _init() to perform "default functionality"
1768
+ _log("debug", "ui.dynatree._init() was called; no current default functionality.");
1769
+ },
1770
+
1771
+ _create: function() {
1772
+ if( parseFloat($.ui.version) >= 1.8 ) {
1773
+ this.options = $.extend(true, $[this.namespace][this.widgetName].defaults, this.options);
1774
+ }
1775
+ logMsg("Dynatree._create(): version='%s', debugLevel=%o.", DynaTree.version, this.options.debugLevel);
1776
+ var opts = this.options;
1777
+ // The widget framework supplies this.element and this.options.
1778
+ this.options.event += ".dynatree"; // namespace event
1779
+
1780
+ var divTree = this.element.get(0);
1781
+ /* // Clear container, in case it contained some 'waiting' or 'error' text
1782
+ // for clients that don't support JS
1783
+ if( opts.children || (opts.initAjax && opts.initAjax.url) || opts.initId )
1784
+ $(divTree).empty();
1785
+ */
1786
+ // Create the DynaTree object
1787
+ this.tree = new DynaTree(this);
1788
+ this.tree._load();
1789
+ this.tree.logDebug("Dynatree._create(): done.");
1790
+ },
1791
+
1792
+ bind: function() {
1793
+ var $this = this.element;
1794
+ var o = this.options;
1795
+
1796
+ // Prevent duplicate binding
1797
+ this.unbind();
1798
+
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
+ var eventNames = "click.dynatree dblclick.dynatree";
1810
+ if( o.keyboard ) // Note: leading ' '!
1811
+ eventNames += " keypress.dynatree keydown.dynatree";
1812
+ $this.bind(eventNames, function(event){
1813
+ var dtnode = __getNodeFromElement(event.target);
1814
+ if( !dtnode )
1815
+ return true; // Allow bubbling of other events
1816
+ var prevPhase = dtnode.tree.phase;
1817
+ dtnode.tree.phase = "userEvent";
1818
+ try {
1819
+ dtnode.tree.logDebug("bind(%o): dtnode: %o", event, dtnode);
1820
+
1821
+ switch(event.type) {
1822
+ case "click":
1823
+ return ( o.onClick && o.onClick(dtnode, event)===false ) ? false : dtnode.onClick(event);
1824
+ case "dblclick":
1825
+ return ( o.onDblClick && o.onDblClick(dtnode, event)===false ) ? false : dtnode.onDblClick(event);
1826
+ case "keydown":
1827
+ return ( o.onKeydown && o.onKeydown(dtnode, event)===false ) ? false : dtnode.onKeydown(event);
1828
+ case "keypress":
1829
+ return ( o.onKeypress && o.onKeypress(dtnode, event)===false ) ? false : dtnode.onKeypress(event);
1830
+ };
1831
+ } catch(e) {
1832
+ var _ = null; // issue 117
1833
+ // dtnode.tree.logError("bind(%o): dtnode: %o", event, dtnode);
1834
+ } finally {
1835
+ dtnode.tree.phase = prevPhase;
1836
+ }
1837
+ });
1838
+
1839
+ // focus/blur don't bubble, i.e. are not delegated to parent <div> tags,
1840
+ // so we use the addEventListener capturing phase.
1841
+ // See http://www.howtocreate.co.uk/tutorials/javascript/domevents
1842
+ function __focusHandler(event) {
1843
+ // Handles blur and focus.
1844
+ // Fix event for IE:
1845
+ event = arguments[0] = $.event.fix( event || window.event );
1846
+ var dtnode = __getNodeFromElement(event.target);
1847
+ return dtnode ? dtnode.onFocus(event) : false;
1848
+ }
1849
+ var div = this.tree.divTree;
1850
+ if( div.addEventListener ) {
1851
+ div.addEventListener("focus", __focusHandler, true);
1852
+ div.addEventListener("blur", __focusHandler, true);
1853
+ } else {
1854
+ div.onfocusin = div.onfocusout = __focusHandler;
1855
+ }
1856
+ // EVENTS
1857
+ // disable click if event is configured to something else
1858
+ // if (!(/^click/).test(o.event))
1859
+ // this.$tabs.bind("click.tabs", function() { return false; });
1860
+
1861
+ },
1862
+
1863
+ unbind: function() {
1864
+ this.element.unbind(".dynatree");
1865
+ },
1866
+
1867
+ /* TODO: we could handle option changes during runtime here (maybe to re-render, ...)
1868
+ setData: function(key, value) {
1869
+ this.tree.logDebug("dynatree.setData('" + key + "', '" + value + "')");
1870
+ },
1871
+ */
1872
+ enable: function() {
1873
+ this.bind();
1874
+ // Call default disable(): remove -disabled from css:
1875
+ $.widget.prototype.enable.apply(this, arguments);
1876
+ },
1877
+
1878
+ disable: function() {
1879
+ this.unbind();
1880
+ // Call default disable(): add -disabled to css:
1881
+ $.widget.prototype.disable.apply(this, arguments);
1882
+ },
1883
+
1884
+ // --- getter methods (i.e. NOT returning a reference to $)
1885
+ getTree: function() {
1886
+ return this.tree;
1887
+ },
1888
+
1889
+ getRoot: function() {
1890
+ return this.tree.getRoot();
1891
+ },
1892
+
1893
+ getActiveNode: function() {
1894
+ return this.tree.getActiveNode();
1895
+ },
1896
+
1897
+ getSelectedNodes: function() {
1898
+ return this.tree.getSelectedNodes();
1899
+ },
1900
+
1901
+ // ------------------------------------------------------------------------
1902
+ lastentry: undefined
1903
+ });
1904
+
1905
+
1906
+ // The following methods return a value (thus breaking the jQuery call chain):
1907
+
1908
+ $.ui.dynatree.getter = "getTree getRoot getActiveNode getSelectedNodes";
1909
+
1910
+
1911
+ // Plugin default options:
1912
+
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.
1916
+ minExpandLevel: 1, // 1: root node is not collapsible
1917
+ imagePath: null, // Path to a folder containing icons. Defaults to 'skin/' subdirectory.
1918
+ children: null, // Init tree structure from this object array.
1919
+ initId: null, // Init tree structure from a <ul> element with this ID.
1920
+ initAjax: null, // Ajax options used to initialize the tree strucuture.
1921
+ autoFocus: true, // Set focus to first child, when expanding or lazy-loading.
1922
+ keyboard: true, // Support keyboard navigation.
1923
+ persist: false, // Persist expand-status to a cookie
1924
+ autoCollapse: false, // Automatically collapse all siblings, when a node is expanded.
1925
+ clickFolderMode: 3, // 1:activate, 2:expand, 3:activate and expand
1926
+ activeVisible: true, // Make sure, active nodes are visible (expanded).
1927
+ checkbox: false, // Show checkboxes.
1928
+ selectMode: 2, // 1:single, 2:multi, 3:multi-hier
1929
+ fx: null, // Animations, e.g. null or { height: "toggle", duration: 200 }
1930
+
1931
+ // Low level event handlers: onEvent(dtnode, event): return false, to stop default processing
1932
+ onClick: null, // null: generate focus, expand, activate, select events.
1933
+ onDblClick: null, // (No default actions.)
1934
+ onKeydown: null, // null: generate keyboard navigation (focus, expand, activate).
1935
+ onKeypress: null, // (No default actions.)
1936
+ onFocus: null, // null: set focus to node.
1937
+ onBlur: null, // null: remove focus from node.
1938
+
1939
+ // Pre-event handlers onQueryEvent(flag, dtnode): return false, to stop processing
1940
+ onQueryActivate: null, // Callback(flag, dtnode) before a node is (de)activated.
1941
+ onQuerySelect: null, // Callback(flag, dtnode) before a node is (de)selected.
1942
+ onQueryExpand: null, // Callback(flag, dtnode) before a node is expanded/collpsed.
1943
+
1944
+ // High level event handlers
1945
+ onPostInit: null, // Callback(isReloading, isError) when tree was (re)loaded.
1946
+ onActivate: null, // Callback(dtnode) when a node is activated.
1947
+ onDeactivate: null, // Callback(dtnode) when a node is deactivated.
1948
+ onSelect: null, // Callback(flag, dtnode) when a node is (de)selected.
1949
+ onExpand: null, // Callback(dtnode) when a node is expanded/collapsed.
1950
+ onLazyRead: null, // Callback(dtnode) when a lazy node is expanded for the first time.
1951
+
1952
+ ajaxDefaults: { // Used by initAjax option
1953
+ cache: false, // false: Append random '_' argument to the request url to prevent caching.
1954
+ dataType: "json" // Expect json format and pass json object to callbacks.
1955
+ },
1956
+ strings: {
1957
+ loading: "Loading&#8230;",
1958
+ loadError: "Load error!"
1959
+ },
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.
1962
+ cookieId: "dynatree", // Choose a more unique name, to allow multiple trees.
1963
+ cookie: {
1964
+ expires: null //7, // Days or Date; null: session cookie
1965
+ // path: "/", // Defaults to current page
1966
+ // domain: "jquery.com",
1967
+ // secure: true
1968
+ },
1969
+ // Class names used, when rendering the HTML markup.
1970
+ // Note: if only single entries are passed for options.classNames, all other
1971
+ // values are still set to default.
1972
+ classNames: {
1973
+ container: "ui-dynatree-container",
1974
+ folder: "ui-dynatree-folder",
1975
+ document: "ui-dynatree-document",
1976
+
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",
1984
+
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,
2001
+
2002
+ // ------------------------------------------------------------------------
2003
+ lastentry: undefined
2004
+ };
2005
+
2006
+ /**
2007
+ * Reserved data attributes for a tree node.
2008
+ */
2009
+ $.ui.dynatree.nodedatadefaults = {
2010
+ title: null, // (required) Displayed name of the node (html is allowed here)
2011
+ key: null, // May be used with activate(), select(), find(), ...
2012
+ isFolder: false, // Use a folder icon. Also the node is expandable but not selectable.
2013
+ isLazy: false, // Call onLazyRead(), when the node is expanded for the first time to allow for delayed creation of children.
2014
+ tooltip: null, // Show this popup text.
2015
+ icon: null, // Use a custom image (filename relative to tree.options.imagePath). 'null' for default icon, 'false' for no icon.
2016
+ addClass: null, // Class name added to the node's span tag.
2017
+ activate: false, // Initial active status.
2018
+ focus: false, // Initial focused status.
2019
+ expand: false, // Initial expanded status.
2020
+ select: false, // Initial selected status.
2021
+ hideCheckbox: false, // Suppress checkbox display for this node.
2022
+ unselectable: false, // Prevent selection.
2023
+ // disabled: false,
2024
+ // The following attributes are only valid if passed to some functions:
2025
+ children: null, // Array of child nodes.
2026
+ // NOTE: we can also add custom attributes here.
2027
+ // This may then also be used in the onActivate(), onSelect() or onLazyTree() callbacks.
2028
+ // ------------------------------------------------------------------------
2029
+ lastentry: undefined
2030
+ };
2031
+
2032
+ // ---------------------------------------------------------------------------
2033
+ })(jQuery);
2034
+
2035
+ // Eclipse syntax parser breaks on this expression, so we put it at the bottom.
2036
+ var _rexDtLibName = /.*dynatree[^/]*\.js$/i;