yui-rails-asset 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (398) hide show
  1. data/LICENSE +21 -0
  2. data/README +17 -0
  3. data/lib/yui/rails.rb +29 -0
  4. data/lib/yui/rails/engine.rb +10 -0
  5. data/lib/yui/rails/version.rb +6 -0
  6. data/vendor/assets/javascripts/yui-2.8.1/build/animation/animation-debug.js +1396 -0
  7. data/vendor/assets/javascripts/yui-2.8.1/build/animation/animation-min.js +23 -0
  8. data/vendor/assets/javascripts/yui-2.8.1/build/animation/animation.js +1392 -0
  9. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/ajax-loader.gif +0 -0
  10. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/asc.gif +0 -0
  11. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/autocomplete.css +7 -0
  12. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/back-h.png +0 -0
  13. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/back-v.png +0 -0
  14. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/bar-h.png +0 -0
  15. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/bar-v.png +0 -0
  16. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/bg-h.gif +0 -0
  17. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/bg-v.gif +0 -0
  18. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/blankimage.png +0 -0
  19. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/button.css +7 -0
  20. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/calendar.css +8 -0
  21. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/carousel.css +7 -0
  22. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/check0.gif +0 -0
  23. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/check1.gif +0 -0
  24. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/check2.gif +0 -0
  25. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/colorpicker.css +7 -0
  26. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/container.css +7 -0
  27. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/datatable.css +8 -0
  28. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/desc.gif +0 -0
  29. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/dt-arrow-dn.png +0 -0
  30. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/dt-arrow-up.png +0 -0
  31. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/editor-knob.gif +0 -0
  32. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/editor-sprite-active.gif +0 -0
  33. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/editor-sprite.gif +0 -0
  34. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/editor.css +10 -0
  35. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/header_background.png +0 -0
  36. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/hue_bg.png +0 -0
  37. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/imagecropper.css +7 -0
  38. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/layout.css +7 -0
  39. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/layout_sprite.png +0 -0
  40. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/loading.gif +0 -0
  41. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/logger.css +7 -0
  42. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/menu-button-arrow-disabled.png +0 -0
  43. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/menu-button-arrow.png +0 -0
  44. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/menu.css +7 -0
  45. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/menubaritem_submenuindicator.png +0 -0
  46. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/menubaritem_submenuindicator_disabled.png +0 -0
  47. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/menuitem_checkbox.png +0 -0
  48. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/menuitem_checkbox_disabled.png +0 -0
  49. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/menuitem_submenuindicator.png +0 -0
  50. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/menuitem_submenuindicator_disabled.png +0 -0
  51. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/paginator.css +7 -0
  52. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/picker_mask.png +0 -0
  53. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/profilerviewer.css +7 -0
  54. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/progressbar.css +7 -0
  55. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/resize.css +7 -0
  56. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/simpleeditor.css +10 -0
  57. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/skin.css +36 -0
  58. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/slider.css +7 -0
  59. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/split-button-arrow-active.png +0 -0
  60. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/split-button-arrow-disabled.png +0 -0
  61. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/split-button-arrow-focus.png +0 -0
  62. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/split-button-arrow-hover.png +0 -0
  63. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/split-button-arrow.png +0 -0
  64. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/sprite.png +0 -0
  65. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/sprite.psd +0 -0
  66. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/tabview.css +8 -0
  67. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/treeview-loading.gif +0 -0
  68. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/treeview-sprite.gif +0 -0
  69. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/treeview.css +7 -0
  70. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/wait.gif +0 -0
  71. data/vendor/assets/javascripts/yui-2.8.1/build/assets/skins/sam/yuitest.css +7 -0
  72. data/vendor/assets/javascripts/yui-2.8.1/build/autocomplete/assets/autocomplete-core.css +7 -0
  73. data/vendor/assets/javascripts/yui-2.8.1/build/autocomplete/assets/skins/sam/autocomplete-skin.css +57 -0
  74. data/vendor/assets/javascripts/yui-2.8.1/build/autocomplete/assets/skins/sam/autocomplete.css +7 -0
  75. data/vendor/assets/javascripts/yui-2.8.1/build/autocomplete/autocomplete-debug.js +3009 -0
  76. data/vendor/assets/javascripts/yui-2.8.1/build/autocomplete/autocomplete-min.js +12 -0
  77. data/vendor/assets/javascripts/yui-2.8.1/build/autocomplete/autocomplete.js +2966 -0
  78. data/vendor/assets/javascripts/yui-2.8.1/build/base/base-min.css +7 -0
  79. data/vendor/assets/javascripts/yui-2.8.1/build/base/base.css +131 -0
  80. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/button-core.css +44 -0
  81. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/skins/sam/button-skin.css +219 -0
  82. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/skins/sam/button.css +7 -0
  83. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/skins/sam/menu-button-arrow-disabled.png +0 -0
  84. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/skins/sam/menu-button-arrow.png +0 -0
  85. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/skins/sam/split-button-arrow-active.png +0 -0
  86. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/skins/sam/split-button-arrow-disabled.png +0 -0
  87. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/skins/sam/split-button-arrow-focus.png +0 -0
  88. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/skins/sam/split-button-arrow-hover.png +0 -0
  89. data/vendor/assets/javascripts/yui-2.8.1/build/button/assets/skins/sam/split-button-arrow.png +0 -0
  90. data/vendor/assets/javascripts/yui-2.8.1/build/button/button-debug.js +4694 -0
  91. data/vendor/assets/javascripts/yui-2.8.1/build/button/button-min.js +11 -0
  92. data/vendor/assets/javascripts/yui-2.8.1/build/button/button.js +4633 -0
  93. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/assets/calendar-core.css +132 -0
  94. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/assets/calendar.css +320 -0
  95. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/assets/calgrad.png +0 -0
  96. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/assets/callt.gif +0 -0
  97. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/assets/calrt.gif +0 -0
  98. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/assets/calx.gif +0 -0
  99. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/assets/skins/sam/calendar-skin.css +361 -0
  100. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/assets/skins/sam/calendar.css +8 -0
  101. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/calendar-debug.js +7324 -0
  102. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/calendar-min.js +18 -0
  103. data/vendor/assets/javascripts/yui-2.8.1/build/calendar/calendar.js +7294 -0
  104. data/vendor/assets/javascripts/yui-2.8.1/build/carousel/assets/ajax-loader.gif +0 -0
  105. data/vendor/assets/javascripts/yui-2.8.1/build/carousel/assets/carousel-core.css +88 -0
  106. data/vendor/assets/javascripts/yui-2.8.1/build/carousel/assets/skins/sam/ajax-loader.gif +0 -0
  107. data/vendor/assets/javascripts/yui-2.8.1/build/carousel/assets/skins/sam/carousel-skin.css +142 -0
  108. data/vendor/assets/javascripts/yui-2.8.1/build/carousel/assets/skins/sam/carousel.css +7 -0
  109. data/vendor/assets/javascripts/yui-2.8.1/build/carousel/carousel-debug.js +4390 -0
  110. data/vendor/assets/javascripts/yui-2.8.1/build/carousel/carousel-min.js +12 -0
  111. data/vendor/assets/javascripts/yui-2.8.1/build/carousel/carousel.js +4349 -0
  112. data/vendor/assets/javascripts/yui-2.8.1/build/charts/assets/charts.swf +0 -0
  113. data/vendor/assets/javascripts/yui-2.8.1/build/charts/charts-debug.js +2061 -0
  114. data/vendor/assets/javascripts/yui-2.8.1/build/charts/charts-min.js +9 -0
  115. data/vendor/assets/javascripts/yui-2.8.1/build/charts/charts.js +2060 -0
  116. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/assets/colorpicker-core.css +6 -0
  117. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/assets/hue_thumb.png +0 -0
  118. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/assets/picker_mask.png +0 -0
  119. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/assets/picker_thumb.png +0 -0
  120. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/assets/skins/sam/colorpicker-skin.css +105 -0
  121. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/assets/skins/sam/colorpicker.css +7 -0
  122. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/assets/skins/sam/hue_bg.png +0 -0
  123. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/assets/skins/sam/picker_mask.png +0 -0
  124. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/colorpicker-debug.js +1783 -0
  125. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/colorpicker-min.js +9 -0
  126. data/vendor/assets/javascripts/yui-2.8.1/build/colorpicker/colorpicker.js +1763 -0
  127. data/vendor/assets/javascripts/yui-2.8.1/build/connection/connection-debug.js +1576 -0
  128. data/vendor/assets/javascripts/yui-2.8.1/build/connection/connection-min.js +9 -0
  129. data/vendor/assets/javascripts/yui-2.8.1/build/connection/connection.js +1546 -0
  130. data/vendor/assets/javascripts/yui-2.8.1/build/connection/connection.swf +0 -0
  131. data/vendor/assets/javascripts/yui-2.8.1/build/connection/connection_core-debug.js +980 -0
  132. data/vendor/assets/javascripts/yui-2.8.1/build/connection/connection_core-min.js +8 -0
  133. data/vendor/assets/javascripts/yui-2.8.1/build/connection/connection_core.js +957 -0
  134. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/alrt16_1.gif +0 -0
  135. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/blck16_1.gif +0 -0
  136. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/close12_1.gif +0 -0
  137. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/container-core.css +176 -0
  138. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/container.css +324 -0
  139. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/hlp16_1.gif +0 -0
  140. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/info16_1.gif +0 -0
  141. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/skins/sam/container-skin.css +242 -0
  142. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/skins/sam/container.css +7 -0
  143. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/tip16_1.gif +0 -0
  144. data/vendor/assets/javascripts/yui-2.8.1/build/container/assets/warn16_1.gif +0 -0
  145. data/vendor/assets/javascripts/yui-2.8.1/build/container/container-debug.js +9076 -0
  146. data/vendor/assets/javascripts/yui-2.8.1/build/container/container-min.js +19 -0
  147. data/vendor/assets/javascripts/yui-2.8.1/build/container/container.js +9052 -0
  148. data/vendor/assets/javascripts/yui-2.8.1/build/container/container_core-debug.js +5136 -0
  149. data/vendor/assets/javascripts/yui-2.8.1/build/container/container_core-min.js +14 -0
  150. data/vendor/assets/javascripts/yui-2.8.1/build/container/container_core.js +5126 -0
  151. data/vendor/assets/javascripts/yui-2.8.1/build/cookie/cookie-debug.js +482 -0
  152. data/vendor/assets/javascripts/yui-2.8.1/build/cookie/cookie-min.js +7 -0
  153. data/vendor/assets/javascripts/yui-2.8.1/build/cookie/cookie.js +482 -0
  154. data/vendor/assets/javascripts/yui-2.8.1/build/datasource/datasource-debug.js +3067 -0
  155. data/vendor/assets/javascripts/yui-2.8.1/build/datasource/datasource-min.js +12 -0
  156. data/vendor/assets/javascripts/yui-2.8.1/build/datasource/datasource.js +2996 -0
  157. data/vendor/assets/javascripts/yui-2.8.1/build/datatable/assets/datatable-core.css +93 -0
  158. data/vendor/assets/javascripts/yui-2.8.1/build/datatable/assets/datatable.css +49 -0
  159. data/vendor/assets/javascripts/yui-2.8.1/build/datatable/assets/skins/sam/datatable-skin.css +240 -0
  160. data/vendor/assets/javascripts/yui-2.8.1/build/datatable/assets/skins/sam/datatable.css +8 -0
  161. data/vendor/assets/javascripts/yui-2.8.1/build/datatable/assets/skins/sam/dt-arrow-dn.png +0 -0
  162. data/vendor/assets/javascripts/yui-2.8.1/build/datatable/assets/skins/sam/dt-arrow-up.png +0 -0
  163. data/vendor/assets/javascripts/yui-2.8.1/build/datatable/datatable-debug.js +17360 -0
  164. data/vendor/assets/javascripts/yui-2.8.1/build/datatable/datatable-min.js +29 -0
  165. data/vendor/assets/javascripts/yui-2.8.1/build/datatable/datatable.js +17122 -0
  166. data/vendor/assets/javascripts/yui-2.8.1/build/datemath/datemath-debug.js +408 -0
  167. data/vendor/assets/javascripts/yui-2.8.1/build/datemath/datemath-min.js +7 -0
  168. data/vendor/assets/javascripts/yui-2.8.1/build/datemath/datemath.js +408 -0
  169. data/vendor/assets/javascripts/yui-2.8.1/build/dom/dom-debug.js +1872 -0
  170. data/vendor/assets/javascripts/yui-2.8.1/build/dom/dom-min.js +9 -0
  171. data/vendor/assets/javascripts/yui-2.8.1/build/dom/dom.js +1832 -0
  172. data/vendor/assets/javascripts/yui-2.8.1/build/dragdrop/dragdrop-debug.js +3710 -0
  173. data/vendor/assets/javascripts/yui-2.8.1/build/dragdrop/dragdrop-min.js +10 -0
  174. data/vendor/assets/javascripts/yui-2.8.1/build/dragdrop/dragdrop.js +3601 -0
  175. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/editor-core.css +602 -0
  176. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/simpleeditor-core.css +602 -0
  177. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/skins/sam/blankimage.png +0 -0
  178. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/skins/sam/editor-knob.gif +0 -0
  179. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/skins/sam/editor-skin.css +711 -0
  180. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/skins/sam/editor-sprite-active.gif +0 -0
  181. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/skins/sam/editor-sprite.gif +0 -0
  182. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/skins/sam/editor.css +10 -0
  183. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/skins/sam/simpleeditor-skin.css +711 -0
  184. data/vendor/assets/javascripts/yui-2.8.1/build/editor/assets/skins/sam/simpleeditor.css +10 -0
  185. data/vendor/assets/javascripts/yui-2.8.1/build/editor/editor-debug.js +9557 -0
  186. data/vendor/assets/javascripts/yui-2.8.1/build/editor/editor-min.js +30 -0
  187. data/vendor/assets/javascripts/yui-2.8.1/build/editor/editor.js +9447 -0
  188. data/vendor/assets/javascripts/yui-2.8.1/build/editor/simpleeditor-debug.js +7493 -0
  189. data/vendor/assets/javascripts/yui-2.8.1/build/editor/simpleeditor-min.js +24 -0
  190. data/vendor/assets/javascripts/yui-2.8.1/build/editor/simpleeditor.js +7406 -0
  191. data/vendor/assets/javascripts/yui-2.8.1/build/element-delegate/element-delegate-debug.js +141 -0
  192. data/vendor/assets/javascripts/yui-2.8.1/build/element-delegate/element-delegate-min.js +7 -0
  193. data/vendor/assets/javascripts/yui-2.8.1/build/element-delegate/element-delegate.js +138 -0
  194. data/vendor/assets/javascripts/yui-2.8.1/build/element/element-debug.js +1106 -0
  195. data/vendor/assets/javascripts/yui-2.8.1/build/element/element-min.js +8 -0
  196. data/vendor/assets/javascripts/yui-2.8.1/build/element/element.js +1090 -0
  197. data/vendor/assets/javascripts/yui-2.8.1/build/event-delegate/event-delegate-debug.js +283 -0
  198. data/vendor/assets/javascripts/yui-2.8.1/build/event-delegate/event-delegate-min.js +7 -0
  199. data/vendor/assets/javascripts/yui-2.8.1/build/event-delegate/event-delegate.js +281 -0
  200. data/vendor/assets/javascripts/yui-2.8.1/build/event-mouseenter/event-mouseenter-debug.js +219 -0
  201. data/vendor/assets/javascripts/yui-2.8.1/build/event-mouseenter/event-mouseenter-min.js +7 -0
  202. data/vendor/assets/javascripts/yui-2.8.1/build/event-mouseenter/event-mouseenter.js +219 -0
  203. data/vendor/assets/javascripts/yui-2.8.1/build/event-simulate/event-simulate-debug.js +622 -0
  204. data/vendor/assets/javascripts/yui-2.8.1/build/event-simulate/event-simulate-min.js +7 -0
  205. data/vendor/assets/javascripts/yui-2.8.1/build/event-simulate/event-simulate.js +622 -0
  206. data/vendor/assets/javascripts/yui-2.8.1/build/event/event-debug.js +2524 -0
  207. data/vendor/assets/javascripts/yui-2.8.1/build/event/event-min.js +11 -0
  208. data/vendor/assets/javascripts/yui-2.8.1/build/event/event.js +2500 -0
  209. data/vendor/assets/javascripts/yui-2.8.1/build/fonts/fonts-min.css +7 -0
  210. data/vendor/assets/javascripts/yui-2.8.1/build/fonts/fonts.css +56 -0
  211. data/vendor/assets/javascripts/yui-2.8.1/build/get/get-debug.js +773 -0
  212. data/vendor/assets/javascripts/yui-2.8.1/build/get/get-min.js +7 -0
  213. data/vendor/assets/javascripts/yui-2.8.1/build/get/get.js +755 -0
  214. data/vendor/assets/javascripts/yui-2.8.1/build/grids/grids-min.css +7 -0
  215. data/vendor/assets/javascripts/yui-2.8.1/build/grids/grids.css +467 -0
  216. data/vendor/assets/javascripts/yui-2.8.1/build/history/assets/blank.html +1 -0
  217. data/vendor/assets/javascripts/yui-2.8.1/build/history/history-debug.js +808 -0
  218. data/vendor/assets/javascripts/yui-2.8.1/build/history/history-min.js +7 -0
  219. data/vendor/assets/javascripts/yui-2.8.1/build/history/history.js +808 -0
  220. data/vendor/assets/javascripts/yui-2.8.1/build/imagecropper/assets/imagecropper-core.css +33 -0
  221. data/vendor/assets/javascripts/yui-2.8.1/build/imagecropper/assets/skins/sam/imagecropper-skin.css +16 -0
  222. data/vendor/assets/javascripts/yui-2.8.1/build/imagecropper/assets/skins/sam/imagecropper.css +7 -0
  223. data/vendor/assets/javascripts/yui-2.8.1/build/imagecropper/imagecropper-debug.js +907 -0
  224. data/vendor/assets/javascripts/yui-2.8.1/build/imagecropper/imagecropper-min.js +8 -0
  225. data/vendor/assets/javascripts/yui-2.8.1/build/imagecropper/imagecropper.js +889 -0
  226. data/vendor/assets/javascripts/yui-2.8.1/build/imageloader/imageloader-debug.js +487 -0
  227. data/vendor/assets/javascripts/yui-2.8.1/build/imageloader/imageloader-min.js +7 -0
  228. data/vendor/assets/javascripts/yui-2.8.1/build/imageloader/imageloader.js +481 -0
  229. data/vendor/assets/javascripts/yui-2.8.1/build/json/json-debug.js +538 -0
  230. data/vendor/assets/javascripts/yui-2.8.1/build/json/json-min.js +7 -0
  231. data/vendor/assets/javascripts/yui-2.8.1/build/json/json.js +538 -0
  232. data/vendor/assets/javascripts/yui-2.8.1/build/layout/assets/layout-core.css +158 -0
  233. data/vendor/assets/javascripts/yui-2.8.1/build/layout/assets/skins/sam/layout-skin.css +207 -0
  234. data/vendor/assets/javascripts/yui-2.8.1/build/layout/assets/skins/sam/layout.css +7 -0
  235. data/vendor/assets/javascripts/yui-2.8.1/build/layout/assets/skins/sam/layout_sprite.png +0 -0
  236. data/vendor/assets/javascripts/yui-2.8.1/build/layout/layout-debug.js +2305 -0
  237. data/vendor/assets/javascripts/yui-2.8.1/build/layout/layout-min.js +11 -0
  238. data/vendor/assets/javascripts/yui-2.8.1/build/layout/layout.js +2290 -0
  239. data/vendor/assets/javascripts/yui-2.8.1/build/logger/assets/logger-core.css +7 -0
  240. data/vendor/assets/javascripts/yui-2.8.1/build/logger/assets/logger.css +57 -0
  241. data/vendor/assets/javascripts/yui-2.8.1/build/logger/assets/skins/sam/logger-skin.css +55 -0
  242. data/vendor/assets/javascripts/yui-2.8.1/build/logger/assets/skins/sam/logger.css +7 -0
  243. data/vendor/assets/javascripts/yui-2.8.1/build/logger/logger-debug.js +2104 -0
  244. data/vendor/assets/javascripts/yui-2.8.1/build/logger/logger-min.js +9 -0
  245. data/vendor/assets/javascripts/yui-2.8.1/build/logger/logger.js +2104 -0
  246. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menu-core.css +242 -0
  247. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menu.css +503 -0
  248. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menu_down_arrow.png +0 -0
  249. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menu_down_arrow_disabled.png +0 -0
  250. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menu_up_arrow.png +0 -0
  251. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menu_up_arrow_disabled.png +0 -0
  252. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menubaritem_submenuindicator.png +0 -0
  253. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menubaritem_submenuindicator_disabled.png +0 -0
  254. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menubaritem_submenuindicator_selected.png +0 -0
  255. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menuitem_checkbox.png +0 -0
  256. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menuitem_checkbox_disabled.png +0 -0
  257. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menuitem_checkbox_selected.png +0 -0
  258. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menuitem_submenuindicator.png +0 -0
  259. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menuitem_submenuindicator_disabled.png +0 -0
  260. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/menuitem_submenuindicator_selected.png +0 -0
  261. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/skins/sam/menu-skin.css +339 -0
  262. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/skins/sam/menu.css +7 -0
  263. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/skins/sam/menubaritem_submenuindicator.png +0 -0
  264. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/skins/sam/menubaritem_submenuindicator_disabled.png +0 -0
  265. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/skins/sam/menuitem_checkbox.png +0 -0
  266. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/skins/sam/menuitem_checkbox_disabled.png +0 -0
  267. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/skins/sam/menuitem_submenuindicator.png +0 -0
  268. data/vendor/assets/javascripts/yui-2.8.1/build/menu/assets/skins/sam/menuitem_submenuindicator_disabled.png +0 -0
  269. data/vendor/assets/javascripts/yui-2.8.1/build/menu/menu-debug.js +9870 -0
  270. data/vendor/assets/javascripts/yui-2.8.1/build/menu/menu-min.js +16 -0
  271. data/vendor/assets/javascripts/yui-2.8.1/build/menu/menu.js +9823 -0
  272. data/vendor/assets/javascripts/yui-2.8.1/build/paginator/assets/paginator-core.css +6 -0
  273. data/vendor/assets/javascripts/yui-2.8.1/build/paginator/assets/skins/sam/paginator-skin.css +78 -0
  274. data/vendor/assets/javascripts/yui-2.8.1/build/paginator/assets/skins/sam/paginator.css +7 -0
  275. data/vendor/assets/javascripts/yui-2.8.1/build/paginator/paginator-debug.js +2393 -0
  276. data/vendor/assets/javascripts/yui-2.8.1/build/paginator/paginator-min.js +10 -0
  277. data/vendor/assets/javascripts/yui-2.8.1/build/paginator/paginator.js +2393 -0
  278. data/vendor/assets/javascripts/yui-2.8.1/build/profiler/profiler-debug.js +557 -0
  279. data/vendor/assets/javascripts/yui-2.8.1/build/profiler/profiler-min.js +7 -0
  280. data/vendor/assets/javascripts/yui-2.8.1/build/profiler/profiler.js +557 -0
  281. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/assets/profilerviewer-core.css +6 -0
  282. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/assets/skins/sam/asc.gif +0 -0
  283. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/assets/skins/sam/desc.gif +0 -0
  284. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/assets/skins/sam/header_background.png +0 -0
  285. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/assets/skins/sam/profilerviewer-skin.css +167 -0
  286. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/assets/skins/sam/profilerviewer.css +7 -0
  287. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/assets/skins/sam/wait.gif +0 -0
  288. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/profilerviewer-debug.js +1229 -0
  289. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/profilerviewer-min.js +9 -0
  290. data/vendor/assets/javascripts/yui-2.8.1/build/profilerviewer/profilerviewer.js +1192 -0
  291. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/assets/progressbar-core.css +85 -0
  292. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/assets/skins/sam/back-h.png +0 -0
  293. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/assets/skins/sam/back-v.png +0 -0
  294. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/assets/skins/sam/bar-h.png +0 -0
  295. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/assets/skins/sam/bar-v.png +0 -0
  296. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/assets/skins/sam/progressbar-skin.css +56 -0
  297. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/assets/skins/sam/progressbar.css +7 -0
  298. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/progressbar-debug.js +691 -0
  299. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/progressbar-min.js +8 -0
  300. data/vendor/assets/javascripts/yui-2.8.1/build/progressbar/progressbar.js +677 -0
  301. data/vendor/assets/javascripts/yui-2.8.1/build/reset-fonts-grids/reset-fonts-grids.css +7 -0
  302. data/vendor/assets/javascripts/yui-2.8.1/build/reset-fonts/reset-fonts.css +7 -0
  303. data/vendor/assets/javascripts/yui-2.8.1/build/reset/reset-min.css +7 -0
  304. data/vendor/assets/javascripts/yui-2.8.1/build/reset/reset.css +142 -0
  305. data/vendor/assets/javascripts/yui-2.8.1/build/resize/assets/resize-core.css +173 -0
  306. data/vendor/assets/javascripts/yui-2.8.1/build/resize/assets/skins/sam/layout_sprite.png +0 -0
  307. data/vendor/assets/javascripts/yui-2.8.1/build/resize/assets/skins/sam/resize-skin.css +142 -0
  308. data/vendor/assets/javascripts/yui-2.8.1/build/resize/assets/skins/sam/resize.css +7 -0
  309. data/vendor/assets/javascripts/yui-2.8.1/build/resize/resize-debug.js +1749 -0
  310. data/vendor/assets/javascripts/yui-2.8.1/build/resize/resize-min.js +10 -0
  311. data/vendor/assets/javascripts/yui-2.8.1/build/resize/resize.js +1689 -0
  312. data/vendor/assets/javascripts/yui-2.8.1/build/selector/selector-debug.js +651 -0
  313. data/vendor/assets/javascripts/yui-2.8.1/build/selector/selector-min.js +8 -0
  314. data/vendor/assets/javascripts/yui-2.8.1/build/selector/selector.js +644 -0
  315. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/bg-fader.gif +0 -0
  316. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/bg-h.gif +0 -0
  317. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/bg-v-e.gif +0 -0
  318. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/bg-v.gif +0 -0
  319. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/left-thumb.png +0 -0
  320. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/right-thumb.png +0 -0
  321. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/skins/sam/bg-h.gif +0 -0
  322. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/skins/sam/bg-v.gif +0 -0
  323. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/skins/sam/slider-skin.css +24 -0
  324. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/skins/sam/slider.css +7 -0
  325. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/slider-core.css +17 -0
  326. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/slider-skin.css +20 -0
  327. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/thumb-bar.gif +0 -0
  328. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/thumb-e.gif +0 -0
  329. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/thumb-fader.gif +0 -0
  330. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/thumb-n.gif +0 -0
  331. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/thumb-s.gif +0 -0
  332. data/vendor/assets/javascripts/yui-2.8.1/build/slider/assets/thumb-w.gif +0 -0
  333. data/vendor/assets/javascripts/yui-2.8.1/build/slider/slider-debug.js +2114 -0
  334. data/vendor/assets/javascripts/yui-2.8.1/build/slider/slider-min.js +9 -0
  335. data/vendor/assets/javascripts/yui-2.8.1/build/slider/slider.js +2068 -0
  336. data/vendor/assets/javascripts/yui-2.8.1/build/storage/storage-debug.js +1185 -0
  337. data/vendor/assets/javascripts/yui-2.8.1/build/storage/storage-min.js +8 -0
  338. data/vendor/assets/javascripts/yui-2.8.1/build/storage/storage.js +1183 -0
  339. data/vendor/assets/javascripts/yui-2.8.1/build/stylesheet/stylesheet-debug.js +648 -0
  340. data/vendor/assets/javascripts/yui-2.8.1/build/stylesheet/stylesheet-min.js +7 -0
  341. data/vendor/assets/javascripts/yui-2.8.1/build/stylesheet/stylesheet.js +645 -0
  342. data/vendor/assets/javascripts/yui-2.8.1/build/swf/swf-debug.js +269 -0
  343. data/vendor/assets/javascripts/yui-2.8.1/build/swf/swf-min.js +7 -0
  344. data/vendor/assets/javascripts/yui-2.8.1/build/swf/swf.js +268 -0
  345. data/vendor/assets/javascripts/yui-2.8.1/build/swfdetect/swfdetect-debug.js +93 -0
  346. data/vendor/assets/javascripts/yui-2.8.1/build/swfdetect/swfdetect-min.js +7 -0
  347. data/vendor/assets/javascripts/yui-2.8.1/build/swfdetect/swfdetect.js +93 -0
  348. data/vendor/assets/javascripts/yui-2.8.1/build/swfstore/swf.js +238 -0
  349. data/vendor/assets/javascripts/yui-2.8.1/build/swfstore/swfstore-debug.js +470 -0
  350. data/vendor/assets/javascripts/yui-2.8.1/build/swfstore/swfstore-min.js +7 -0
  351. data/vendor/assets/javascripts/yui-2.8.1/build/swfstore/swfstore.js +453 -0
  352. data/vendor/assets/javascripts/yui-2.8.1/build/swfstore/swfstore.swf +0 -0
  353. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/assets/border_tabs.css +54 -0
  354. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/assets/loading.gif +0 -0
  355. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/assets/skin-sam.css +77 -0
  356. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/assets/skins/sam/tabview-skin.css +186 -0
  357. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/assets/skins/sam/tabview.css +8 -0
  358. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/assets/tabview-core.css +133 -0
  359. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/assets/tabview.css +77 -0
  360. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/tabview-debug.js +995 -0
  361. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/tabview-min.js +8 -0
  362. data/vendor/assets/javascripts/yui-2.8.1/build/tabview/tabview.js +987 -0
  363. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/assets/skins/sam/check0.gif +0 -0
  364. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/assets/skins/sam/check1.gif +0 -0
  365. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/assets/skins/sam/check2.gif +0 -0
  366. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/assets/skins/sam/loading.gif +0 -0
  367. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/assets/skins/sam/treeview-loading.gif +0 -0
  368. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/assets/skins/sam/treeview-skin.css +249 -0
  369. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/assets/skins/sam/treeview-sprite.gif +0 -0
  370. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/assets/skins/sam/treeview.css +7 -0
  371. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/assets/treeview-core.css +6 -0
  372. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/treeview-debug.js +4058 -0
  373. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/treeview-min.js +12 -0
  374. data/vendor/assets/javascripts/yui-2.8.1/build/treeview/treeview.js +3989 -0
  375. data/vendor/assets/javascripts/yui-2.8.1/build/uploader/assets/uploader.swf +0 -0
  376. data/vendor/assets/javascripts/yui-2.8.1/build/uploader/uploader-debug.js +1072 -0
  377. data/vendor/assets/javascripts/yui-2.8.1/build/uploader/uploader-min.js +15 -0
  378. data/vendor/assets/javascripts/yui-2.8.1/build/uploader/uploader.js +1069 -0
  379. data/vendor/assets/javascripts/yui-2.8.1/build/utilities/utilities.js +39 -0
  380. data/vendor/assets/javascripts/yui-2.8.1/build/yahoo-dom-event/yahoo-dom-event.js +14 -0
  381. data/vendor/assets/javascripts/yui-2.8.1/build/yahoo/yahoo-debug.js +1075 -0
  382. data/vendor/assets/javascripts/yui-2.8.1/build/yahoo/yahoo-min.js +7 -0
  383. data/vendor/assets/javascripts/yui-2.8.1/build/yahoo/yahoo.js +1075 -0
  384. data/vendor/assets/javascripts/yui-2.8.1/build/yuiloader-dom-event/yuiloader-dom-event.js +17 -0
  385. data/vendor/assets/javascripts/yui-2.8.1/build/yuiloader/yuiloader-debug.js +3879 -0
  386. data/vendor/assets/javascripts/yui-2.8.1/build/yuiloader/yuiloader-min.js +10 -0
  387. data/vendor/assets/javascripts/yui-2.8.1/build/yuiloader/yuiloader.js +3879 -0
  388. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/assets/skins/sam/yuitest-skin.css +7 -0
  389. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/assets/skins/sam/yuitest.css +7 -0
  390. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/assets/testlogger.css +7 -0
  391. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/assets/yuitest-core.css +7 -0
  392. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/yuitest-debug.js +2741 -0
  393. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/yuitest-min.js +10 -0
  394. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/yuitest.js +2741 -0
  395. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/yuitest_core-debug.js +1976 -0
  396. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/yuitest_core-min.js +9 -0
  397. data/vendor/assets/javascripts/yui-2.8.1/build/yuitest/yuitest_core.js +1976 -0
  398. metadata +470 -0
@@ -0,0 +1,12 @@
1
+ /*
2
+ Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3
+ Code licensed under the BSD License:
4
+ http://developer.yahoo.com/yui/license.html
5
+ version: 2.8.1
6
+ */
7
+ (function(){var D=YAHOO.util.Dom,B=YAHOO.util.Event,F=YAHOO.lang,E=YAHOO.widget;YAHOO.widget.TreeView=function(H,G){if(H){this.init(H);}if(G){this.buildTreeFromObject(G);}else{if(F.trim(this._el.innerHTML)){this.buildTreeFromMarkup(H);}}};var C=E.TreeView;C.prototype={id:null,_el:null,_nodes:null,locked:false,_expandAnim:null,_collapseAnim:null,_animCount:0,maxAnim:2,_hasDblClickSubscriber:false,_dblClickTimer:null,currentFocus:null,singleNodeHighlight:false,_currentlyHighlighted:null,setExpandAnim:function(G){this._expandAnim=(E.TVAnim.isValid(G))?G:null;},setCollapseAnim:function(G){this._collapseAnim=(E.TVAnim.isValid(G))?G:null;},animateExpand:function(I,J){if(this._expandAnim&&this._animCount<this.maxAnim){var G=this;var H=E.TVAnim.getAnim(this._expandAnim,I,function(){G.expandComplete(J);});if(H){++this._animCount;this.fireEvent("animStart",{"node":J,"type":"expand"});H.animate();}return true;}return false;},animateCollapse:function(I,J){if(this._collapseAnim&&this._animCount<this.maxAnim){var G=this;var H=E.TVAnim.getAnim(this._collapseAnim,I,function(){G.collapseComplete(J);});if(H){++this._animCount;this.fireEvent("animStart",{"node":J,"type":"collapse"});H.animate();}return true;}return false;},expandComplete:function(G){--this._animCount;this.fireEvent("animComplete",{"node":G,"type":"expand"});},collapseComplete:function(G){--this._animCount;this.fireEvent("animComplete",{"node":G,"type":"collapse"});},init:function(I){this._el=D.get(I);this.id=D.generateId(this._el,"yui-tv-auto-id-");this.createEvent("animStart",this);this.createEvent("animComplete",this);this.createEvent("collapse",this);this.createEvent("collapseComplete",this);this.createEvent("expand",this);this.createEvent("expandComplete",this);this.createEvent("enterKeyPressed",this);this.createEvent("clickEvent",this);this.createEvent("focusChanged",this);var G=this;this.createEvent("dblClickEvent",{scope:this,onSubscribeCallback:function(){G._hasDblClickSubscriber=true;}});this.createEvent("labelClick",this);this.createEvent("highlightEvent",this);this._nodes=[];C.trees[this.id]=this;this.root=new E.RootNode(this);var H=E.LogWriter;if(this._initEditor){this._initEditor();}},buildTreeFromObject:function(G){var H=function(P,M){var L,Q,K,J,O,I,N;for(L=0;L<M.length;L++){Q=M[L];if(F.isString(Q)){K=new E.TextNode(Q,P);}else{if(F.isObject(Q)){J=Q.children;delete Q.children;O=Q.type||"text";delete Q.type;switch(F.isString(O)&&O.toLowerCase()){case"text":K=new E.TextNode(Q,P);break;case"menu":K=new E.MenuNode(Q,P);break;case"html":K=new E.HTMLNode(Q,P);break;default:if(F.isString(O)){I=E[O];}else{I=O;}if(F.isObject(I)){for(N=I;N&&N!==E.Node;N=N.superclass.constructor){}if(N){K=new I(Q,P);}else{}}else{}}if(J){H(K,J);}}else{}}}};if(!F.isArray(G)){G=[G];}H(this.root,G);},buildTreeFromMarkup:function(I){var H=function(J){var N,Q,M=[],L={},K,O;for(N=D.getFirstChild(J);N;N=D.getNextSibling(N)){switch(N.tagName.toUpperCase()){case"LI":K="";L={expanded:D.hasClass(N,"expanded"),title:N.title||N.alt||null,className:F.trim(N.className.replace(/\bexpanded\b/,""))||null};Q=N.firstChild;if(Q.nodeType==3){K=F.trim(Q.nodeValue.replace(/[\n\t\r]*/g,""));if(K){L.type="text";L.label=K;}else{Q=D.getNextSibling(Q);}}if(!K){if(Q.tagName.toUpperCase()=="A"){L.type="text";L.label=Q.innerHTML;L.href=Q.href;L.target=Q.target;L.title=Q.title||Q.alt||L.title;}else{L.type="html";var P=document.createElement("div");P.appendChild(Q.cloneNode(true));L.html=P.innerHTML;L.hasIcon=true;}}Q=D.getNextSibling(Q);switch(Q&&Q.tagName.toUpperCase()){case"UL":case"OL":L.children=H(Q);break;}if(YAHOO.lang.JSON){O=N.getAttribute("yuiConfig");if(O){O=YAHOO.lang.JSON.parse(O);L=YAHOO.lang.merge(L,O);}}M.push(L);break;case"UL":case"OL":L={type:"text",label:"",children:H(Q)};M.push(L);break;}}return M;};var G=D.getChildrenBy(D.get(I),function(K){var J=K.tagName.toUpperCase();return J=="UL"||J=="OL";});if(G.length){this.buildTreeFromObject(H(G[0]));}else{}},_getEventTargetTdEl:function(H){var I=B.getTarget(H);while(I&&!(I.tagName.toUpperCase()=="TD"&&D.hasClass(I.parentNode,"ygtvrow"))){I=D.getAncestorByTagName(I,"td");}if(F.isNull(I)){return null;}if(/\bygtv(blank)?depthcell/.test(I.className)){return null;}if(I.id){var G=I.id.match(/\bygtv([^\d]*)(.*)/);if(G&&G[2]&&this._nodes[G[2]]){return I;}}return null;},_onClickEvent:function(J){var H=this,L=this._getEventTargetTdEl(J),I,K,G=function(M){I.focus();if(M||!I.href){I.toggle();try{B.preventDefault(J);}catch(N){}}};if(!L){return;}I=this.getNodeByElement(L);if(!I){return;}K=B.getTarget(J);if(D.hasClass(K,I.labelStyle)||D.getAncestorByClassName(K,I.labelStyle)){this.fireEvent("labelClick",I);}if(/\bygtv[tl][mp]h?h?/.test(L.className)){G(true);}else{if(this._dblClickTimer){window.clearTimeout(this._dblClickTimer);this._dblClickTimer=null;}else{if(this._hasDblClickSubscriber){this._dblClickTimer=window.setTimeout(function(){H._dblClickTimer=null;if(H.fireEvent("clickEvent",{event:J,node:I})!==false){G();}},200);}else{if(H.fireEvent("clickEvent",{event:J,node:I})!==false){G();}}}}},_onDblClickEvent:function(G){if(!this._hasDblClickSubscriber){return;}var H=this._getEventTargetTdEl(G);if(!H){return;}if(!(/\bygtv[tl][mp]h?h?/.test(H.className))){this.fireEvent("dblClickEvent",{event:G,node:this.getNodeByElement(H)});if(this._dblClickTimer){window.clearTimeout(this._dblClickTimer);this._dblClickTimer=null;}}},_onMouseOverEvent:function(G){var H;if((H=this._getEventTargetTdEl(G))&&(H=this.getNodeByElement(H))&&(H=H.getToggleEl())){H.className=H.className.replace(/\bygtv([lt])([mp])\b/gi,"ygtv$1$2h");}},_onMouseOutEvent:function(G){var H;if((H=this._getEventTargetTdEl(G))&&(H=this.getNodeByElement(H))&&(H=H.getToggleEl())){H.className=H.className.replace(/\bygtv([lt])([mp])h\b/gi,"ygtv$1$2");}},_onKeyDownEvent:function(L){var N=B.getTarget(L),K=this.getNodeByElement(N),J=K,G=YAHOO.util.KeyListener.KEY;switch(L.keyCode){case G.UP:do{if(J.previousSibling){J=J.previousSibling;}else{J=J.parent;}}while(J&&!J._canHaveFocus());if(J){J.focus();
8
+ }B.preventDefault(L);break;case G.DOWN:do{if(J.nextSibling){J=J.nextSibling;}else{J.expand();J=(J.children.length||null)&&J.children[0];}}while(J&&!J._canHaveFocus);if(J){J.focus();}B.preventDefault(L);break;case G.LEFT:do{if(J.parent){J=J.parent;}else{J=J.previousSibling;}}while(J&&!J._canHaveFocus());if(J){J.focus();}B.preventDefault(L);break;case G.RIGHT:var I=this,M,H=function(O){I.unsubscribe("expandComplete",H);M(O);};M=function(O){do{if(O.isDynamic()&&!O.childrenRendered){I.subscribe("expandComplete",H);O.expand();O=null;break;}else{O.expand();if(O.children.length){O=O.children[0];}else{O=O.nextSibling;}}}while(O&&!O._canHaveFocus());if(O){O.focus();}};M(J);B.preventDefault(L);break;case G.ENTER:if(K.href){if(K.target){window.open(K.href,K.target);}else{window.location(K.href);}}else{K.toggle();}this.fireEvent("enterKeyPressed",K);B.preventDefault(L);break;case G.HOME:J=this.getRoot();if(J.children.length){J=J.children[0];}if(J._canHaveFocus()){J.focus();}B.preventDefault(L);break;case G.END:J=J.parent.children;J=J[J.length-1];if(J._canHaveFocus()){J.focus();}B.preventDefault(L);break;case 107:if(L.shiftKey){K.parent.expandAll();}else{K.expand();}break;case 109:if(L.shiftKey){K.parent.collapseAll();}else{K.collapse();}break;default:break;}},render:function(){var G=this.root.getHtml(),H=this.getEl();H.innerHTML=G;if(!this._hasEvents){B.on(H,"click",this._onClickEvent,this,true);B.on(H,"dblclick",this._onDblClickEvent,this,true);B.on(H,"mouseover",this._onMouseOverEvent,this,true);B.on(H,"mouseout",this._onMouseOutEvent,this,true);B.on(H,"keydown",this._onKeyDownEvent,this,true);}this._hasEvents=true;},getEl:function(){if(!this._el){this._el=D.get(this.id);}return this._el;},regNode:function(G){this._nodes[G.index]=G;},getRoot:function(){return this.root;},setDynamicLoad:function(G,H){this.root.setDynamicLoad(G,H);},expandAll:function(){if(!this.locked){this.root.expandAll();}},collapseAll:function(){if(!this.locked){this.root.collapseAll();}},getNodeByIndex:function(H){var G=this._nodes[H];return(G)?G:null;},getNodeByProperty:function(I,H){for(var G in this._nodes){if(this._nodes.hasOwnProperty(G)){var J=this._nodes[G];if((I in J&&J[I]==H)||(J.data&&H==J.data[I])){return J;}}}return null;},getNodesByProperty:function(J,I){var G=[];for(var H in this._nodes){if(this._nodes.hasOwnProperty(H)){var K=this._nodes[H];if((J in K&&K[J]==I)||(K.data&&I==K.data[J])){G.push(K);}}}return(G.length)?G:null;},getNodesBy:function(I){var G=[];for(var H in this._nodes){if(this._nodes.hasOwnProperty(H)){var J=this._nodes[H];if(I(J)){G.push(J);}}}return(G.length)?G:null;},getNodeByElement:function(I){var J=I,G,H=/ygtv([^\d]*)(.*)/;do{if(J&&J.id){G=J.id.match(H);if(G&&G[2]){return this.getNodeByIndex(G[2]);}}J=J.parentNode;if(!J||!J.tagName){break;}}while(J.id!==this.id&&J.tagName.toLowerCase()!=="body");return null;},getHighlightedNode:function(){return this._currentlyHighlighted;},removeNode:function(H,G){if(H.isRoot()){return false;}var I=H.parent;if(I.parent){I=I.parent;}this._deleteNode(H);if(G&&I&&I.childrenRendered){I.refresh();}return true;},_removeChildren_animComplete:function(G){this.unsubscribe(this._removeChildren_animComplete);this.removeChildren(G.node);},removeChildren:function(G){if(G.expanded){if(this._collapseAnim){this.subscribe("animComplete",this._removeChildren_animComplete,this,true);E.Node.prototype.collapse.call(G);return;}G.collapse();}while(G.children.length){this._deleteNode(G.children[0]);}if(G.isRoot()){E.Node.prototype.expand.call(G);}G.childrenRendered=false;G.dynamicLoadComplete=false;G.updateIcon();},_deleteNode:function(G){this.removeChildren(G);this.popNode(G);},popNode:function(J){var K=J.parent;var H=[];for(var I=0,G=K.children.length;I<G;++I){if(K.children[I]!=J){H[H.length]=K.children[I];}}K.children=H;K.childrenRendered=false;if(J.previousSibling){J.previousSibling.nextSibling=J.nextSibling;}if(J.nextSibling){J.nextSibling.previousSibling=J.previousSibling;}if(this.currentFocus==J){this.currentFocus=null;}if(this._currentlyHighlighted==J){this._currentlyHighlighted=null;}J.parent=null;J.previousSibling=null;J.nextSibling=null;J.tree=null;delete this._nodes[J.index];},destroy:function(){if(this._destroyEditor){this._destroyEditor();}var H=this.getEl();B.removeListener(H,"click");B.removeListener(H,"dblclick");B.removeListener(H,"mouseover");B.removeListener(H,"mouseout");B.removeListener(H,"keydown");for(var G=0;G<this._nodes.length;G++){var I=this._nodes[G];if(I&&I.destroy){I.destroy();}}H.innerHTML="";this._hasEvents=false;},toString:function(){return"TreeView "+this.id;},getNodeCount:function(){return this.getRoot().getNodeCount();},getTreeDefinition:function(){return this.getRoot().getNodeDefinition();},onExpand:function(G){},onCollapse:function(G){},setNodesProperty:function(G,I,H){this.root.setNodesProperty(G,I);if(H){this.root.refresh();}},onEventToggleHighlight:function(H){var G;if("node" in H&&H.node instanceof E.Node){G=H.node;}else{if(H instanceof E.Node){G=H;}else{return false;}}G.toggleHighlight();return false;}};var A=C.prototype;A.draw=A.render;YAHOO.augment(C,YAHOO.util.EventProvider);C.nodeCount=0;C.trees=[];C.getTree=function(H){var G=C.trees[H];return(G)?G:null;};C.getNode=function(H,I){var G=C.getTree(H);return(G)?G.getNodeByIndex(I):null;};C.FOCUS_CLASS_NAME="ygtvfocus";})();(function(){var B=YAHOO.util.Dom,C=YAHOO.lang,A=YAHOO.util.Event;YAHOO.widget.Node=function(F,E,D){if(F){this.init(F,E,D);}};YAHOO.widget.Node.prototype={index:0,children:null,tree:null,data:null,parent:null,depth:-1,expanded:false,multiExpand:true,renderHidden:false,childrenRendered:false,dynamicLoadComplete:false,previousSibling:null,nextSibling:null,_dynLoad:false,dataLoader:null,isLoading:false,hasIcon:true,iconMode:0,nowrap:false,isLeaf:false,contentStyle:"",contentElId:null,enableHighlight:true,highlightState:0,propagateHighlightUp:false,propagateHighlightDown:false,className:null,_type:"Node",init:function(G,F,D){this.data={};this.children=[];this.index=YAHOO.widget.TreeView.nodeCount;
9
+ ++YAHOO.widget.TreeView.nodeCount;this.contentElId="ygtvcontentel"+this.index;if(C.isObject(G)){for(var E in G){if(G.hasOwnProperty(E)){if(E.charAt(0)!="_"&&!C.isUndefined(this[E])&&!C.isFunction(this[E])){this[E]=G[E];}else{this.data[E]=G[E];}}}}if(!C.isUndefined(D)){this.expanded=D;}this.createEvent("parentChange",this);if(F){F.appendChild(this);}},applyParent:function(E){if(!E){return false;}this.tree=E.tree;this.parent=E;this.depth=E.depth+1;this.tree.regNode(this);E.childrenRendered=false;for(var F=0,D=this.children.length;F<D;++F){this.children[F].applyParent(this);}this.fireEvent("parentChange");return true;},appendChild:function(E){if(this.hasChildren()){var D=this.children[this.children.length-1];D.nextSibling=E;E.previousSibling=D;}this.children[this.children.length]=E;E.applyParent(this);if(this.childrenRendered&&this.expanded){this.getChildrenEl().style.display="";}return E;},appendTo:function(D){return D.appendChild(this);},insertBefore:function(D){var F=D.parent;if(F){if(this.tree){this.tree.popNode(this);}var E=D.isChildOf(F);F.children.splice(E,0,this);if(D.previousSibling){D.previousSibling.nextSibling=this;}this.previousSibling=D.previousSibling;this.nextSibling=D;D.previousSibling=this;this.applyParent(F);}return this;},insertAfter:function(D){var F=D.parent;if(F){if(this.tree){this.tree.popNode(this);}var E=D.isChildOf(F);if(!D.nextSibling){this.nextSibling=null;return this.appendTo(F);}F.children.splice(E+1,0,this);D.nextSibling.previousSibling=this;this.previousSibling=D;this.nextSibling=D.nextSibling;D.nextSibling=this;this.applyParent(F);}return this;},isChildOf:function(E){if(E&&E.children){for(var F=0,D=E.children.length;F<D;++F){if(E.children[F]===this){return F;}}}return -1;},getSiblings:function(){var D=this.parent.children.slice(0);for(var E=0;E<D.length&&D[E]!=this;E++){}D.splice(E,1);if(D.length){return D;}return null;},showChildren:function(){if(!this.tree.animateExpand(this.getChildrenEl(),this)){if(this.hasChildren()){this.getChildrenEl().style.display="";}}},hideChildren:function(){if(!this.tree.animateCollapse(this.getChildrenEl(),this)){this.getChildrenEl().style.display="none";}},getElId:function(){return"ygtv"+this.index;},getChildrenElId:function(){return"ygtvc"+this.index;},getToggleElId:function(){return"ygtvt"+this.index;},getEl:function(){return B.get(this.getElId());},getChildrenEl:function(){return B.get(this.getChildrenElId());},getToggleEl:function(){return B.get(this.getToggleElId());},getContentEl:function(){return B.get(this.contentElId);},collapse:function(){if(!this.expanded){return;}var D=this.tree.onCollapse(this);if(false===D){return;}D=this.tree.fireEvent("collapse",this);if(false===D){return;}if(!this.getEl()){this.expanded=false;}else{this.hideChildren();this.expanded=false;this.updateIcon();}D=this.tree.fireEvent("collapseComplete",this);},expand:function(F){if(this.isLoading||(this.expanded&&!F)){return;}var D=true;if(!F){D=this.tree.onExpand(this);if(false===D){return;}D=this.tree.fireEvent("expand",this);}if(false===D){return;}if(!this.getEl()){this.expanded=true;return;}if(!this.childrenRendered){this.getChildrenEl().innerHTML=this.renderChildren();}else{}this.expanded=true;this.updateIcon();if(this.isLoading){this.expanded=false;return;}if(!this.multiExpand){var G=this.getSiblings();for(var E=0;G&&E<G.length;++E){if(G[E]!=this&&G[E].expanded){G[E].collapse();}}}this.showChildren();D=this.tree.fireEvent("expandComplete",this);},updateIcon:function(){if(this.hasIcon){var D=this.getToggleEl();if(D){D.className=D.className.replace(/\bygtv(([tl][pmn]h?)|(loading))\b/gi,this.getStyle());}}},getStyle:function(){if(this.isLoading){return"ygtvloading";}else{var E=(this.nextSibling)?"t":"l";var D="n";if(this.hasChildren(true)||(this.isDynamic()&&!this.getIconMode())){D=(this.expanded)?"m":"p";}return"ygtv"+E+D;}},getHoverStyle:function(){var D=this.getStyle();if(this.hasChildren(true)&&!this.isLoading){D+="h";}return D;},expandAll:function(){var D=this.children.length;for(var E=0;E<D;++E){var F=this.children[E];if(F.isDynamic()){break;}else{if(!F.multiExpand){break;}else{F.expand();F.expandAll();}}}},collapseAll:function(){for(var D=0;D<this.children.length;++D){this.children[D].collapse();this.children[D].collapseAll();}},setDynamicLoad:function(D,E){if(D){this.dataLoader=D;this._dynLoad=true;}else{this.dataLoader=null;this._dynLoad=false;}if(E){this.iconMode=E;}},isRoot:function(){return(this==this.tree.root);},isDynamic:function(){if(this.isLeaf){return false;}else{return(!this.isRoot()&&(this._dynLoad||this.tree.root._dynLoad));}},getIconMode:function(){return(this.iconMode||this.tree.root.iconMode);},hasChildren:function(D){if(this.isLeaf){return false;}else{return(this.children.length>0||(D&&this.isDynamic()&&!this.dynamicLoadComplete));}},toggle:function(){if(!this.tree.locked&&(this.hasChildren(true)||this.isDynamic())){if(this.expanded){this.collapse();}else{this.expand();}}},getHtml:function(){this.childrenRendered=false;return['<div class="ygtvitem" id="',this.getElId(),'">',this.getNodeHtml(),this.getChildrenHtml(),"</div>"].join("");},getChildrenHtml:function(){var D=[];D[D.length]='<div class="ygtvchildren" id="'+this.getChildrenElId()+'"';if(!this.expanded||!this.hasChildren()){D[D.length]=' style="display:none;"';}D[D.length]=">";if((this.hasChildren(true)&&this.expanded)||(this.renderHidden&&!this.isDynamic())){D[D.length]=this.renderChildren();}D[D.length]="</div>";return D.join("");},renderChildren:function(){var D=this;if(this.isDynamic()&&!this.dynamicLoadComplete){this.isLoading=true;this.tree.locked=true;if(this.dataLoader){setTimeout(function(){D.dataLoader(D,function(){D.loadComplete();});},10);}else{if(this.tree.root.dataLoader){setTimeout(function(){D.tree.root.dataLoader(D,function(){D.loadComplete();});},10);}else{return"Error: data loader not found or not specified.";}}return"";}else{return this.completeRender();}},completeRender:function(){var E=[];for(var D=0;D<this.children.length;++D){E[E.length]=this.children[D].getHtml();
10
+ }this.childrenRendered=true;return E.join("");},loadComplete:function(){this.getChildrenEl().innerHTML=this.completeRender();if(this.propagateHighlightDown){if(this.highlightState===1&&!this.tree.singleNodeHighlight){for(var D=0;D<this.children.length;D++){this.children[D].highlight(true);}}else{if(this.highlightState===0||this.tree.singleNodeHighlight){for(D=0;D<this.children.length;D++){this.children[D].unhighlight(true);}}}}this.dynamicLoadComplete=true;this.isLoading=false;this.expand(true);this.tree.locked=false;},getAncestor:function(E){if(E>=this.depth||E<0){return null;}var D=this.parent;while(D.depth>E){D=D.parent;}return D;},getDepthStyle:function(D){return(this.getAncestor(D).nextSibling)?"ygtvdepthcell":"ygtvblankdepthcell";},getNodeHtml:function(){var E=[];E[E.length]='<table id="ygtvtableel'+this.index+'" border="0" cellpadding="0" cellspacing="0" class="ygtvtable ygtvdepth'+this.depth;if(this.enableHighlight){E[E.length]=" ygtv-highlight"+this.highlightState;}if(this.className){E[E.length]=" "+this.className;}E[E.length]='"><tr class="ygtvrow">';for(var D=0;D<this.depth;++D){E[E.length]='<td class="ygtvcell '+this.getDepthStyle(D)+'"><div class="ygtvspacer"></div></td>';}if(this.hasIcon){E[E.length]='<td id="'+this.getToggleElId();E[E.length]='" class="ygtvcell ';E[E.length]=this.getStyle();E[E.length]='"><a href="#" class="ygtvspacer">&#160;</a></td>';}E[E.length]='<td id="'+this.contentElId;E[E.length]='" class="ygtvcell ';E[E.length]=this.contentStyle+' ygtvcontent" ';E[E.length]=(this.nowrap)?' nowrap="nowrap" ':"";E[E.length]=" >";E[E.length]=this.getContentHtml();E[E.length]="</td></tr></table>";return E.join("");},getContentHtml:function(){return"";},refresh:function(){this.getChildrenEl().innerHTML=this.completeRender();if(this.hasIcon){var D=this.getToggleEl();if(D){D.className=D.className.replace(/\bygtv[lt][nmp]h*\b/gi,this.getStyle());}}},toString:function(){return this._type+" ("+this.index+")";},_focusHighlightedItems:[],_focusedItem:null,_canHaveFocus:function(){return this.getEl().getElementsByTagName("a").length>0;},_removeFocus:function(){if(this._focusedItem){A.removeListener(this._focusedItem,"blur");this._focusedItem=null;}var D;while((D=this._focusHighlightedItems.shift())){B.removeClass(D,YAHOO.widget.TreeView.FOCUS_CLASS_NAME);}},focus:function(){var F=false,D=this;if(this.tree.currentFocus){this.tree.currentFocus._removeFocus();}var E=function(G){if(G.parent){E(G.parent);G.parent.expand();}};E(this);B.getElementsBy(function(G){return(/ygtv(([tl][pmn]h?)|(content))/).test(G.className);},"td",D.getEl().firstChild,function(H){B.addClass(H,YAHOO.widget.TreeView.FOCUS_CLASS_NAME);if(!F){var G=H.getElementsByTagName("a");if(G.length){G=G[0];G.focus();D._focusedItem=G;A.on(G,"blur",function(){D.tree.fireEvent("focusChanged",{oldNode:D.tree.currentFocus,newNode:null});D.tree.currentFocus=null;D._removeFocus();});F=true;}}D._focusHighlightedItems.push(H);});if(F){this.tree.fireEvent("focusChanged",{oldNode:this.tree.currentFocus,newNode:this});this.tree.currentFocus=this;}else{this.tree.fireEvent("focusChanged",{oldNode:D.tree.currentFocus,newNode:null});this.tree.currentFocus=null;this._removeFocus();}return F;},getNodeCount:function(){for(var D=0,E=0;D<this.children.length;D++){E+=this.children[D].getNodeCount();}return E+1;},getNodeDefinition:function(){if(this.isDynamic()){return false;}var G,D=C.merge(this.data),F=[];if(this.expanded){D.expanded=this.expanded;}if(!this.multiExpand){D.multiExpand=this.multiExpand;}if(!this.renderHidden){D.renderHidden=this.renderHidden;}if(!this.hasIcon){D.hasIcon=this.hasIcon;}if(this.nowrap){D.nowrap=this.nowrap;}if(this.className){D.className=this.className;}if(this.editable){D.editable=this.editable;}if(this.enableHighlight){D.enableHighlight=this.enableHighlight;}if(this.highlightState){D.highlightState=this.highlightState;}if(this.propagateHighlightUp){D.propagateHighlightUp=this.propagateHighlightUp;}if(this.propagateHighlightDown){D.propagateHighlightDown=this.propagateHighlightDown;}D.type=this._type;for(var E=0;E<this.children.length;E++){G=this.children[E].getNodeDefinition();if(G===false){return false;}F.push(G);}if(F.length){D.children=F;}return D;},getToggleLink:function(){return"return false;";},setNodesProperty:function(D,G,F){if(D.charAt(0)!="_"&&!C.isUndefined(this[D])&&!C.isFunction(this[D])){this[D]=G;}else{this.data[D]=G;}for(var E=0;E<this.children.length;E++){this.children[E].setNodesProperty(D,G);}if(F){this.refresh();}},toggleHighlight:function(){if(this.enableHighlight){if(this.highlightState==1){this.unhighlight();}else{this.highlight();}}},highlight:function(E){if(this.enableHighlight){if(this.tree.singleNodeHighlight){if(this.tree._currentlyHighlighted){this.tree._currentlyHighlighted.unhighlight(E);}this.tree._currentlyHighlighted=this;}this.highlightState=1;this._setHighlightClassName();if(!this.tree.singleNodeHighlight){if(this.propagateHighlightDown){for(var D=0;D<this.children.length;D++){this.children[D].highlight(true);}}if(this.propagateHighlightUp){if(this.parent){this.parent._childrenHighlighted();}}}if(!E){this.tree.fireEvent("highlightEvent",this);}}},unhighlight:function(E){if(this.enableHighlight){this.tree._currentlyHighlighted=null;this.highlightState=0;this._setHighlightClassName();if(!this.tree.singleNodeHighlight){if(this.propagateHighlightDown){for(var D=0;D<this.children.length;D++){this.children[D].unhighlight(true);}}if(this.propagateHighlightUp){if(this.parent){this.parent._childrenHighlighted();}}}if(!E){this.tree.fireEvent("highlightEvent",this);}}},_childrenHighlighted:function(){var F=false,E=false;if(this.enableHighlight){for(var D=0;D<this.children.length;D++){switch(this.children[D].highlightState){case 0:E=true;break;case 1:F=true;break;case 2:F=E=true;break;}}if(F&&E){this.highlightState=2;}else{if(F){this.highlightState=1;}else{this.highlightState=0;}}this._setHighlightClassName();if(this.propagateHighlightUp){if(this.parent){this.parent._childrenHighlighted();
11
+ }}}},_setHighlightClassName:function(){var D=B.get("ygtvtableel"+this.index);if(D){D.className=D.className.replace(/\bygtv-highlight\d\b/gi,"ygtv-highlight"+this.highlightState);}}};YAHOO.augment(YAHOO.widget.Node,YAHOO.util.EventProvider);})();YAHOO.widget.RootNode=function(A){this.init(null,null,true);this.tree=A;};YAHOO.extend(YAHOO.widget.RootNode,YAHOO.widget.Node,{_type:"RootNode",getNodeHtml:function(){return"";},toString:function(){return this._type;},loadComplete:function(){this.tree.draw();},getNodeCount:function(){for(var A=0,B=0;A<this.children.length;A++){B+=this.children[A].getNodeCount();}return B;},getNodeDefinition:function(){for(var C,A=[],B=0;B<this.children.length;B++){C=this.children[B].getNodeDefinition();if(C===false){return false;}A.push(C);}return A;},collapse:function(){},expand:function(){},getSiblings:function(){return null;},focus:function(){}});(function(){var B=YAHOO.util.Dom,C=YAHOO.lang,A=YAHOO.util.Event;YAHOO.widget.TextNode=function(F,E,D){if(F){if(C.isString(F)){F={label:F};}this.init(F,E,D);this.setUpLabel(F);}};YAHOO.extend(YAHOO.widget.TextNode,YAHOO.widget.Node,{labelStyle:"ygtvlabel",labelElId:null,label:null,title:null,href:null,target:"_self",_type:"TextNode",setUpLabel:function(D){if(C.isString(D)){D={label:D};}else{if(D.style){this.labelStyle=D.style;}}this.label=D.label;this.labelElId="ygtvlabelel"+this.index;},getLabelEl:function(){return B.get(this.labelElId);},getContentHtml:function(){var D=[];D[D.length]=this.href?"<a":"<span";D[D.length]=' id="'+this.labelElId+'"';D[D.length]=' class="'+this.labelStyle+'"';if(this.href){D[D.length]=' href="'+this.href+'"';D[D.length]=' target="'+this.target+'"';}if(this.title){D[D.length]=' title="'+this.title+'"';}D[D.length]=" >";D[D.length]=this.label;D[D.length]=this.href?"</a>":"</span>";return D.join("");},getNodeDefinition:function(){var D=YAHOO.widget.TextNode.superclass.getNodeDefinition.call(this);if(D===false){return false;}D.label=this.label;if(this.labelStyle!="ygtvlabel"){D.style=this.labelStyle;}if(this.title){D.title=this.title;}if(this.href){D.href=this.href;}if(this.target!="_self"){D.target=this.target;}return D;},toString:function(){return YAHOO.widget.TextNode.superclass.toString.call(this)+": "+this.label;},onLabelClick:function(){return false;},refresh:function(){YAHOO.widget.TextNode.superclass.refresh.call(this);var D=this.getLabelEl();D.innerHTML=this.label;if(D.tagName.toUpperCase()=="A"){D.href=this.href;D.target=this.target;}}});})();YAHOO.widget.MenuNode=function(C,B,A){YAHOO.widget.MenuNode.superclass.constructor.call(this,C,B,A);this.multiExpand=false;};YAHOO.extend(YAHOO.widget.MenuNode,YAHOO.widget.TextNode,{_type:"MenuNode"});(function(){var B=YAHOO.util.Dom,C=YAHOO.lang,A=YAHOO.util.Event;YAHOO.widget.HTMLNode=function(G,F,E,D){if(G){this.init(G,F,E);this.initContent(G,D);}};YAHOO.extend(YAHOO.widget.HTMLNode,YAHOO.widget.Node,{contentStyle:"ygtvhtml",html:null,_type:"HTMLNode",initContent:function(E,D){this.setHtml(E);this.contentElId="ygtvcontentel"+this.index;if(!C.isUndefined(D)){this.hasIcon=D;}},setHtml:function(E){this.html=(typeof E==="string")?E:E.html;var D=this.getContentEl();if(D){D.innerHTML=this.html;}},getContentHtml:function(){return this.html;},getNodeDefinition:function(){var D=YAHOO.widget.HTMLNode.superclass.getNodeDefinition.call(this);if(D===false){return false;}D.html=this.html;return D;}});})();(function(){var B=YAHOO.util.Dom,C=YAHOO.lang,A=YAHOO.util.Event,D=YAHOO.widget.Calendar;YAHOO.widget.DateNode=function(G,F,E){YAHOO.widget.DateNode.superclass.constructor.call(this,G,F,E);};YAHOO.extend(YAHOO.widget.DateNode,YAHOO.widget.TextNode,{_type:"DateNode",calendarConfig:null,fillEditorContainer:function(G){var H,F=G.inputContainer;if(C.isUndefined(D)){B.replaceClass(G.editorPanel,"ygtv-edit-DateNode","ygtv-edit-TextNode");YAHOO.widget.DateNode.superclass.fillEditorContainer.call(this,G);return;}if(G.nodeType!=this._type){G.nodeType=this._type;G.saveOnEnter=false;G.node.destroyEditorContents(G);G.inputObject=H=new D(F.appendChild(document.createElement("div")));if(this.calendarConfig){H.cfg.applyConfig(this.calendarConfig,true);H.cfg.fireQueue();}H.selectEvent.subscribe(function(){this.tree._closeEditor(true);},this,true);}else{H=G.inputObject;}G.oldValue=this.label;H.cfg.setProperty("selected",this.label,false);var I=H.cfg.getProperty("DATE_FIELD_DELIMITER");var E=this.label.split(I);H.cfg.setProperty("pagedate",E[H.cfg.getProperty("MDY_MONTH_POSITION")-1]+I+E[H.cfg.getProperty("MDY_YEAR_POSITION")-1]);H.cfg.fireQueue();H.render();H.oDomContainer.focus();},getEditorValue:function(F){if(C.isUndefined(D)){return F.inputElement.value;}else{var H=F.inputObject,G=H.getSelectedDates()[0],E=[];E[H.cfg.getProperty("MDY_DAY_POSITION")-1]=G.getDate();E[H.cfg.getProperty("MDY_MONTH_POSITION")-1]=G.getMonth()+1;E[H.cfg.getProperty("MDY_YEAR_POSITION")-1]=G.getFullYear();return E.join(H.cfg.getProperty("DATE_FIELD_DELIMITER"));}},displayEditedValue:function(G,E){var F=E.node;F.label=G;F.getLabelEl().innerHTML=G;},getNodeDefinition:function(){var E=YAHOO.widget.DateNode.superclass.getNodeDefinition.call(this);if(E===false){return false;}if(this.calendarConfig){E.calendarConfig=this.calendarConfig;}return E;}});})();(function(){var E=YAHOO.util.Dom,F=YAHOO.lang,B=YAHOO.util.Event,D=YAHOO.widget.TreeView,C=D.prototype;D.editorData={active:false,whoHasIt:null,nodeType:null,editorPanel:null,inputContainer:null,buttonsContainer:null,node:null,saveOnEnter:true,oldValue:undefined};C.validator=null;C._initEditor=function(){this.createEvent("editorSaveEvent",this);this.createEvent("editorCancelEvent",this);};C._nodeEditing=function(M){if(M.fillEditorContainer&&M.editable){var I,K,L,J,H=D.editorData;H.active=true;H.whoHasIt=this;if(!H.nodeType){H.editorPanel=I=document.body.appendChild(document.createElement("div"));E.addClass(I,"ygtv-label-editor");L=H.buttonsContainer=I.appendChild(document.createElement("div"));E.addClass(L,"ygtv-button-container");J=L.appendChild(document.createElement("button"));
12
+ E.addClass(J,"ygtvok");J.innerHTML=" ";J=L.appendChild(document.createElement("button"));E.addClass(J,"ygtvcancel");J.innerHTML=" ";B.on(L,"click",function(O){var P=B.getTarget(O);var N=D.editorData.node;if(E.hasClass(P,"ygtvok")){B.stopEvent(O);this._closeEditor(true);}if(E.hasClass(P,"ygtvcancel")){B.stopEvent(O);this._closeEditor(false);}},this,true);H.inputContainer=I.appendChild(document.createElement("div"));E.addClass(H.inputContainer,"ygtv-input");B.on(I,"keydown",function(P){var O=D.editorData,N=YAHOO.util.KeyListener.KEY;switch(P.keyCode){case N.ENTER:B.stopEvent(P);if(O.saveOnEnter){this._closeEditor(true);}break;case N.ESCAPE:B.stopEvent(P);this._closeEditor(false);break;}},this,true);}else{I=H.editorPanel;}H.node=M;if(H.nodeType){E.removeClass(I,"ygtv-edit-"+H.nodeType);}E.addClass(I," ygtv-edit-"+M._type);K=E.getXY(M.getContentEl());E.setStyle(I,"left",K[0]+"px");E.setStyle(I,"top",K[1]+"px");E.setStyle(I,"display","block");I.focus();M.fillEditorContainer(H);return true;}};C.onEventEditNode=function(H){if(H instanceof YAHOO.widget.Node){H.editNode();}else{if(H.node instanceof YAHOO.widget.Node){H.node.editNode();}}};C._closeEditor=function(J){var H=D.editorData,I=H.node,K=true;if(J){K=H.node.saveEditorValue(H)!==false;}else{this.fireEvent("editorCancelEvent",I);}if(K){E.setStyle(H.editorPanel,"display","none");H.active=false;I.focus();}};C._destroyEditor=function(){var H=D.editorData;if(H&&H.nodeType&&(!H.active||H.whoHasIt===this)){B.removeListener(H.editorPanel,"keydown");B.removeListener(H.buttonContainer,"click");H.node.destroyEditorContents(H);document.body.removeChild(H.editorPanel);H.nodeType=H.editorPanel=H.inputContainer=H.buttonsContainer=H.whoHasIt=H.node=null;H.active=false;}};var G=YAHOO.widget.Node.prototype;G.editable=false;G.editNode=function(){this.tree._nodeEditing(this);};G.fillEditorContainer=null;G.destroyEditorContents=function(H){B.purgeElement(H.inputContainer,true);H.inputContainer.innerHTML="";};G.saveEditorValue=function(H){var J=H.node,K,I=J.tree.validator;K=this.getEditorValue(H);if(F.isFunction(I)){K=I(K,H.oldValue,J);if(F.isUndefined(K)){return false;}}if(this.tree.fireEvent("editorSaveEvent",{newValue:K,oldValue:H.oldValue,node:J})!==false){this.displayEditedValue(K,H);}};G.getEditorValue=function(H){};G.displayEditedValue=function(I,H){};var A=YAHOO.widget.TextNode.prototype;A.fillEditorContainer=function(I){var H;if(I.nodeType!=this._type){I.nodeType=this._type;I.saveOnEnter=true;I.node.destroyEditorContents(I);I.inputElement=H=I.inputContainer.appendChild(document.createElement("input"));}else{H=I.inputElement;}I.oldValue=this.label;H.value=this.label;H.focus();H.select();};A.getEditorValue=function(H){return H.inputElement.value;};A.displayEditedValue=function(J,H){var I=H.node;I.label=J;I.getLabelEl().innerHTML=J;};A.destroyEditorContents=function(H){H.inputContainer.innerHTML="";};})();YAHOO.widget.TVAnim=function(){return{FADE_IN:"TVFadeIn",FADE_OUT:"TVFadeOut",getAnim:function(B,A,C){if(YAHOO.widget[B]){return new YAHOO.widget[B](A,C);}else{return null;}},isValid:function(A){return(YAHOO.widget[A]);}};}();YAHOO.widget.TVFadeIn=function(A,B){this.el=A;this.callback=B;};YAHOO.widget.TVFadeIn.prototype={animate:function(){var D=this;var C=this.el.style;C.opacity=0.1;C.filter="alpha(opacity=10)";C.display="";var B=0.4;var A=new YAHOO.util.Anim(this.el,{opacity:{from:0.1,to:1,unit:""}},B);A.onComplete.subscribe(function(){D.onComplete();});A.animate();},onComplete:function(){this.callback();},toString:function(){return"TVFadeIn";}};YAHOO.widget.TVFadeOut=function(A,B){this.el=A;this.callback=B;};YAHOO.widget.TVFadeOut.prototype={animate:function(){var C=this;var B=0.4;var A=new YAHOO.util.Anim(this.el,{opacity:{from:1,to:0.1,unit:""}},B);A.onComplete.subscribe(function(){C.onComplete();});A.animate();},onComplete:function(){var A=this.el.style;A.display="none";A.opacity=1;A.filter="alpha(opacity=100)";this.callback();},toString:function(){return"TVFadeOut";}};YAHOO.register("treeview",YAHOO.widget.TreeView,{version:"2.8.1",build:"19"});
@@ -0,0 +1,3989 @@
1
+ /*
2
+ Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3
+ Code licensed under the BSD License:
4
+ http://developer.yahoo.com/yui/license.html
5
+ version: 2.8.1
6
+ */
7
+ (function () {
8
+ var Dom = YAHOO.util.Dom,
9
+ Event = YAHOO.util.Event,
10
+ Lang = YAHOO.lang,
11
+ Widget = YAHOO.widget;
12
+
13
+
14
+
15
+ /**
16
+ * The treeview widget is a generic tree building tool.
17
+ * @module treeview
18
+ * @title TreeView Widget
19
+ * @requires yahoo, dom, event
20
+ * @optional animation, json, calendar
21
+ * @namespace YAHOO.widget
22
+ */
23
+
24
+ /**
25
+ * Contains the tree view state data and the root node.
26
+ *
27
+ * @class TreeView
28
+ * @uses YAHOO.util.EventProvider
29
+ * @constructor
30
+ * @param {string|HTMLElement} id The id of the element, or the element itself that the tree will be inserted into.
31
+ * Existing markup in this element, if valid, will be used to build the tree
32
+ * @param {Array|Object|String} oConfig (optional) If present, it will be used to build the tree via method <a href="#method_buildTreeFromObject">buildTreeFromObject</a>
33
+ *
34
+ */
35
+ YAHOO.widget.TreeView = function(id, oConfig) {
36
+ if (id) { this.init(id); }
37
+ if (oConfig) {
38
+ this.buildTreeFromObject(oConfig);
39
+ } else if (Lang.trim(this._el.innerHTML)) {
40
+ this.buildTreeFromMarkup(id);
41
+ }
42
+ };
43
+
44
+ var TV = Widget.TreeView;
45
+
46
+ TV.prototype = {
47
+
48
+ /**
49
+ * The id of tree container element
50
+ * @property id
51
+ * @type String
52
+ */
53
+ id: null,
54
+
55
+ /**
56
+ * The host element for this tree
57
+ * @property _el
58
+ * @private
59
+ * @type HTMLelement
60
+ */
61
+ _el: null,
62
+
63
+ /**
64
+ * Flat collection of all nodes in this tree. This is a sparse
65
+ * array, so the length property can't be relied upon for a
66
+ * node count for the tree.
67
+ * @property _nodes
68
+ * @type Node[]
69
+ * @private
70
+ */
71
+ _nodes: null,
72
+
73
+ /**
74
+ * We lock the tree control while waiting for the dynamic loader to return
75
+ * @property locked
76
+ * @type boolean
77
+ */
78
+ locked: false,
79
+
80
+ /**
81
+ * The animation to use for expanding children, if any
82
+ * @property _expandAnim
83
+ * @type string
84
+ * @private
85
+ */
86
+ _expandAnim: null,
87
+
88
+ /**
89
+ * The animation to use for collapsing children, if any
90
+ * @property _collapseAnim
91
+ * @type string
92
+ * @private
93
+ */
94
+ _collapseAnim: null,
95
+
96
+ /**
97
+ * The current number of animations that are executing
98
+ * @property _animCount
99
+ * @type int
100
+ * @private
101
+ */
102
+ _animCount: 0,
103
+
104
+ /**
105
+ * The maximum number of animations to run at one time.
106
+ * @property maxAnim
107
+ * @type int
108
+ */
109
+ maxAnim: 2,
110
+
111
+ /**
112
+ * Whether there is any subscriber to dblClickEvent
113
+ * @property _hasDblClickSubscriber
114
+ * @type boolean
115
+ * @private
116
+ */
117
+ _hasDblClickSubscriber: false,
118
+
119
+ /**
120
+ * Stores the timer used to check for double clicks
121
+ * @property _dblClickTimer
122
+ * @type window.timer object
123
+ * @private
124
+ */
125
+ _dblClickTimer: null,
126
+
127
+ /**
128
+ * A reference to the Node currently having the focus or null if none.
129
+ * @property currentFocus
130
+ * @type YAHOO.widget.Node
131
+ */
132
+ currentFocus: null,
133
+
134
+ /**
135
+ * If true, only one Node can be highlighted at a time
136
+ * @property singleNodeHighlight
137
+ * @type boolean
138
+ * @default false
139
+ */
140
+
141
+ singleNodeHighlight: false,
142
+
143
+ /**
144
+ * A reference to the Node that is currently highlighted.
145
+ * It is only meaningful if singleNodeHighlight is enabled
146
+ * @property _currentlyHighlighted
147
+ * @type YAHOO.widget.Node
148
+ * @default null
149
+ * @private
150
+ */
151
+
152
+ _currentlyHighlighted: null,
153
+
154
+ /**
155
+ * Sets up the animation for expanding children
156
+ * @method setExpandAnim
157
+ * @param {string} type the type of animation (acceptable values defined
158
+ * in YAHOO.widget.TVAnim)
159
+ */
160
+ setExpandAnim: function(type) {
161
+ this._expandAnim = (Widget.TVAnim.isValid(type)) ? type : null;
162
+ },
163
+
164
+ /**
165
+ * Sets up the animation for collapsing children
166
+ * @method setCollapseAnim
167
+ * @param {string} type of animation (acceptable values defined in
168
+ * YAHOO.widget.TVAnim)
169
+ */
170
+ setCollapseAnim: function(type) {
171
+ this._collapseAnim = (Widget.TVAnim.isValid(type)) ? type : null;
172
+ },
173
+
174
+ /**
175
+ * Perform the expand animation if configured, or just show the
176
+ * element if not configured or too many animations are in progress
177
+ * @method animateExpand
178
+ * @param el {HTMLElement} the element to animate
179
+ * @param node {YAHOO.util.Node} the node that was expanded
180
+ * @return {boolean} true if animation could be invoked, false otherwise
181
+ */
182
+ animateExpand: function(el, node) {
183
+
184
+ if (this._expandAnim && this._animCount < this.maxAnim) {
185
+ // this.locked = true;
186
+ var tree = this;
187
+ var a = Widget.TVAnim.getAnim(this._expandAnim, el,
188
+ function() { tree.expandComplete(node); });
189
+ if (a) {
190
+ ++this._animCount;
191
+ this.fireEvent("animStart", {
192
+ "node": node,
193
+ "type": "expand"
194
+ });
195
+ a.animate();
196
+ }
197
+
198
+ return true;
199
+ }
200
+
201
+ return false;
202
+ },
203
+
204
+ /**
205
+ * Perform the collapse animation if configured, or just show the
206
+ * element if not configured or too many animations are in progress
207
+ * @method animateCollapse
208
+ * @param el {HTMLElement} the element to animate
209
+ * @param node {YAHOO.util.Node} the node that was expanded
210
+ * @return {boolean} true if animation could be invoked, false otherwise
211
+ */
212
+ animateCollapse: function(el, node) {
213
+
214
+ if (this._collapseAnim && this._animCount < this.maxAnim) {
215
+ // this.locked = true;
216
+ var tree = this;
217
+ var a = Widget.TVAnim.getAnim(this._collapseAnim, el,
218
+ function() { tree.collapseComplete(node); });
219
+ if (a) {
220
+ ++this._animCount;
221
+ this.fireEvent("animStart", {
222
+ "node": node,
223
+ "type": "collapse"
224
+ });
225
+ a.animate();
226
+ }
227
+
228
+ return true;
229
+ }
230
+
231
+ return false;
232
+ },
233
+
234
+ /**
235
+ * Function executed when the expand animation completes
236
+ * @method expandComplete
237
+ */
238
+ expandComplete: function(node) {
239
+ --this._animCount;
240
+ this.fireEvent("animComplete", {
241
+ "node": node,
242
+ "type": "expand"
243
+ });
244
+ // this.locked = false;
245
+ },
246
+
247
+ /**
248
+ * Function executed when the collapse animation completes
249
+ * @method collapseComplete
250
+ */
251
+ collapseComplete: function(node) {
252
+ --this._animCount;
253
+ this.fireEvent("animComplete", {
254
+ "node": node,
255
+ "type": "collapse"
256
+ });
257
+ // this.locked = false;
258
+ },
259
+
260
+ /**
261
+ * Initializes the tree
262
+ * @method init
263
+ * @parm {string|HTMLElement} id the id of the element that will hold the tree
264
+ * @private
265
+ */
266
+ init: function(id) {
267
+ this._el = Dom.get(id);
268
+ this.id = Dom.generateId(this._el,"yui-tv-auto-id-");
269
+
270
+ /**
271
+ * When animation is enabled, this event fires when the animation
272
+ * starts
273
+ * @event animStart
274
+ * @type CustomEvent
275
+ * @param {YAHOO.widget.Node} oArgs.node the node that is expanding/collapsing
276
+ * @param {String} oArgs.type the type of animation ("expand" or "collapse")
277
+ */
278
+ this.createEvent("animStart", this);
279
+
280
+ /**
281
+ * When animation is enabled, this event fires when the animation
282
+ * completes
283
+ * @event animComplete
284
+ * @type CustomEvent
285
+ * @param {YAHOO.widget.Node} oArgs.node the node that is expanding/collapsing
286
+ * @param {String} oArgs.type the type of animation ("expand" or "collapse")
287
+ */
288
+ this.createEvent("animComplete", this);
289
+
290
+ /**
291
+ * Fires when a node is going to be collapsed. Return false to stop
292
+ * the collapse.
293
+ * @event collapse
294
+ * @type CustomEvent
295
+ * @param {YAHOO.widget.Node} node the node that is collapsing
296
+ */
297
+ this.createEvent("collapse", this);
298
+
299
+ /**
300
+ * Fires after a node is successfully collapsed. This event will not fire
301
+ * if the "collapse" event was cancelled.
302
+ * @event collapseComplete
303
+ * @type CustomEvent
304
+ * @param {YAHOO.widget.Node} node the node that was collapsed
305
+ */
306
+ this.createEvent("collapseComplete", this);
307
+
308
+ /**
309
+ * Fires when a node is going to be expanded. Return false to stop
310
+ * the collapse.
311
+ * @event expand
312
+ * @type CustomEvent
313
+ * @param {YAHOO.widget.Node} node the node that is expanding
314
+ */
315
+ this.createEvent("expand", this);
316
+
317
+ /**
318
+ * Fires after a node is successfully expanded. This event will not fire
319
+ * if the "expand" event was cancelled.
320
+ * @event expandComplete
321
+ * @type CustomEvent
322
+ * @param {YAHOO.widget.Node} node the node that was expanded
323
+ */
324
+ this.createEvent("expandComplete", this);
325
+
326
+ /**
327
+ * Fires when the Enter key is pressed on a node that has the focus
328
+ * @event enterKeyPressed
329
+ * @type CustomEvent
330
+ * @param {YAHOO.widget.Node} node the node that has the focus
331
+ */
332
+ this.createEvent("enterKeyPressed", this);
333
+
334
+ /**
335
+ * Fires when the label in a TextNode or MenuNode or content in an HTMLNode receives a Click.
336
+ * The listener may return false to cancel toggling and focusing on the node.
337
+ * @event clickEvent
338
+ * @type CustomEvent
339
+ * @param oArgs.event {HTMLEvent} The event object
340
+ * @param oArgs.node {YAHOO.widget.Node} node the node that was clicked
341
+ */
342
+ this.createEvent("clickEvent", this);
343
+
344
+ /**
345
+ * Fires when the focus receives the focus, when it changes from a Node
346
+ * to another Node or when it is completely lost (blurred)
347
+ * @event focusChanged
348
+ * @type CustomEvent
349
+ * @param oArgs.oldNode {YAHOO.widget.Node} Node that had the focus or null if none
350
+ * @param oArgs.newNode {YAHOO.widget.Node} Node that receives the focus or null if none
351
+ */
352
+
353
+ this.createEvent('focusChanged',this);
354
+
355
+ /**
356
+ * Fires when the label in a TextNode or MenuNode or content in an HTMLNode receives a double Click
357
+ * @event dblClickEvent
358
+ * @type CustomEvent
359
+ * @param oArgs.event {HTMLEvent} The event object
360
+ * @param oArgs.node {YAHOO.widget.Node} node the node that was clicked
361
+ */
362
+ var self = this;
363
+ this.createEvent("dblClickEvent", {
364
+ scope:this,
365
+ onSubscribeCallback: function() {
366
+ self._hasDblClickSubscriber = true;
367
+ }
368
+ });
369
+
370
+ /**
371
+ * Custom event that is fired when the text node label is clicked.
372
+ * The node clicked is provided as an argument
373
+ *
374
+ * @event labelClick
375
+ * @type CustomEvent
376
+ * @param {YAHOO.widget.Node} node the node clicked
377
+ * @deprecated use clickEvent or dblClickEvent
378
+ */
379
+ this.createEvent("labelClick", this);
380
+
381
+ /**
382
+ * Custom event fired when the highlight of a node changes.
383
+ * The node that triggered the change is provided as an argument:
384
+ * The status of the highlight can be checked in
385
+ * <a href="YAHOO.widget.Node.html#property_highlightState">nodeRef.highlightState</a>.
386
+ * Depending on <a href="YAHOO.widget.Node.html#property_propagateHighlight">nodeRef.propagateHighlight</a>, other nodes might have changed
387
+ * @event highlightEvent
388
+ * @type CustomEvent
389
+ * @param node {YAHOO.widget.Node} the node that started the change in highlighting state
390
+ */
391
+ this.createEvent("highlightEvent",this);
392
+
393
+
394
+
395
+ this._nodes = [];
396
+
397
+ // store a global reference
398
+ TV.trees[this.id] = this;
399
+
400
+ // Set up the root node
401
+ this.root = new Widget.RootNode(this);
402
+
403
+ var LW = Widget.LogWriter;
404
+
405
+
406
+
407
+ if (this._initEditor) {
408
+ this._initEditor();
409
+ }
410
+
411
+ // YAHOO.util.Event.onContentReady(this.id, this.handleAvailable, this, true);
412
+ // YAHOO.util.Event.on(this.id, "click", this.handleClick, this, true);
413
+ },
414
+
415
+ //handleAvailable: function() {
416
+ //var Event = YAHOO.util.Event;
417
+ //Event.on(this.id,
418
+ //},
419
+ /**
420
+ * Builds the TreeView from an object.
421
+ * This is the method called by the constructor to build the tree when it has a second argument.
422
+ * A tree can be described by an array of objects, each object corresponding to a node.
423
+ * Node descriptions may contain values for any property of a node plus the following extra properties: <ul>
424
+ * <li>type: can be one of the following:<ul>
425
+ * <li> A shortname for a node type (<code>'text','menu','html'</code>) </li>
426
+ * <li>The name of a Node class under YAHOO.widget (<code>'TextNode', 'MenuNode', 'DateNode'</code>, etc) </li>
427
+ * <li>a reference to an actual class: <code>YAHOO.widget.DateNode</code></li>
428
+ * </ul></li>
429
+ * <li>children: an array containing further node definitions</li></ul>
430
+ * A string instead of an object will produce a node of type 'text' with the given string as its label.
431
+ * @method buildTreeFromObject
432
+ * @param oConfig {Array|Object|String} array containing a full description of the tree.
433
+ * An object or a string will be turned into an array with the given object or string as its only element.
434
+ *
435
+ */
436
+ buildTreeFromObject: function (oConfig) {
437
+ var build = function (parent, oConfig) {
438
+ var i, item, node, children, type, NodeType, ThisType;
439
+ for (i = 0; i < oConfig.length; i++) {
440
+ item = oConfig[i];
441
+ if (Lang.isString(item)) {
442
+ node = new Widget.TextNode(item, parent);
443
+ } else if (Lang.isObject(item)) {
444
+ children = item.children;
445
+ delete item.children;
446
+ type = item.type || 'text';
447
+ delete item.type;
448
+ switch (Lang.isString(type) && type.toLowerCase()) {
449
+ case 'text':
450
+ node = new Widget.TextNode(item, parent);
451
+ break;
452
+ case 'menu':
453
+ node = new Widget.MenuNode(item, parent);
454
+ break;
455
+ case 'html':
456
+ node = new Widget.HTMLNode(item, parent);
457
+ break;
458
+ default:
459
+ if (Lang.isString(type)) {
460
+ NodeType = Widget[type];
461
+ } else {
462
+ NodeType = type;
463
+ }
464
+ if (Lang.isObject(NodeType)) {
465
+ for (ThisType = NodeType; ThisType && ThisType !== Widget.Node; ThisType = ThisType.superclass.constructor) {}
466
+ if (ThisType) {
467
+ node = new NodeType(item, parent);
468
+ } else {
469
+ }
470
+ } else {
471
+ }
472
+ }
473
+ if (children) {
474
+ build(node,children);
475
+ }
476
+ } else {
477
+ }
478
+ }
479
+ };
480
+ if (!Lang.isArray(oConfig)) {
481
+ oConfig = [oConfig];
482
+ }
483
+
484
+
485
+ build(this.root,oConfig);
486
+ },
487
+ /**
488
+ * Builds the TreeView from existing markup. Markup should consist of &lt;UL&gt; or &lt;OL&gt; elements containing &lt;LI&gt; elements.
489
+ * Each &lt;LI&gt; can have one element used as label and a second optional element which is to be a &lt;UL&gt; or &lt;OL&gt;
490
+ * containing nested nodes.
491
+ * Depending on what the first element of the &lt;LI&gt; element is, the following Nodes will be created: <ul>
492
+ * <li>plain text: a regular TextNode</li>
493
+ * <li>anchor &lt;A&gt;: a TextNode with its <code>href</code> and <code>target</code> taken from the anchor</li>
494
+ * <li>anything else: an HTMLNode</li></ul>
495
+ * Only the first outermost (un-)ordered list in the markup and its children will be parsed.
496
+ * Nodes will be collapsed unless an &lt;LI&gt; tag has a className called 'expanded'.
497
+ * All other className attributes will be copied over to the Node className property.
498
+ * If the &lt;LI&gt; element contains an attribute called <code>yuiConfig</code>, its contents should be a JSON-encoded object
499
+ * as the one used in method <a href="#method_buildTreeFromObject">buildTreeFromObject</a>.
500
+ * @method buildTreeFromMarkup
501
+ * @param id {string|HTMLElement} The id of the element that contains the markup or a reference to it.
502
+ */
503
+ buildTreeFromMarkup: function (id) {
504
+ var build = function (markup) {
505
+ var el, child, branch = [], config = {}, label, yuiConfig;
506
+ // Dom's getFirstChild and getNextSibling skip over text elements
507
+ for (el = Dom.getFirstChild(markup); el; el = Dom.getNextSibling(el)) {
508
+ switch (el.tagName.toUpperCase()) {
509
+ case 'LI':
510
+ label = '';
511
+ config = {
512
+ expanded: Dom.hasClass(el,'expanded'),
513
+ title: el.title || el.alt || null,
514
+ className: Lang.trim(el.className.replace(/\bexpanded\b/,'')) || null
515
+ };
516
+ // I cannot skip over text elements here because I want them for labels
517
+ child = el.firstChild;
518
+ if (child.nodeType == 3) {
519
+ // nodes with only whitespace, tabs and new lines don't count, they are probably just formatting.
520
+ label = Lang.trim(child.nodeValue.replace(/[\n\t\r]*/g,''));
521
+ if (label) {
522
+ config.type = 'text';
523
+ config.label = label;
524
+ } else {
525
+ child = Dom.getNextSibling(child);
526
+ }
527
+ }
528
+ if (!label) {
529
+ if (child.tagName.toUpperCase() == 'A') {
530
+ config.type = 'text';
531
+ config.label = child.innerHTML;
532
+ config.href = child.href;
533
+ config.target = child.target;
534
+ config.title = child.title || child.alt || config.title;
535
+ } else {
536
+ config.type = 'html';
537
+ var d = document.createElement('div');
538
+ d.appendChild(child.cloneNode(true));
539
+ config.html = d.innerHTML;
540
+ config.hasIcon = true;
541
+ }
542
+ }
543
+ // see if after the label it has a further list which will become children of this node.
544
+ child = Dom.getNextSibling(child);
545
+ switch (child && child.tagName.toUpperCase()) {
546
+ case 'UL':
547
+ case 'OL':
548
+ config.children = build(child);
549
+ break;
550
+ }
551
+ // if there are further elements or text, it will be ignored.
552
+
553
+ if (YAHOO.lang.JSON) {
554
+ yuiConfig = el.getAttribute('yuiConfig');
555
+ if (yuiConfig) {
556
+ yuiConfig = YAHOO.lang.JSON.parse(yuiConfig);
557
+ config = YAHOO.lang.merge(config,yuiConfig);
558
+ }
559
+ }
560
+
561
+ branch.push(config);
562
+ break;
563
+ case 'UL':
564
+ case 'OL':
565
+ config = {
566
+ type: 'text',
567
+ label: '',
568
+ children: build(child)
569
+ };
570
+ branch.push(config);
571
+ break;
572
+ }
573
+ }
574
+ return branch;
575
+ };
576
+
577
+ var markup = Dom.getChildrenBy(Dom.get(id),function (el) {
578
+ var tag = el.tagName.toUpperCase();
579
+ return tag == 'UL' || tag == 'OL';
580
+ });
581
+ if (markup.length) {
582
+ this.buildTreeFromObject(build(markup[0]));
583
+ } else {
584
+ }
585
+ },
586
+ /**
587
+ * Returns the TD element where the event has occurred
588
+ * @method _getEventTargetTdEl
589
+ * @private
590
+ */
591
+ _getEventTargetTdEl: function (ev) {
592
+ var target = Event.getTarget(ev);
593
+ // go up looking for a TD with a className with a ygtv prefix
594
+ while (target && !(target.tagName.toUpperCase() == 'TD' && Dom.hasClass(target.parentNode,'ygtvrow'))) {
595
+ target = Dom.getAncestorByTagName(target,'td');
596
+ }
597
+ if (Lang.isNull(target)) { return null; }
598
+ // If it is a spacer cell, do nothing
599
+ if (/\bygtv(blank)?depthcell/.test(target.className)) { return null;}
600
+ // If it has an id, search for the node number and see if it belongs to a node in this tree.
601
+ if (target.id) {
602
+ var m = target.id.match(/\bygtv([^\d]*)(.*)/);
603
+ if (m && m[2] && this._nodes[m[2]]) {
604
+ return target;
605
+ }
606
+ }
607
+ return null;
608
+ },
609
+ /**
610
+ * Event listener for click events
611
+ * @method _onClickEvent
612
+ * @private
613
+ */
614
+ _onClickEvent: function (ev) {
615
+ var self = this,
616
+ td = this._getEventTargetTdEl(ev),
617
+ node,
618
+ target,
619
+ toggle = function (force) {
620
+ node.focus();
621
+ if (force || !node.href) {
622
+ node.toggle();
623
+ try {
624
+ Event.preventDefault(ev);
625
+ } catch (e) {
626
+ // @TODO
627
+ // For some reason IE8 is providing an event object with
628
+ // most of the fields missing, but only when clicking on
629
+ // the node's label, and only when working with inline
630
+ // editing. This generates a "Member not found" error
631
+ // in that browser. Determine if this is a browser
632
+ // bug, or a problem with this code. Already checked to
633
+ // see if the problem has to do with access the event
634
+ // in the outer scope, and that isn't the problem.
635
+ // Maybe the markup for inline editing is broken.
636
+ }
637
+ }
638
+ };
639
+
640
+ if (!td) {
641
+ return;
642
+ }
643
+
644
+ node = this.getNodeByElement(td);
645
+ if (!node) {
646
+ return;
647
+ }
648
+
649
+ // exception to handle deprecated event labelClick
650
+ // @TODO take another look at this deprecation. It is common for people to
651
+ // only be interested in the label click, so why make them have to test
652
+ // the node type to figure out whether the click was on the label?
653
+ target = Event.getTarget(ev);
654
+ if (Dom.hasClass(target, node.labelStyle) || Dom.getAncestorByClassName(target,node.labelStyle)) {
655
+ this.fireEvent('labelClick',node);
656
+ }
657
+
658
+ // If it is a toggle cell, toggle
659
+ if (/\bygtv[tl][mp]h?h?/.test(td.className)) {
660
+ toggle(true);
661
+ } else {
662
+ if (this._dblClickTimer) {
663
+ window.clearTimeout(this._dblClickTimer);
664
+ this._dblClickTimer = null;
665
+ } else {
666
+ if (this._hasDblClickSubscriber) {
667
+ this._dblClickTimer = window.setTimeout(function () {
668
+ self._dblClickTimer = null;
669
+ if (self.fireEvent('clickEvent', {event:ev,node:node}) !== false) {
670
+ toggle();
671
+ }
672
+ }, 200);
673
+ } else {
674
+ if (self.fireEvent('clickEvent', {event:ev,node:node}) !== false) {
675
+ toggle();
676
+ }
677
+ }
678
+ }
679
+ }
680
+ },
681
+
682
+ /**
683
+ * Event listener for double-click events
684
+ * @method _onDblClickEvent
685
+ * @private
686
+ */
687
+ _onDblClickEvent: function (ev) {
688
+ if (!this._hasDblClickSubscriber) { return; }
689
+ var td = this._getEventTargetTdEl(ev);
690
+ if (!td) {return;}
691
+
692
+ if (!(/\bygtv[tl][mp]h?h?/.test(td.className))) {
693
+ this.fireEvent('dblClickEvent', {event:ev, node:this.getNodeByElement(td)});
694
+ if (this._dblClickTimer) {
695
+ window.clearTimeout(this._dblClickTimer);
696
+ this._dblClickTimer = null;
697
+ }
698
+ }
699
+ },
700
+ /**
701
+ * Event listener for mouse over events
702
+ * @method _onMouseOverEvent
703
+ * @private
704
+ */
705
+ _onMouseOverEvent:function (ev) {
706
+ var target;
707
+ if ((target = this._getEventTargetTdEl(ev)) && (target = this.getNodeByElement(target)) && (target = target.getToggleEl())) {
708
+ target.className = target.className.replace(/\bygtv([lt])([mp])\b/gi,'ygtv$1$2h');
709
+ }
710
+ },
711
+ /**
712
+ * Event listener for mouse out events
713
+ * @method _onMouseOutEvent
714
+ * @private
715
+ */
716
+ _onMouseOutEvent: function (ev) {
717
+ var target;
718
+ if ((target = this._getEventTargetTdEl(ev)) && (target = this.getNodeByElement(target)) && (target = target.getToggleEl())) {
719
+ target.className = target.className.replace(/\bygtv([lt])([mp])h\b/gi,'ygtv$1$2');
720
+ }
721
+ },
722
+ /**
723
+ * Event listener for key down events
724
+ * @method _onKeyDownEvent
725
+ * @private
726
+ */
727
+ _onKeyDownEvent: function (ev) {
728
+ var target = Event.getTarget(ev),
729
+ node = this.getNodeByElement(target),
730
+ newNode = node,
731
+ KEY = YAHOO.util.KeyListener.KEY;
732
+
733
+ switch(ev.keyCode) {
734
+ case KEY.UP:
735
+ do {
736
+ if (newNode.previousSibling) {
737
+ newNode = newNode.previousSibling;
738
+ } else {
739
+ newNode = newNode.parent;
740
+ }
741
+ } while (newNode && !newNode._canHaveFocus());
742
+ if (newNode) { newNode.focus(); }
743
+ Event.preventDefault(ev);
744
+ break;
745
+ case KEY.DOWN:
746
+ do {
747
+ if (newNode.nextSibling) {
748
+ newNode = newNode.nextSibling;
749
+ } else {
750
+ newNode.expand();
751
+ newNode = (newNode.children.length || null) && newNode.children[0];
752
+ }
753
+ } while (newNode && !newNode._canHaveFocus);
754
+ if (newNode) { newNode.focus();}
755
+ Event.preventDefault(ev);
756
+ break;
757
+ case KEY.LEFT:
758
+ do {
759
+ if (newNode.parent) {
760
+ newNode = newNode.parent;
761
+ } else {
762
+ newNode = newNode.previousSibling;
763
+ }
764
+ } while (newNode && !newNode._canHaveFocus());
765
+ if (newNode) { newNode.focus();}
766
+ Event.preventDefault(ev);
767
+ break;
768
+ case KEY.RIGHT:
769
+ var self = this,
770
+ moveFocusRight,
771
+ focusOnExpand = function (newNode) {
772
+ self.unsubscribe('expandComplete',focusOnExpand);
773
+ moveFocusRight(newNode);
774
+ };
775
+ moveFocusRight = function (newNode) {
776
+ do {
777
+ if (newNode.isDynamic() && !newNode.childrenRendered) {
778
+ self.subscribe('expandComplete',focusOnExpand);
779
+ newNode.expand();
780
+ newNode = null;
781
+ break;
782
+ } else {
783
+ newNode.expand();
784
+ if (newNode.children.length) {
785
+ newNode = newNode.children[0];
786
+ } else {
787
+ newNode = newNode.nextSibling;
788
+ }
789
+ }
790
+ } while (newNode && !newNode._canHaveFocus());
791
+ if (newNode) { newNode.focus();}
792
+ };
793
+
794
+ moveFocusRight(newNode);
795
+ Event.preventDefault(ev);
796
+ break;
797
+ case KEY.ENTER:
798
+ if (node.href) {
799
+ if (node.target) {
800
+ window.open(node.href,node.target);
801
+ } else {
802
+ window.location(node.href);
803
+ }
804
+ } else {
805
+ node.toggle();
806
+ }
807
+ this.fireEvent('enterKeyPressed',node);
808
+ Event.preventDefault(ev);
809
+ break;
810
+ case KEY.HOME:
811
+ newNode = this.getRoot();
812
+ if (newNode.children.length) {newNode = newNode.children[0];}
813
+ if (newNode._canHaveFocus()) { newNode.focus(); }
814
+ Event.preventDefault(ev);
815
+ break;
816
+ case KEY.END:
817
+ newNode = newNode.parent.children;
818
+ newNode = newNode[newNode.length -1];
819
+ if (newNode._canHaveFocus()) { newNode.focus(); }
820
+ Event.preventDefault(ev);
821
+ break;
822
+ // case KEY.PAGE_UP:
823
+ // break;
824
+ // case KEY.PAGE_DOWN:
825
+ // break;
826
+ case 107: // plus key
827
+ if (ev.shiftKey) {
828
+ node.parent.expandAll();
829
+ } else {
830
+ node.expand();
831
+ }
832
+ break;
833
+ case 109: // minus key
834
+ if (ev.shiftKey) {
835
+ node.parent.collapseAll();
836
+ } else {
837
+ node.collapse();
838
+ }
839
+ break;
840
+ default:
841
+ break;
842
+ }
843
+ },
844
+ /**
845
+ * Renders the tree boilerplate and visible nodes
846
+ * @method render
847
+ */
848
+ render: function() {
849
+ var html = this.root.getHtml(),
850
+ el = this.getEl();
851
+ el.innerHTML = html;
852
+ if (!this._hasEvents) {
853
+ Event.on(el, 'click', this._onClickEvent, this, true);
854
+ Event.on(el, 'dblclick', this._onDblClickEvent, this, true);
855
+ Event.on(el, 'mouseover', this._onMouseOverEvent, this, true);
856
+ Event.on(el, 'mouseout', this._onMouseOutEvent, this, true);
857
+ Event.on(el, 'keydown', this._onKeyDownEvent, this, true);
858
+ }
859
+ this._hasEvents = true;
860
+ },
861
+
862
+ /**
863
+ * Returns the tree's host element
864
+ * @method getEl
865
+ * @return {HTMLElement} the host element
866
+ */
867
+ getEl: function() {
868
+ if (! this._el) {
869
+ this._el = Dom.get(this.id);
870
+ }
871
+ return this._el;
872
+ },
873
+
874
+ /**
875
+ * Nodes register themselves with the tree instance when they are created.
876
+ * @method regNode
877
+ * @param node {Node} the node to register
878
+ * @private
879
+ */
880
+ regNode: function(node) {
881
+ this._nodes[node.index] = node;
882
+ },
883
+
884
+ /**
885
+ * Returns the root node of this tree
886
+ * @method getRoot
887
+ * @return {Node} the root node
888
+ */
889
+ getRoot: function() {
890
+ return this.root;
891
+ },
892
+
893
+ /**
894
+ * Configures this tree to dynamically load all child data
895
+ * @method setDynamicLoad
896
+ * @param {function} fnDataLoader the function that will be called to get the data
897
+ * @param iconMode {int} configures the icon that is displayed when a dynamic
898
+ * load node is expanded the first time without children. By default, the
899
+ * "collapse" icon will be used. If set to 1, the leaf node icon will be
900
+ * displayed.
901
+ */
902
+ setDynamicLoad: function(fnDataLoader, iconMode) {
903
+ this.root.setDynamicLoad(fnDataLoader, iconMode);
904
+ },
905
+
906
+ /**
907
+ * Expands all child nodes. Note: this conflicts with the "multiExpand"
908
+ * node property. If expand all is called in a tree with nodes that
909
+ * do not allow multiple siblings to be displayed, only the last sibling
910
+ * will be expanded.
911
+ * @method expandAll
912
+ */
913
+ expandAll: function() {
914
+ if (!this.locked) {
915
+ this.root.expandAll();
916
+ }
917
+ },
918
+
919
+ /**
920
+ * Collapses all expanded child nodes in the entire tree.
921
+ * @method collapseAll
922
+ */
923
+ collapseAll: function() {
924
+ if (!this.locked) {
925
+ this.root.collapseAll();
926
+ }
927
+ },
928
+
929
+ /**
930
+ * Returns a node in the tree that has the specified index (this index
931
+ * is created internally, so this function probably will only be used
932
+ * in html generated for a given node.)
933
+ * @method getNodeByIndex
934
+ * @param {int} nodeIndex the index of the node wanted
935
+ * @return {Node} the node with index=nodeIndex, null if no match
936
+ */
937
+ getNodeByIndex: function(nodeIndex) {
938
+ var n = this._nodes[nodeIndex];
939
+ return (n) ? n : null;
940
+ },
941
+
942
+ /**
943
+ * Returns a node that has a matching property and value in the data
944
+ * object that was passed into its constructor.
945
+ * @method getNodeByProperty
946
+ * @param {object} property the property to search (usually a string)
947
+ * @param {object} value the value we want to find (usuall an int or string)
948
+ * @return {Node} the matching node, null if no match
949
+ */
950
+ getNodeByProperty: function(property, value) {
951
+ for (var i in this._nodes) {
952
+ if (this._nodes.hasOwnProperty(i)) {
953
+ var n = this._nodes[i];
954
+ if ((property in n && n[property] == value) || (n.data && value == n.data[property])) {
955
+ return n;
956
+ }
957
+ }
958
+ }
959
+
960
+ return null;
961
+ },
962
+
963
+ /**
964
+ * Returns a collection of nodes that have a matching property
965
+ * and value in the data object that was passed into its constructor.
966
+ * @method getNodesByProperty
967
+ * @param {object} property the property to search (usually a string)
968
+ * @param {object} value the value we want to find (usuall an int or string)
969
+ * @return {Array} the matching collection of nodes, null if no match
970
+ */
971
+ getNodesByProperty: function(property, value) {
972
+ var values = [];
973
+ for (var i in this._nodes) {
974
+ if (this._nodes.hasOwnProperty(i)) {
975
+ var n = this._nodes[i];
976
+ if ((property in n && n[property] == value) || (n.data && value == n.data[property])) {
977
+ values.push(n);
978
+ }
979
+ }
980
+ }
981
+
982
+ return (values.length) ? values : null;
983
+ },
984
+
985
+
986
+ /**
987
+ * Returns a collection of nodes that have passed the test function
988
+ * passed as its only argument.
989
+ * The function will receive a reference to each node to be tested.
990
+ * @method getNodesBy
991
+ * @param {function} a boolean function that receives a Node instance and returns true to add the node to the results list
992
+ * @return {Array} the matching collection of nodes, null if no match
993
+ */
994
+ getNodesBy: function(fn) {
995
+ var values = [];
996
+ for (var i in this._nodes) {
997
+ if (this._nodes.hasOwnProperty(i)) {
998
+ var n = this._nodes[i];
999
+ if (fn(n)) {
1000
+ values.push(n);
1001
+ }
1002
+ }
1003
+ }
1004
+ return (values.length) ? values : null;
1005
+ },
1006
+ /**
1007
+ * Returns the treeview node reference for an ancestor element
1008
+ * of the node, or null if it is not contained within any node
1009
+ * in this tree.
1010
+ * @method getNodeByElement
1011
+ * @param el {HTMLElement} the element to test
1012
+ * @return {YAHOO.widget.Node} a node reference or null
1013
+ */
1014
+ getNodeByElement: function(el) {
1015
+
1016
+ var p=el, m, re=/ygtv([^\d]*)(.*)/;
1017
+
1018
+ do {
1019
+
1020
+ if (p && p.id) {
1021
+ m = p.id.match(re);
1022
+ if (m && m[2]) {
1023
+ return this.getNodeByIndex(m[2]);
1024
+ }
1025
+ }
1026
+
1027
+ p = p.parentNode;
1028
+
1029
+ if (!p || !p.tagName) {
1030
+ break;
1031
+ }
1032
+
1033
+ }
1034
+ while (p.id !== this.id && p.tagName.toLowerCase() !== "body");
1035
+
1036
+ return null;
1037
+ },
1038
+
1039
+ /**
1040
+ * When in singleNodeHighlight it returns the node highlighted
1041
+ * or null if none. Returns null if singleNodeHighlight is false.
1042
+ * @method getHighlightedNode
1043
+ * @return {YAHOO.widget.Node} a node reference or null
1044
+ */
1045
+ getHighlightedNode: function() {
1046
+ return this._currentlyHighlighted;
1047
+ },
1048
+
1049
+
1050
+ /**
1051
+ * Removes the node and its children, and optionally refreshes the
1052
+ * branch of the tree that was affected.
1053
+ * @method removeNode
1054
+ * @param {Node} node to remove
1055
+ * @param {boolean} autoRefresh automatically refreshes branch if true
1056
+ * @return {boolean} False is there was a problem, true otherwise.
1057
+ */
1058
+ removeNode: function(node, autoRefresh) {
1059
+
1060
+ // Don't delete the root node
1061
+ if (node.isRoot()) {
1062
+ return false;
1063
+ }
1064
+
1065
+ // Get the branch that we may need to refresh
1066
+ var p = node.parent;
1067
+ if (p.parent) {
1068
+ p = p.parent;
1069
+ }
1070
+
1071
+ // Delete the node and its children
1072
+ this._deleteNode(node);
1073
+
1074
+ // Refresh the parent of the parent
1075
+ if (autoRefresh && p && p.childrenRendered) {
1076
+ p.refresh();
1077
+ }
1078
+
1079
+ return true;
1080
+ },
1081
+
1082
+ /**
1083
+ * wait until the animation is complete before deleting
1084
+ * to avoid javascript errors
1085
+ * @method _removeChildren_animComplete
1086
+ * @param o the custom event payload
1087
+ * @private
1088
+ */
1089
+ _removeChildren_animComplete: function(o) {
1090
+ this.unsubscribe(this._removeChildren_animComplete);
1091
+ this.removeChildren(o.node);
1092
+ },
1093
+
1094
+ /**
1095
+ * Deletes this nodes child collection, recursively. Also collapses
1096
+ * the node, and resets the dynamic load flag. The primary use for
1097
+ * this method is to purge a node and allow it to fetch its data
1098
+ * dynamically again.
1099
+ * @method removeChildren
1100
+ * @param {Node} node the node to purge
1101
+ */
1102
+ removeChildren: function(node) {
1103
+
1104
+ if (node.expanded) {
1105
+ // wait until the animation is complete before deleting to
1106
+ // avoid javascript errors
1107
+ if (this._collapseAnim) {
1108
+ this.subscribe("animComplete",
1109
+ this._removeChildren_animComplete, this, true);
1110
+ Widget.Node.prototype.collapse.call(node);
1111
+ return;
1112
+ }
1113
+
1114
+ node.collapse();
1115
+ }
1116
+
1117
+ while (node.children.length) {
1118
+ this._deleteNode(node.children[0]);
1119
+ }
1120
+
1121
+ if (node.isRoot()) {
1122
+ Widget.Node.prototype.expand.call(node);
1123
+ }
1124
+
1125
+ node.childrenRendered = false;
1126
+ node.dynamicLoadComplete = false;
1127
+
1128
+ node.updateIcon();
1129
+ },
1130
+
1131
+ /**
1132
+ * Deletes the node and recurses children
1133
+ * @method _deleteNode
1134
+ * @private
1135
+ */
1136
+ _deleteNode: function(node) {
1137
+ // Remove all the child nodes first
1138
+ this.removeChildren(node);
1139
+
1140
+ // Remove the node from the tree
1141
+ this.popNode(node);
1142
+ },
1143
+
1144
+ /**
1145
+ * Removes the node from the tree, preserving the child collection
1146
+ * to make it possible to insert the branch into another part of the
1147
+ * tree, or another tree.
1148
+ * @method popNode
1149
+ * @param {Node} node to remove
1150
+ */
1151
+ popNode: function(node) {
1152
+ var p = node.parent;
1153
+
1154
+ // Update the parent's collection of children
1155
+ var a = [];
1156
+
1157
+ for (var i=0, len=p.children.length;i<len;++i) {
1158
+ if (p.children[i] != node) {
1159
+ a[a.length] = p.children[i];
1160
+ }
1161
+ }
1162
+
1163
+ p.children = a;
1164
+
1165
+ // reset the childrenRendered flag for the parent
1166
+ p.childrenRendered = false;
1167
+
1168
+ // Update the sibling relationship
1169
+ if (node.previousSibling) {
1170
+ node.previousSibling.nextSibling = node.nextSibling;
1171
+ }
1172
+
1173
+ if (node.nextSibling) {
1174
+ node.nextSibling.previousSibling = node.previousSibling;
1175
+ }
1176
+
1177
+ if (this.currentFocus == node) {
1178
+ this.currentFocus = null;
1179
+ }
1180
+ if (this._currentlyHighlighted == node) {
1181
+ this._currentlyHighlighted = null;
1182
+ }
1183
+
1184
+ node.parent = null;
1185
+ node.previousSibling = null;
1186
+ node.nextSibling = null;
1187
+ node.tree = null;
1188
+
1189
+ // Update the tree's node collection
1190
+ delete this._nodes[node.index];
1191
+ },
1192
+
1193
+ /**
1194
+ * Nulls out the entire TreeView instance and related objects, removes attached
1195
+ * event listeners, and clears out DOM elements inside the container. After
1196
+ * calling this method, the instance reference should be expliclitly nulled by
1197
+ * implementer, as in myDataTable = null. Use with caution!
1198
+ *
1199
+ * @method destroy
1200
+ */
1201
+ destroy : function() {
1202
+ // Since the label editor can be separated from the main TreeView control
1203
+ // the destroy method for it might not be there.
1204
+ if (this._destroyEditor) { this._destroyEditor(); }
1205
+ var el = this.getEl();
1206
+ Event.removeListener(el,'click');
1207
+ Event.removeListener(el,'dblclick');
1208
+ Event.removeListener(el,'mouseover');
1209
+ Event.removeListener(el,'mouseout');
1210
+ Event.removeListener(el,'keydown');
1211
+ for (var i = 0 ; i < this._nodes.length; i++) {
1212
+ var node = this._nodes[i];
1213
+ if (node && node.destroy) {node.destroy(); }
1214
+ }
1215
+ el.innerHTML = '';
1216
+ this._hasEvents = false;
1217
+ },
1218
+
1219
+
1220
+
1221
+
1222
+ /**
1223
+ * TreeView instance toString
1224
+ * @method toString
1225
+ * @return {string} string representation of the tree
1226
+ */
1227
+ toString: function() {
1228
+ return "TreeView " + this.id;
1229
+ },
1230
+
1231
+ /**
1232
+ * Count of nodes in tree
1233
+ * @method getNodeCount
1234
+ * @return {int} number of nodes in the tree
1235
+ */
1236
+ getNodeCount: function() {
1237
+ return this.getRoot().getNodeCount();
1238
+ },
1239
+
1240
+ /**
1241
+ * Returns an object which could be used to rebuild the tree.
1242
+ * It can be passed to the tree constructor to reproduce the same tree.
1243
+ * It will return false if any node loads dynamically, regardless of whether it is loaded or not.
1244
+ * @method getTreeDefinition
1245
+ * @return {Object | false} definition of the tree or false if any node is defined as dynamic
1246
+ */
1247
+ getTreeDefinition: function() {
1248
+ return this.getRoot().getNodeDefinition();
1249
+ },
1250
+
1251
+ /**
1252
+ * Abstract method that is executed when a node is expanded
1253
+ * @method onExpand
1254
+ * @param node {Node} the node that was expanded
1255
+ * @deprecated use treeobj.subscribe("expand") instead
1256
+ */
1257
+ onExpand: function(node) { },
1258
+
1259
+ /**
1260
+ * Abstract method that is executed when a node is collapsed.
1261
+ * @method onCollapse
1262
+ * @param node {Node} the node that was collapsed.
1263
+ * @deprecated use treeobj.subscribe("collapse") instead
1264
+ */
1265
+ onCollapse: function(node) { },
1266
+
1267
+ /**
1268
+ * Sets the value of a property for all loaded nodes in the tree.
1269
+ * @method setNodesProperty
1270
+ * @param name {string} Name of the property to be set
1271
+ * @param value {any} value to be set
1272
+ * @param refresh {boolean} if present and true, it does a refresh
1273
+ */
1274
+ setNodesProperty: function(name, value, refresh) {
1275
+ this.root.setNodesProperty(name,value);
1276
+ if (refresh) {
1277
+ this.root.refresh();
1278
+ }
1279
+ },
1280
+ /**
1281
+ * Event listener to toggle node highlight.
1282
+ * Can be assigned as listener to clickEvent, dblClickEvent and enterKeyPressed.
1283
+ * It returns false to prevent the default action.
1284
+ * @method onEventToggleHighlight
1285
+ * @param oArgs {any} it takes the arguments of any of the events mentioned above
1286
+ * @return {false} Always cancels the default action for the event
1287
+ */
1288
+ onEventToggleHighlight: function (oArgs) {
1289
+ var node;
1290
+ if ('node' in oArgs && oArgs.node instanceof Widget.Node) {
1291
+ node = oArgs.node;
1292
+ } else if (oArgs instanceof Widget.Node) {
1293
+ node = oArgs;
1294
+ } else {
1295
+ return false;
1296
+ }
1297
+ node.toggleHighlight();
1298
+ return false;
1299
+ }
1300
+
1301
+
1302
+ };
1303
+
1304
+ /* Backwards compatibility aliases */
1305
+ var PROT = TV.prototype;
1306
+ /**
1307
+ * Renders the tree boilerplate and visible nodes.
1308
+ * Alias for render
1309
+ * @method draw
1310
+ * @deprecated Use render instead
1311
+ */
1312
+ PROT.draw = PROT.render;
1313
+
1314
+ /* end backwards compatibility aliases */
1315
+
1316
+ YAHOO.augment(TV, YAHOO.util.EventProvider);
1317
+
1318
+ /**
1319
+ * Running count of all nodes created in all trees. This is
1320
+ * used to provide unique identifies for all nodes. Deleting
1321
+ * nodes does not change the nodeCount.
1322
+ * @property YAHOO.widget.TreeView.nodeCount
1323
+ * @type int
1324
+ * @static
1325
+ */
1326
+ TV.nodeCount = 0;
1327
+
1328
+ /**
1329
+ * Global cache of tree instances
1330
+ * @property YAHOO.widget.TreeView.trees
1331
+ * @type Array
1332
+ * @static
1333
+ * @private
1334
+ */
1335
+ TV.trees = [];
1336
+
1337
+ /**
1338
+ * Global method for getting a tree by its id. Used in the generated
1339
+ * tree html.
1340
+ * @method YAHOO.widget.TreeView.getTree
1341
+ * @param treeId {String} the id of the tree instance
1342
+ * @return {TreeView} the tree instance requested, null if not found.
1343
+ * @static
1344
+ */
1345
+ TV.getTree = function(treeId) {
1346
+ var t = TV.trees[treeId];
1347
+ return (t) ? t : null;
1348
+ };
1349
+
1350
+
1351
+ /**
1352
+ * Global method for getting a node by its id. Used in the generated
1353
+ * tree html.
1354
+ * @method YAHOO.widget.TreeView.getNode
1355
+ * @param treeId {String} the id of the tree instance
1356
+ * @param nodeIndex {String} the index of the node to return
1357
+ * @return {Node} the node instance requested, null if not found
1358
+ * @static
1359
+ */
1360
+ TV.getNode = function(treeId, nodeIndex) {
1361
+ var t = TV.getTree(treeId);
1362
+ return (t) ? t.getNodeByIndex(nodeIndex) : null;
1363
+ };
1364
+
1365
+
1366
+ /**
1367
+ * Class name assigned to elements that have the focus
1368
+ *
1369
+ * @property TreeView.FOCUS_CLASS_NAME
1370
+ * @type String
1371
+ * @static
1372
+ * @final
1373
+ * @default "ygtvfocus"
1374
+
1375
+ */
1376
+ TV.FOCUS_CLASS_NAME = 'ygtvfocus';
1377
+
1378
+
1379
+
1380
+ })();
1381
+
1382
+ (function () {
1383
+ var Dom = YAHOO.util.Dom,
1384
+ Lang = YAHOO.lang,
1385
+ Event = YAHOO.util.Event;
1386
+ /**
1387
+ * The base class for all tree nodes. The node's presentation and behavior in
1388
+ * response to mouse events is handled in Node subclasses.
1389
+ * @namespace YAHOO.widget
1390
+ * @class Node
1391
+ * @uses YAHOO.util.EventProvider
1392
+ * @param oData {object} a string or object containing the data that will
1393
+ * be used to render this node, and any custom attributes that should be
1394
+ * stored with the node (which is available in noderef.data).
1395
+ * All values in oData will be used to set equally named properties in the node
1396
+ * as long as the node does have such properties, they are not undefined, private or functions,
1397
+ * the rest of the values will be stored in noderef.data
1398
+ * @param oParent {Node} this node's parent node
1399
+ * @param expanded {boolean} the initial expanded/collapsed state (deprecated, use oData.expanded)
1400
+ * @constructor
1401
+ */
1402
+ YAHOO.widget.Node = function(oData, oParent, expanded) {
1403
+ if (oData) { this.init(oData, oParent, expanded); }
1404
+ };
1405
+
1406
+ YAHOO.widget.Node.prototype = {
1407
+
1408
+ /**
1409
+ * The index for this instance obtained from global counter in YAHOO.widget.TreeView.
1410
+ * @property index
1411
+ * @type int
1412
+ */
1413
+ index: 0,
1414
+
1415
+ /**
1416
+ * This node's child node collection.
1417
+ * @property children
1418
+ * @type Node[]
1419
+ */
1420
+ children: null,
1421
+
1422
+ /**
1423
+ * Tree instance this node is part of
1424
+ * @property tree
1425
+ * @type TreeView
1426
+ */
1427
+ tree: null,
1428
+
1429
+ /**
1430
+ * The data linked to this node. This can be any object or primitive
1431
+ * value, and the data can be used in getNodeHtml().
1432
+ * @property data
1433
+ * @type object
1434
+ */
1435
+ data: null,
1436
+
1437
+ /**
1438
+ * Parent node
1439
+ * @property parent
1440
+ * @type Node
1441
+ */
1442
+ parent: null,
1443
+
1444
+ /**
1445
+ * The depth of this node. We start at -1 for the root node.
1446
+ * @property depth
1447
+ * @type int
1448
+ */
1449
+ depth: -1,
1450
+
1451
+ /**
1452
+ * The node's expanded/collapsed state
1453
+ * @property expanded
1454
+ * @type boolean
1455
+ */
1456
+ expanded: false,
1457
+
1458
+ /**
1459
+ * Can multiple children be expanded at once?
1460
+ * @property multiExpand
1461
+ * @type boolean
1462
+ */
1463
+ multiExpand: true,
1464
+
1465
+ /**
1466
+ * Should we render children for a collapsed node? It is possible that the
1467
+ * implementer will want to render the hidden data... @todo verify that we
1468
+ * need this, and implement it if we do.
1469
+ * @property renderHidden
1470
+ * @type boolean
1471
+ */
1472
+ renderHidden: false,
1473
+
1474
+ /**
1475
+ * This flag is set to true when the html is generated for this node's
1476
+ * children, and set to false when new children are added.
1477
+ * @property childrenRendered
1478
+ * @type boolean
1479
+ */
1480
+ childrenRendered: false,
1481
+
1482
+ /**
1483
+ * Dynamically loaded nodes only fetch the data the first time they are
1484
+ * expanded. This flag is set to true once the data has been fetched.
1485
+ * @property dynamicLoadComplete
1486
+ * @type boolean
1487
+ */
1488
+ dynamicLoadComplete: false,
1489
+
1490
+ /**
1491
+ * This node's previous sibling
1492
+ * @property previousSibling
1493
+ * @type Node
1494
+ */
1495
+ previousSibling: null,
1496
+
1497
+ /**
1498
+ * This node's next sibling
1499
+ * @property nextSibling
1500
+ * @type Node
1501
+ */
1502
+ nextSibling: null,
1503
+
1504
+ /**
1505
+ * We can set the node up to call an external method to get the child
1506
+ * data dynamically.
1507
+ * @property _dynLoad
1508
+ * @type boolean
1509
+ * @private
1510
+ */
1511
+ _dynLoad: false,
1512
+
1513
+ /**
1514
+ * Function to execute when we need to get this node's child data.
1515
+ * @property dataLoader
1516
+ * @type function
1517
+ */
1518
+ dataLoader: null,
1519
+
1520
+ /**
1521
+ * This is true for dynamically loading nodes while waiting for the
1522
+ * callback to return.
1523
+ * @property isLoading
1524
+ * @type boolean
1525
+ */
1526
+ isLoading: false,
1527
+
1528
+ /**
1529
+ * The toggle/branch icon will not show if this is set to false. This
1530
+ * could be useful if the implementer wants to have the child contain
1531
+ * extra info about the parent, rather than an actual node.
1532
+ * @property hasIcon
1533
+ * @type boolean
1534
+ */
1535
+ hasIcon: true,
1536
+
1537
+ /**
1538
+ * Used to configure what happens when a dynamic load node is expanded
1539
+ * and we discover that it does not have children. By default, it is
1540
+ * treated as if it still could have children (plus/minus icon). Set
1541
+ * iconMode to have it display like a leaf node instead.
1542
+ * @property iconMode
1543
+ * @type int
1544
+ */
1545
+ iconMode: 0,
1546
+
1547
+ /**
1548
+ * Specifies whether or not the content area of the node should be allowed
1549
+ * to wrap.
1550
+ * @property nowrap
1551
+ * @type boolean
1552
+ * @default false
1553
+ */
1554
+ nowrap: false,
1555
+
1556
+ /**
1557
+ * If true, the node will alway be rendered as a leaf node. This can be
1558
+ * used to override the presentation when dynamically loading the entire
1559
+ * tree. Setting this to true also disables the dynamic load call for the
1560
+ * node.
1561
+ * @property isLeaf
1562
+ * @type boolean
1563
+ * @default false
1564
+ */
1565
+ isLeaf: false,
1566
+
1567
+ /**
1568
+ * The CSS class for the html content container. Defaults to ygtvhtml, but
1569
+ * can be overridden to provide a custom presentation for a specific node.
1570
+ * @property contentStyle
1571
+ * @type string
1572
+ */
1573
+ contentStyle: "",
1574
+
1575
+
1576
+ /**
1577
+ * The generated id that will contain the data passed in by the implementer.
1578
+ * @property contentElId
1579
+ * @type string
1580
+ */
1581
+ contentElId: null,
1582
+
1583
+ /**
1584
+ * Enables node highlighting. If true, the node can be highlighted and/or propagate highlighting
1585
+ * @property enableHighlight
1586
+ * @type boolean
1587
+ * @default true
1588
+ */
1589
+ enableHighlight: true,
1590
+
1591
+ /**
1592
+ * Stores the highlight state. Can be any of:
1593
+ * <ul>
1594
+ * <li>0 - not highlighted</li>
1595
+ * <li>1 - highlighted</li>
1596
+ * <li>2 - some children highlighted</li>
1597
+ * </ul>
1598
+ * @property highlightState
1599
+ * @type integer
1600
+ * @default 0
1601
+ */
1602
+
1603
+ highlightState: 0,
1604
+
1605
+ /**
1606
+ * Tells whether highlighting will be propagated up to the parents of the clicked node
1607
+ * @property propagateHighlightUp
1608
+ * @type boolean
1609
+ * @default false
1610
+ */
1611
+
1612
+ propagateHighlightUp: false,
1613
+
1614
+ /**
1615
+ * Tells whether highlighting will be propagated down to the children of the clicked node
1616
+ * @property propagateHighlightDown
1617
+ * @type boolean
1618
+ * @default false
1619
+ */
1620
+
1621
+ propagateHighlightDown: false,
1622
+
1623
+ /**
1624
+ * User-defined className to be added to the Node
1625
+ * @property className
1626
+ * @type string
1627
+ * @default null
1628
+ */
1629
+
1630
+ className: null,
1631
+
1632
+ /**
1633
+ * The node type
1634
+ * @property _type
1635
+ * @private
1636
+ * @type string
1637
+ * @default "Node"
1638
+ */
1639
+ _type: "Node",
1640
+
1641
+ /*
1642
+ spacerPath: "http://l.yimg.com/a/i/space.gif",
1643
+ expandedText: "Expanded",
1644
+ collapsedText: "Collapsed",
1645
+ loadingText: "Loading",
1646
+ */
1647
+
1648
+ /**
1649
+ * Initializes this node, gets some of the properties from the parent
1650
+ * @method init
1651
+ * @param oData {object} a string or object containing the data that will
1652
+ * be used to render this node
1653
+ * @param oParent {Node} this node's parent node
1654
+ * @param expanded {boolean} the initial expanded/collapsed state
1655
+ */
1656
+ init: function(oData, oParent, expanded) {
1657
+
1658
+ this.data = {};
1659
+ this.children = [];
1660
+ this.index = YAHOO.widget.TreeView.nodeCount;
1661
+ ++YAHOO.widget.TreeView.nodeCount;
1662
+ this.contentElId = "ygtvcontentel" + this.index;
1663
+
1664
+ if (Lang.isObject(oData)) {
1665
+ for (var property in oData) {
1666
+ if (oData.hasOwnProperty(property)) {
1667
+ if (property.charAt(0) != '_' && !Lang.isUndefined(this[property]) && !Lang.isFunction(this[property]) ) {
1668
+ this[property] = oData[property];
1669
+ } else {
1670
+ this.data[property] = oData[property];
1671
+ }
1672
+ }
1673
+ }
1674
+ }
1675
+ if (!Lang.isUndefined(expanded) ) { this.expanded = expanded; }
1676
+
1677
+
1678
+ /**
1679
+ * The parentChange event is fired when a parent element is applied
1680
+ * to the node. This is useful if you need to apply tree-level
1681
+ * properties to a tree that need to happen if a node is moved from
1682
+ * one tree to another.
1683
+ *
1684
+ * @event parentChange
1685
+ * @type CustomEvent
1686
+ */
1687
+ this.createEvent("parentChange", this);
1688
+
1689
+ // oParent should never be null except when we create the root node.
1690
+ if (oParent) {
1691
+ oParent.appendChild(this);
1692
+ }
1693
+ },
1694
+
1695
+ /**
1696
+ * Certain properties for the node cannot be set until the parent
1697
+ * is known. This is called after the node is inserted into a tree.
1698
+ * the parent is also applied to this node's children in order to
1699
+ * make it possible to move a branch from one tree to another.
1700
+ * @method applyParent
1701
+ * @param {Node} parentNode this node's parent node
1702
+ * @return {boolean} true if the application was successful
1703
+ */
1704
+ applyParent: function(parentNode) {
1705
+ if (!parentNode) {
1706
+ return false;
1707
+ }
1708
+
1709
+ this.tree = parentNode.tree;
1710
+ this.parent = parentNode;
1711
+ this.depth = parentNode.depth + 1;
1712
+
1713
+ // @todo why was this put here. This causes new nodes added at the
1714
+ // root level to lose the menu behavior.
1715
+ // if (! this.multiExpand) {
1716
+ // this.multiExpand = parentNode.multiExpand;
1717
+ // }
1718
+
1719
+ this.tree.regNode(this);
1720
+ parentNode.childrenRendered = false;
1721
+
1722
+ // cascade update existing children
1723
+ for (var i=0, len=this.children.length;i<len;++i) {
1724
+ this.children[i].applyParent(this);
1725
+ }
1726
+
1727
+ this.fireEvent("parentChange");
1728
+
1729
+ return true;
1730
+ },
1731
+
1732
+ /**
1733
+ * Appends a node to the child collection.
1734
+ * @method appendChild
1735
+ * @param childNode {Node} the new node
1736
+ * @return {Node} the child node
1737
+ * @private
1738
+ */
1739
+ appendChild: function(childNode) {
1740
+ if (this.hasChildren()) {
1741
+ var sib = this.children[this.children.length - 1];
1742
+ sib.nextSibling = childNode;
1743
+ childNode.previousSibling = sib;
1744
+ }
1745
+ this.children[this.children.length] = childNode;
1746
+ childNode.applyParent(this);
1747
+
1748
+ // part of the IE display issue workaround. If child nodes
1749
+ // are added after the initial render, and the node was
1750
+ // instantiated with expanded = true, we need to show the
1751
+ // children div now that the node has a child.
1752
+ if (this.childrenRendered && this.expanded) {
1753
+ this.getChildrenEl().style.display = "";
1754
+ }
1755
+
1756
+ return childNode;
1757
+ },
1758
+
1759
+ /**
1760
+ * Appends this node to the supplied node's child collection
1761
+ * @method appendTo
1762
+ * @param parentNode {Node} the node to append to.
1763
+ * @return {Node} The appended node
1764
+ */
1765
+ appendTo: function(parentNode) {
1766
+ return parentNode.appendChild(this);
1767
+ },
1768
+
1769
+ /**
1770
+ * Inserts this node before this supplied node
1771
+ * @method insertBefore
1772
+ * @param node {Node} the node to insert this node before
1773
+ * @return {Node} the inserted node
1774
+ */
1775
+ insertBefore: function(node) {
1776
+ var p = node.parent;
1777
+ if (p) {
1778
+
1779
+ if (this.tree) {
1780
+ this.tree.popNode(this);
1781
+ }
1782
+
1783
+ var refIndex = node.isChildOf(p);
1784
+ p.children.splice(refIndex, 0, this);
1785
+ if (node.previousSibling) {
1786
+ node.previousSibling.nextSibling = this;
1787
+ }
1788
+ this.previousSibling = node.previousSibling;
1789
+ this.nextSibling = node;
1790
+ node.previousSibling = this;
1791
+
1792
+ this.applyParent(p);
1793
+ }
1794
+
1795
+ return this;
1796
+ },
1797
+
1798
+ /**
1799
+ * Inserts this node after the supplied node
1800
+ * @method insertAfter
1801
+ * @param node {Node} the node to insert after
1802
+ * @return {Node} the inserted node
1803
+ */
1804
+ insertAfter: function(node) {
1805
+ var p = node.parent;
1806
+ if (p) {
1807
+
1808
+ if (this.tree) {
1809
+ this.tree.popNode(this);
1810
+ }
1811
+
1812
+ var refIndex = node.isChildOf(p);
1813
+
1814
+ if (!node.nextSibling) {
1815
+ this.nextSibling = null;
1816
+ return this.appendTo(p);
1817
+ }
1818
+
1819
+ p.children.splice(refIndex + 1, 0, this);
1820
+
1821
+ node.nextSibling.previousSibling = this;
1822
+ this.previousSibling = node;
1823
+ this.nextSibling = node.nextSibling;
1824
+ node.nextSibling = this;
1825
+
1826
+ this.applyParent(p);
1827
+ }
1828
+
1829
+ return this;
1830
+ },
1831
+
1832
+ /**
1833
+ * Returns true if the Node is a child of supplied Node
1834
+ * @method isChildOf
1835
+ * @param parentNode {Node} the Node to check
1836
+ * @return {boolean} The node index if this Node is a child of
1837
+ * supplied Node, else -1.
1838
+ * @private
1839
+ */
1840
+ isChildOf: function(parentNode) {
1841
+ if (parentNode && parentNode.children) {
1842
+ for (var i=0, len=parentNode.children.length; i<len ; ++i) {
1843
+ if (parentNode.children[i] === this) {
1844
+ return i;
1845
+ }
1846
+ }
1847
+ }
1848
+
1849
+ return -1;
1850
+ },
1851
+
1852
+ /**
1853
+ * Returns a node array of this node's siblings, null if none.
1854
+ * @method getSiblings
1855
+ * @return Node[]
1856
+ */
1857
+ getSiblings: function() {
1858
+ var sib = this.parent.children.slice(0);
1859
+ for (var i=0;i < sib.length && sib[i] != this;i++) {}
1860
+ sib.splice(i,1);
1861
+ if (sib.length) { return sib; }
1862
+ return null;
1863
+ },
1864
+
1865
+ /**
1866
+ * Shows this node's children
1867
+ * @method showChildren
1868
+ */
1869
+ showChildren: function() {
1870
+ if (!this.tree.animateExpand(this.getChildrenEl(), this)) {
1871
+ if (this.hasChildren()) {
1872
+ this.getChildrenEl().style.display = "";
1873
+ }
1874
+ }
1875
+ },
1876
+
1877
+ /**
1878
+ * Hides this node's children
1879
+ * @method hideChildren
1880
+ */
1881
+ hideChildren: function() {
1882
+
1883
+ if (!this.tree.animateCollapse(this.getChildrenEl(), this)) {
1884
+ this.getChildrenEl().style.display = "none";
1885
+ }
1886
+ },
1887
+
1888
+ /**
1889
+ * Returns the id for this node's container div
1890
+ * @method getElId
1891
+ * @return {string} the element id
1892
+ */
1893
+ getElId: function() {
1894
+ return "ygtv" + this.index;
1895
+ },
1896
+
1897
+ /**
1898
+ * Returns the id for this node's children div
1899
+ * @method getChildrenElId
1900
+ * @return {string} the element id for this node's children div
1901
+ */
1902
+ getChildrenElId: function() {
1903
+ return "ygtvc" + this.index;
1904
+ },
1905
+
1906
+ /**
1907
+ * Returns the id for this node's toggle element
1908
+ * @method getToggleElId
1909
+ * @return {string} the toggel element id
1910
+ */
1911
+ getToggleElId: function() {
1912
+ return "ygtvt" + this.index;
1913
+ },
1914
+
1915
+
1916
+ /*
1917
+ * Returns the id for this node's spacer image. The spacer is positioned
1918
+ * over the toggle and provides feedback for screen readers.
1919
+ * @method getSpacerId
1920
+ * @return {string} the id for the spacer image
1921
+ */
1922
+ /*
1923
+ getSpacerId: function() {
1924
+ return "ygtvspacer" + this.index;
1925
+ },
1926
+ */
1927
+
1928
+ /**
1929
+ * Returns this node's container html element
1930
+ * @method getEl
1931
+ * @return {HTMLElement} the container html element
1932
+ */
1933
+ getEl: function() {
1934
+ return Dom.get(this.getElId());
1935
+ },
1936
+
1937
+ /**
1938
+ * Returns the div that was generated for this node's children
1939
+ * @method getChildrenEl
1940
+ * @return {HTMLElement} this node's children div
1941
+ */
1942
+ getChildrenEl: function() {
1943
+ return Dom.get(this.getChildrenElId());
1944
+ },
1945
+
1946
+ /**
1947
+ * Returns the element that is being used for this node's toggle.
1948
+ * @method getToggleEl
1949
+ * @return {HTMLElement} this node's toggle html element
1950
+ */
1951
+ getToggleEl: function() {
1952
+ return Dom.get(this.getToggleElId());
1953
+ },
1954
+ /**
1955
+ * Returns the outer html element for this node's content
1956
+ * @method getContentEl
1957
+ * @return {HTMLElement} the element
1958
+ */
1959
+ getContentEl: function() {
1960
+ return Dom.get(this.contentElId);
1961
+ },
1962
+
1963
+
1964
+ /*
1965
+ * Returns the element that is being used for this node's spacer.
1966
+ * @method getSpacer
1967
+ * @return {HTMLElement} this node's spacer html element
1968
+ */
1969
+ /*
1970
+ getSpacer: function() {
1971
+ return document.getElementById( this.getSpacerId() ) || {};
1972
+ },
1973
+ */
1974
+
1975
+ /*
1976
+ getStateText: function() {
1977
+ if (this.isLoading) {
1978
+ return this.loadingText;
1979
+ } else if (this.hasChildren(true)) {
1980
+ if (this.expanded) {
1981
+ return this.expandedText;
1982
+ } else {
1983
+ return this.collapsedText;
1984
+ }
1985
+ } else {
1986
+ return "";
1987
+ }
1988
+ },
1989
+ */
1990
+
1991
+ /**
1992
+ * Hides this nodes children (creating them if necessary), changes the toggle style.
1993
+ * @method collapse
1994
+ */
1995
+ collapse: function() {
1996
+ // Only collapse if currently expanded
1997
+ if (!this.expanded) { return; }
1998
+
1999
+ // fire the collapse event handler
2000
+ var ret = this.tree.onCollapse(this);
2001
+
2002
+ if (false === ret) {
2003
+ return;
2004
+ }
2005
+
2006
+ ret = this.tree.fireEvent("collapse", this);
2007
+
2008
+ if (false === ret) {
2009
+ return;
2010
+ }
2011
+
2012
+
2013
+ if (!this.getEl()) {
2014
+ this.expanded = false;
2015
+ } else {
2016
+ // hide the child div
2017
+ this.hideChildren();
2018
+ this.expanded = false;
2019
+
2020
+ this.updateIcon();
2021
+ }
2022
+
2023
+ // this.getSpacer().title = this.getStateText();
2024
+
2025
+ ret = this.tree.fireEvent("collapseComplete", this);
2026
+
2027
+ },
2028
+
2029
+ /**
2030
+ * Shows this nodes children (creating them if necessary), changes the
2031
+ * toggle style, and collapses its siblings if multiExpand is not set.
2032
+ * @method expand
2033
+ */
2034
+ expand: function(lazySource) {
2035
+ // Only expand if currently collapsed.
2036
+ if (this.isLoading || (this.expanded && !lazySource)) {
2037
+ return;
2038
+ }
2039
+
2040
+ var ret = true;
2041
+
2042
+ // When returning from the lazy load handler, expand is called again
2043
+ // in order to render the new children. The "expand" event already
2044
+ // fired before fething the new data, so we need to skip it now.
2045
+ if (!lazySource) {
2046
+ // fire the expand event handler
2047
+ ret = this.tree.onExpand(this);
2048
+
2049
+ if (false === ret) {
2050
+ return;
2051
+ }
2052
+
2053
+ ret = this.tree.fireEvent("expand", this);
2054
+ }
2055
+
2056
+ if (false === ret) {
2057
+ return;
2058
+ }
2059
+
2060
+ if (!this.getEl()) {
2061
+ this.expanded = true;
2062
+ return;
2063
+ }
2064
+
2065
+ if (!this.childrenRendered) {
2066
+ this.getChildrenEl().innerHTML = this.renderChildren();
2067
+ } else {
2068
+ }
2069
+
2070
+ this.expanded = true;
2071
+
2072
+ this.updateIcon();
2073
+
2074
+ // this.getSpacer().title = this.getStateText();
2075
+
2076
+ // We do an extra check for children here because the lazy
2077
+ // load feature can expose nodes that have no children.
2078
+
2079
+ // if (!this.hasChildren()) {
2080
+ if (this.isLoading) {
2081
+ this.expanded = false;
2082
+ return;
2083
+ }
2084
+
2085
+ if (! this.multiExpand) {
2086
+ var sibs = this.getSiblings();
2087
+ for (var i=0; sibs && i<sibs.length; ++i) {
2088
+ if (sibs[i] != this && sibs[i].expanded) {
2089
+ sibs[i].collapse();
2090
+ }
2091
+ }
2092
+ }
2093
+
2094
+ this.showChildren();
2095
+
2096
+ ret = this.tree.fireEvent("expandComplete", this);
2097
+ },
2098
+
2099
+ updateIcon: function() {
2100
+ if (this.hasIcon) {
2101
+ var el = this.getToggleEl();
2102
+ if (el) {
2103
+ el.className = el.className.replace(/\bygtv(([tl][pmn]h?)|(loading))\b/gi,this.getStyle());
2104
+ }
2105
+ }
2106
+ },
2107
+
2108
+ /**
2109
+ * Returns the css style name for the toggle
2110
+ * @method getStyle
2111
+ * @return {string} the css class for this node's toggle
2112
+ */
2113
+ getStyle: function() {
2114
+ if (this.isLoading) {
2115
+ return "ygtvloading";
2116
+ } else {
2117
+ // location top or bottom, middle nodes also get the top style
2118
+ var loc = (this.nextSibling) ? "t" : "l";
2119
+
2120
+ // type p=plus(expand), m=minus(collapase), n=none(no children)
2121
+ var type = "n";
2122
+ if (this.hasChildren(true) || (this.isDynamic() && !this.getIconMode())) {
2123
+ // if (this.hasChildren(true)) {
2124
+ type = (this.expanded) ? "m" : "p";
2125
+ }
2126
+
2127
+ return "ygtv" + loc + type;
2128
+ }
2129
+ },
2130
+
2131
+ /**
2132
+ * Returns the hover style for the icon
2133
+ * @return {string} the css class hover state
2134
+ * @method getHoverStyle
2135
+ */
2136
+ getHoverStyle: function() {
2137
+ var s = this.getStyle();
2138
+ if (this.hasChildren(true) && !this.isLoading) {
2139
+ s += "h";
2140
+ }
2141
+ return s;
2142
+ },
2143
+
2144
+ /**
2145
+ * Recursively expands all of this node's children.
2146
+ * @method expandAll
2147
+ */
2148
+ expandAll: function() {
2149
+ var l = this.children.length;
2150
+ for (var i=0;i<l;++i) {
2151
+ var c = this.children[i];
2152
+ if (c.isDynamic()) {
2153
+ break;
2154
+ } else if (! c.multiExpand) {
2155
+ break;
2156
+ } else {
2157
+ c.expand();
2158
+ c.expandAll();
2159
+ }
2160
+ }
2161
+ },
2162
+
2163
+ /**
2164
+ * Recursively collapses all of this node's children.
2165
+ * @method collapseAll
2166
+ */
2167
+ collapseAll: function() {
2168
+ for (var i=0;i<this.children.length;++i) {
2169
+ this.children[i].collapse();
2170
+ this.children[i].collapseAll();
2171
+ }
2172
+ },
2173
+
2174
+ /**
2175
+ * Configures this node for dynamically obtaining the child data
2176
+ * when the node is first expanded. Calling it without the callback
2177
+ * will turn off dynamic load for the node.
2178
+ * @method setDynamicLoad
2179
+ * @param fmDataLoader {function} the function that will be used to get the data.
2180
+ * @param iconMode {int} configures the icon that is displayed when a dynamic
2181
+ * load node is expanded the first time without children. By default, the
2182
+ * "collapse" icon will be used. If set to 1, the leaf node icon will be
2183
+ * displayed.
2184
+ */
2185
+ setDynamicLoad: function(fnDataLoader, iconMode) {
2186
+ if (fnDataLoader) {
2187
+ this.dataLoader = fnDataLoader;
2188
+ this._dynLoad = true;
2189
+ } else {
2190
+ this.dataLoader = null;
2191
+ this._dynLoad = false;
2192
+ }
2193
+
2194
+ if (iconMode) {
2195
+ this.iconMode = iconMode;
2196
+ }
2197
+ },
2198
+
2199
+ /**
2200
+ * Evaluates if this node is the root node of the tree
2201
+ * @method isRoot
2202
+ * @return {boolean} true if this is the root node
2203
+ */
2204
+ isRoot: function() {
2205
+ return (this == this.tree.root);
2206
+ },
2207
+
2208
+ /**
2209
+ * Evaluates if this node's children should be loaded dynamically. Looks for
2210
+ * the property both in this instance and the root node. If the tree is
2211
+ * defined to load all children dynamically, the data callback function is
2212
+ * defined in the root node
2213
+ * @method isDynamic
2214
+ * @return {boolean} true if this node's children are to be loaded dynamically
2215
+ */
2216
+ isDynamic: function() {
2217
+ if (this.isLeaf) {
2218
+ return false;
2219
+ } else {
2220
+ return (!this.isRoot() && (this._dynLoad || this.tree.root._dynLoad));
2221
+ // return lazy;
2222
+ }
2223
+ },
2224
+
2225
+ /**
2226
+ * Returns the current icon mode. This refers to the way childless dynamic
2227
+ * load nodes appear (this comes into play only after the initial dynamic
2228
+ * load request produced no children).
2229
+ * @method getIconMode
2230
+ * @return {int} 0 for collapse style, 1 for leaf node style
2231
+ */
2232
+ getIconMode: function() {
2233
+ return (this.iconMode || this.tree.root.iconMode);
2234
+ },
2235
+
2236
+ /**
2237
+ * Checks if this node has children. If this node is lazy-loading and the
2238
+ * children have not been rendered, we do not know whether or not there
2239
+ * are actual children. In most cases, we need to assume that there are
2240
+ * children (for instance, the toggle needs to show the expandable
2241
+ * presentation state). In other times we want to know if there are rendered
2242
+ * children. For the latter, "checkForLazyLoad" should be false.
2243
+ * @method hasChildren
2244
+ * @param checkForLazyLoad {boolean} should we check for unloaded children?
2245
+ * @return {boolean} true if this has children or if it might and we are
2246
+ * checking for this condition.
2247
+ */
2248
+ hasChildren: function(checkForLazyLoad) {
2249
+ if (this.isLeaf) {
2250
+ return false;
2251
+ } else {
2252
+ return ( this.children.length > 0 ||
2253
+ (checkForLazyLoad && this.isDynamic() && !this.dynamicLoadComplete)
2254
+ );
2255
+ }
2256
+ },
2257
+
2258
+ /**
2259
+ * Expands if node is collapsed, collapses otherwise.
2260
+ * @method toggle
2261
+ */
2262
+ toggle: function() {
2263
+ if (!this.tree.locked && ( this.hasChildren(true) || this.isDynamic()) ) {
2264
+ if (this.expanded) { this.collapse(); } else { this.expand(); }
2265
+ }
2266
+ },
2267
+
2268
+ /**
2269
+ * Returns the markup for this node and its children.
2270
+ * @method getHtml
2271
+ * @return {string} the markup for this node and its expanded children.
2272
+ */
2273
+ getHtml: function() {
2274
+
2275
+ this.childrenRendered = false;
2276
+
2277
+ return ['<div class="ygtvitem" id="' , this.getElId() , '">' ,this.getNodeHtml() , this.getChildrenHtml() ,'</div>'].join("");
2278
+ },
2279
+
2280
+ /**
2281
+ * Called when first rendering the tree. We always build the div that will
2282
+ * contain this nodes children, but we don't render the children themselves
2283
+ * unless this node is expanded.
2284
+ * @method getChildrenHtml
2285
+ * @return {string} the children container div html and any expanded children
2286
+ * @private
2287
+ */
2288
+ getChildrenHtml: function() {
2289
+
2290
+
2291
+ var sb = [];
2292
+ sb[sb.length] = '<div class="ygtvchildren" id="' + this.getChildrenElId() + '"';
2293
+
2294
+ // This is a workaround for an IE rendering issue, the child div has layout
2295
+ // in IE, creating extra space if a leaf node is created with the expanded
2296
+ // property set to true.
2297
+ if (!this.expanded || !this.hasChildren()) {
2298
+ sb[sb.length] = ' style="display:none;"';
2299
+ }
2300
+ sb[sb.length] = '>';
2301
+
2302
+
2303
+ // Don't render the actual child node HTML unless this node is expanded.
2304
+ if ( (this.hasChildren(true) && this.expanded) ||
2305
+ (this.renderHidden && !this.isDynamic()) ) {
2306
+ sb[sb.length] = this.renderChildren();
2307
+ }
2308
+
2309
+ sb[sb.length] = '</div>';
2310
+
2311
+ return sb.join("");
2312
+ },
2313
+
2314
+ /**
2315
+ * Generates the markup for the child nodes. This is not done until the node
2316
+ * is expanded.
2317
+ * @method renderChildren
2318
+ * @return {string} the html for this node's children
2319
+ * @private
2320
+ */
2321
+ renderChildren: function() {
2322
+
2323
+
2324
+ var node = this;
2325
+
2326
+ if (this.isDynamic() && !this.dynamicLoadComplete) {
2327
+ this.isLoading = true;
2328
+ this.tree.locked = true;
2329
+
2330
+ if (this.dataLoader) {
2331
+
2332
+ setTimeout(
2333
+ function() {
2334
+ node.dataLoader(node,
2335
+ function() {
2336
+ node.loadComplete();
2337
+ });
2338
+ }, 10);
2339
+
2340
+ } else if (this.tree.root.dataLoader) {
2341
+
2342
+ setTimeout(
2343
+ function() {
2344
+ node.tree.root.dataLoader(node,
2345
+ function() {
2346
+ node.loadComplete();
2347
+ });
2348
+ }, 10);
2349
+
2350
+ } else {
2351
+ return "Error: data loader not found or not specified.";
2352
+ }
2353
+
2354
+ return "";
2355
+
2356
+ } else {
2357
+ return this.completeRender();
2358
+ }
2359
+ },
2360
+
2361
+ /**
2362
+ * Called when we know we have all the child data.
2363
+ * @method completeRender
2364
+ * @return {string} children html
2365
+ */
2366
+ completeRender: function() {
2367
+ var sb = [];
2368
+
2369
+ for (var i=0; i < this.children.length; ++i) {
2370
+ // this.children[i].childrenRendered = false;
2371
+ sb[sb.length] = this.children[i].getHtml();
2372
+ }
2373
+
2374
+ this.childrenRendered = true;
2375
+
2376
+ return sb.join("");
2377
+ },
2378
+
2379
+ /**
2380
+ * Load complete is the callback function we pass to the data provider
2381
+ * in dynamic load situations.
2382
+ * @method loadComplete
2383
+ */
2384
+ loadComplete: function() {
2385
+ this.getChildrenEl().innerHTML = this.completeRender();
2386
+ if (this.propagateHighlightDown) {
2387
+ if (this.highlightState === 1 && !this.tree.singleNodeHighlight) {
2388
+ for (var i = 0; i < this.children.length; i++) {
2389
+ this.children[i].highlight(true);
2390
+ }
2391
+ } else if (this.highlightState === 0 || this.tree.singleNodeHighlight) {
2392
+ for (i = 0; i < this.children.length; i++) {
2393
+ this.children[i].unhighlight(true);
2394
+ }
2395
+ } // if (highlighState == 2) leave child nodes with whichever highlight state they are set
2396
+ }
2397
+
2398
+ this.dynamicLoadComplete = true;
2399
+ this.isLoading = false;
2400
+ this.expand(true);
2401
+ this.tree.locked = false;
2402
+ },
2403
+
2404
+ /**
2405
+ * Returns this node's ancestor at the specified depth.
2406
+ * @method getAncestor
2407
+ * @param {int} depth the depth of the ancestor.
2408
+ * @return {Node} the ancestor
2409
+ */
2410
+ getAncestor: function(depth) {
2411
+ if (depth >= this.depth || depth < 0) {
2412
+ return null;
2413
+ }
2414
+
2415
+ var p = this.parent;
2416
+
2417
+ while (p.depth > depth) {
2418
+ p = p.parent;
2419
+ }
2420
+
2421
+ return p;
2422
+ },
2423
+
2424
+ /**
2425
+ * Returns the css class for the spacer at the specified depth for
2426
+ * this node. If this node's ancestor at the specified depth
2427
+ * has a next sibling the presentation is different than if it
2428
+ * does not have a next sibling
2429
+ * @method getDepthStyle
2430
+ * @param {int} depth the depth of the ancestor.
2431
+ * @return {string} the css class for the spacer
2432
+ */
2433
+ getDepthStyle: function(depth) {
2434
+ return (this.getAncestor(depth).nextSibling) ?
2435
+ "ygtvdepthcell" : "ygtvblankdepthcell";
2436
+ },
2437
+
2438
+ /**
2439
+ * Get the markup for the node. This may be overrided so that we can
2440
+ * support different types of nodes.
2441
+ * @method getNodeHtml
2442
+ * @return {string} The HTML that will render this node.
2443
+ */
2444
+ getNodeHtml: function() {
2445
+ var sb = [];
2446
+
2447
+ sb[sb.length] = '<table id="ygtvtableel' + this.index + '" border="0" cellpadding="0" cellspacing="0" class="ygtvtable ygtvdepth' + this.depth;
2448
+ if (this.enableHighlight) {
2449
+ sb[sb.length] = ' ygtv-highlight' + this.highlightState;
2450
+ }
2451
+ if (this.className) {
2452
+ sb[sb.length] = ' ' + this.className;
2453
+ }
2454
+ sb[sb.length] = '"><tr class="ygtvrow">';
2455
+
2456
+ for (var i=0;i<this.depth;++i) {
2457
+ sb[sb.length] = '<td class="ygtvcell ' + this.getDepthStyle(i) + '"><div class="ygtvspacer"></div></td>';
2458
+ }
2459
+
2460
+ if (this.hasIcon) {
2461
+ sb[sb.length] = '<td id="' + this.getToggleElId();
2462
+ sb[sb.length] = '" class="ygtvcell ';
2463
+ sb[sb.length] = this.getStyle() ;
2464
+ sb[sb.length] = '"><a href="#" class="ygtvspacer">&#160;</a></td>';
2465
+ }
2466
+
2467
+ sb[sb.length] = '<td id="' + this.contentElId;
2468
+ sb[sb.length] = '" class="ygtvcell ';
2469
+ sb[sb.length] = this.contentStyle + ' ygtvcontent" ';
2470
+ sb[sb.length] = (this.nowrap) ? ' nowrap="nowrap" ' : '';
2471
+ sb[sb.length] = ' >';
2472
+ sb[sb.length] = this.getContentHtml();
2473
+ sb[sb.length] = '</td></tr></table>';
2474
+
2475
+ return sb.join("");
2476
+
2477
+ },
2478
+ /**
2479
+ * Get the markup for the contents of the node. This is designed to be overrided so that we can
2480
+ * support different types of nodes.
2481
+ * @method getContentHtml
2482
+ * @return {string} The HTML that will render the content of this node.
2483
+ */
2484
+ getContentHtml: function () {
2485
+ return "";
2486
+ },
2487
+
2488
+ /**
2489
+ * Regenerates the html for this node and its children. To be used when the
2490
+ * node is expanded and new children have been added.
2491
+ * @method refresh
2492
+ */
2493
+ refresh: function() {
2494
+ // this.loadComplete();
2495
+ this.getChildrenEl().innerHTML = this.completeRender();
2496
+
2497
+ if (this.hasIcon) {
2498
+ var el = this.getToggleEl();
2499
+ if (el) {
2500
+ el.className = el.className.replace(/\bygtv[lt][nmp]h*\b/gi,this.getStyle());
2501
+ }
2502
+ }
2503
+ },
2504
+
2505
+ /**
2506
+ * Node toString
2507
+ * @method toString
2508
+ * @return {string} string representation of the node
2509
+ */
2510
+ toString: function() {
2511
+ return this._type + " (" + this.index + ")";
2512
+ },
2513
+ /**
2514
+ * array of items that had the focus set on them
2515
+ * so that they can be cleaned when focus is lost
2516
+ * @property _focusHighlightedItems
2517
+ * @type Array of DOM elements
2518
+ * @private
2519
+ */
2520
+ _focusHighlightedItems: [],
2521
+ /**
2522
+ * DOM element that actually got the browser focus
2523
+ * @property _focusedItem
2524
+ * @type DOM element
2525
+ * @private
2526
+ */
2527
+ _focusedItem: null,
2528
+
2529
+ /**
2530
+ * Returns true if there are any elements in the node that can
2531
+ * accept the real actual browser focus
2532
+ * @method _canHaveFocus
2533
+ * @return {boolean} success
2534
+ * @private
2535
+ */
2536
+ _canHaveFocus: function() {
2537
+ return this.getEl().getElementsByTagName('a').length > 0;
2538
+ },
2539
+ /**
2540
+ * Removes the focus of previously selected Node
2541
+ * @method _removeFocus
2542
+ * @private
2543
+ */
2544
+ _removeFocus:function () {
2545
+ if (this._focusedItem) {
2546
+ Event.removeListener(this._focusedItem,'blur');
2547
+ this._focusedItem = null;
2548
+ }
2549
+ var el;
2550
+ while ((el = this._focusHighlightedItems.shift())) { // yes, it is meant as an assignment, really
2551
+ Dom.removeClass(el,YAHOO.widget.TreeView.FOCUS_CLASS_NAME );
2552
+ }
2553
+ },
2554
+ /**
2555
+ * Sets the focus on the node element.
2556
+ * It will only be able to set the focus on nodes that have anchor elements in it.
2557
+ * Toggle or branch icons have anchors and can be focused on.
2558
+ * If will fail in nodes that have no anchor
2559
+ * @method focus
2560
+ * @return {boolean} success
2561
+ */
2562
+ focus: function () {
2563
+ var focused = false, self = this;
2564
+
2565
+ if (this.tree.currentFocus) {
2566
+ this.tree.currentFocus._removeFocus();
2567
+ }
2568
+
2569
+ var expandParent = function (node) {
2570
+ if (node.parent) {
2571
+ expandParent(node.parent);
2572
+ node.parent.expand();
2573
+ }
2574
+ };
2575
+ expandParent(this);
2576
+
2577
+ Dom.getElementsBy (
2578
+ function (el) {
2579
+ return (/ygtv(([tl][pmn]h?)|(content))/).test(el.className);
2580
+ } ,
2581
+ 'td' ,
2582
+ self.getEl().firstChild ,
2583
+ function (el) {
2584
+ Dom.addClass(el, YAHOO.widget.TreeView.FOCUS_CLASS_NAME );
2585
+ if (!focused) {
2586
+ var aEl = el.getElementsByTagName('a');
2587
+ if (aEl.length) {
2588
+ aEl = aEl[0];
2589
+ aEl.focus();
2590
+ self._focusedItem = aEl;
2591
+ Event.on(aEl,'blur',function () {
2592
+ //console.log('f1');
2593
+ self.tree.fireEvent('focusChanged',{oldNode:self.tree.currentFocus,newNode:null});
2594
+ self.tree.currentFocus = null;
2595
+ self._removeFocus();
2596
+ });
2597
+ focused = true;
2598
+ }
2599
+ }
2600
+ self._focusHighlightedItems.push(el);
2601
+ }
2602
+ );
2603
+ if (focused) {
2604
+ //console.log('f2');
2605
+ this.tree.fireEvent('focusChanged',{oldNode:this.tree.currentFocus,newNode:this});
2606
+ this.tree.currentFocus = this;
2607
+ } else {
2608
+ //console.log('f3');
2609
+ this.tree.fireEvent('focusChanged',{oldNode:self.tree.currentFocus,newNode:null});
2610
+ this.tree.currentFocus = null;
2611
+ this._removeFocus();
2612
+ }
2613
+ return focused;
2614
+ },
2615
+
2616
+ /**
2617
+ * Count of nodes in a branch
2618
+ * @method getNodeCount
2619
+ * @return {int} number of nodes in the branch
2620
+ */
2621
+ getNodeCount: function() {
2622
+ for (var i = 0, count = 0;i< this.children.length;i++) {
2623
+ count += this.children[i].getNodeCount();
2624
+ }
2625
+ return count + 1;
2626
+ },
2627
+
2628
+ /**
2629
+ * Returns an object which could be used to build a tree out of this node and its children.
2630
+ * It can be passed to the tree constructor to reproduce this node as a tree.
2631
+ * It will return false if the node or any children loads dynamically, regardless of whether it is loaded or not.
2632
+ * @method getNodeDefinition
2633
+ * @return {Object | false} definition of the tree or false if the node or any children is defined as dynamic
2634
+ */
2635
+ getNodeDefinition: function() {
2636
+
2637
+ if (this.isDynamic()) { return false; }
2638
+
2639
+ var def, defs = Lang.merge(this.data), children = [];
2640
+
2641
+
2642
+
2643
+ if (this.expanded) {defs.expanded = this.expanded; }
2644
+ if (!this.multiExpand) { defs.multiExpand = this.multiExpand; }
2645
+ if (!this.renderHidden) { defs.renderHidden = this.renderHidden; }
2646
+ if (!this.hasIcon) { defs.hasIcon = this.hasIcon; }
2647
+ if (this.nowrap) { defs.nowrap = this.nowrap; }
2648
+ if (this.className) { defs.className = this.className; }
2649
+ if (this.editable) { defs.editable = this.editable; }
2650
+ if (this.enableHighlight) { defs.enableHighlight = this.enableHighlight; }
2651
+ if (this.highlightState) { defs.highlightState = this.highlightState; }
2652
+ if (this.propagateHighlightUp) { defs.propagateHighlightUp = this.propagateHighlightUp; }
2653
+ if (this.propagateHighlightDown) { defs.propagateHighlightDown = this.propagateHighlightDown; }
2654
+ defs.type = this._type;
2655
+
2656
+
2657
+
2658
+ for (var i = 0; i < this.children.length;i++) {
2659
+ def = this.children[i].getNodeDefinition();
2660
+ if (def === false) { return false;}
2661
+ children.push(def);
2662
+ }
2663
+ if (children.length) { defs.children = children; }
2664
+ return defs;
2665
+ },
2666
+
2667
+
2668
+ /**
2669
+ * Generates the link that will invoke this node's toggle method
2670
+ * @method getToggleLink
2671
+ * @return {string} the javascript url for toggling this node
2672
+ */
2673
+ getToggleLink: function() {
2674
+ return 'return false;';
2675
+ },
2676
+
2677
+ /**
2678
+ * Sets the value of property for this node and all loaded descendants.
2679
+ * Only public and defined properties can be set, not methods.
2680
+ * Values for unknown properties will be assigned to the refNode.data object
2681
+ * @method setNodesProperty
2682
+ * @param name {string} Name of the property to be set
2683
+ * @param value {any} value to be set
2684
+ * @param refresh {boolean} if present and true, it does a refresh
2685
+ */
2686
+ setNodesProperty: function(name, value, refresh) {
2687
+ if (name.charAt(0) != '_' && !Lang.isUndefined(this[name]) && !Lang.isFunction(this[name]) ) {
2688
+ this[name] = value;
2689
+ } else {
2690
+ this.data[name] = value;
2691
+ }
2692
+ for (var i = 0; i < this.children.length;i++) {
2693
+ this.children[i].setNodesProperty(name,value);
2694
+ }
2695
+ if (refresh) {
2696
+ this.refresh();
2697
+ }
2698
+ },
2699
+ /**
2700
+ * Toggles the highlighted state of a Node
2701
+ * @method toggleHighlight
2702
+ */
2703
+ toggleHighlight: function() {
2704
+ if (this.enableHighlight) {
2705
+ // unhighlights only if fully highligthed. For not or partially highlighted it will highlight
2706
+ if (this.highlightState == 1) {
2707
+ this.unhighlight();
2708
+ } else {
2709
+ this.highlight();
2710
+ }
2711
+ }
2712
+ },
2713
+
2714
+ /**
2715
+ * Turns highlighting on node.
2716
+ * @method highlight
2717
+ * @param _silent {boolean} optional, don't fire the highlightEvent
2718
+ */
2719
+ highlight: function(_silent) {
2720
+ if (this.enableHighlight) {
2721
+ if (this.tree.singleNodeHighlight) {
2722
+ if (this.tree._currentlyHighlighted) {
2723
+ this.tree._currentlyHighlighted.unhighlight(_silent);
2724
+ }
2725
+ this.tree._currentlyHighlighted = this;
2726
+ }
2727
+ this.highlightState = 1;
2728
+ this._setHighlightClassName();
2729
+ if (!this.tree.singleNodeHighlight) {
2730
+ if (this.propagateHighlightDown) {
2731
+ for (var i = 0;i < this.children.length;i++) {
2732
+ this.children[i].highlight(true);
2733
+ }
2734
+ }
2735
+ if (this.propagateHighlightUp) {
2736
+ if (this.parent) {
2737
+ this.parent._childrenHighlighted();
2738
+ }
2739
+ }
2740
+ }
2741
+ if (!_silent) {
2742
+ this.tree.fireEvent('highlightEvent',this);
2743
+ }
2744
+ }
2745
+ },
2746
+ /**
2747
+ * Turns highlighting off a node.
2748
+ * @method unhighlight
2749
+ * @param _silent {boolean} optional, don't fire the highlightEvent
2750
+ */
2751
+ unhighlight: function(_silent) {
2752
+ if (this.enableHighlight) {
2753
+ // might have checked singleNodeHighlight but it wouldn't really matter either way
2754
+ this.tree._currentlyHighlighted = null;
2755
+ this.highlightState = 0;
2756
+ this._setHighlightClassName();
2757
+ if (!this.tree.singleNodeHighlight) {
2758
+ if (this.propagateHighlightDown) {
2759
+ for (var i = 0;i < this.children.length;i++) {
2760
+ this.children[i].unhighlight(true);
2761
+ }
2762
+ }
2763
+ if (this.propagateHighlightUp) {
2764
+ if (this.parent) {
2765
+ this.parent._childrenHighlighted();
2766
+ }
2767
+ }
2768
+ }
2769
+ if (!_silent) {
2770
+ this.tree.fireEvent('highlightEvent',this);
2771
+ }
2772
+ }
2773
+ },
2774
+ /**
2775
+ * Checks whether all or part of the children of a node are highlighted and
2776
+ * sets the node highlight to full, none or partial highlight.
2777
+ * If set to propagate it will further call the parent
2778
+ * @method _childrenHighlighted
2779
+ * @private
2780
+ */
2781
+ _childrenHighlighted: function() {
2782
+ var yes = false, no = false;
2783
+ if (this.enableHighlight) {
2784
+ for (var i = 0;i < this.children.length;i++) {
2785
+ switch(this.children[i].highlightState) {
2786
+ case 0:
2787
+ no = true;
2788
+ break;
2789
+ case 1:
2790
+ yes = true;
2791
+ break;
2792
+ case 2:
2793
+ yes = no = true;
2794
+ break;
2795
+ }
2796
+ }
2797
+ if (yes && no) {
2798
+ this.highlightState = 2;
2799
+ } else if (yes) {
2800
+ this.highlightState = 1;
2801
+ } else {
2802
+ this.highlightState = 0;
2803
+ }
2804
+ this._setHighlightClassName();
2805
+ if (this.propagateHighlightUp) {
2806
+ if (this.parent) {
2807
+ this.parent._childrenHighlighted();
2808
+ }
2809
+ }
2810
+ }
2811
+ },
2812
+
2813
+ /**
2814
+ * Changes the classNames on the toggle and content containers to reflect the current highlighting
2815
+ * @method _setHighlightClassName
2816
+ * @private
2817
+ */
2818
+ _setHighlightClassName: function() {
2819
+ var el = Dom.get('ygtvtableel' + this.index);
2820
+ if (el) {
2821
+ el.className = el.className.replace(/\bygtv-highlight\d\b/gi,'ygtv-highlight' + this.highlightState);
2822
+ }
2823
+ }
2824
+
2825
+ };
2826
+
2827
+ YAHOO.augment(YAHOO.widget.Node, YAHOO.util.EventProvider);
2828
+ })();
2829
+
2830
+ /**
2831
+ * A custom YAHOO.widget.Node that handles the unique nature of
2832
+ * the virtual, presentationless root node.
2833
+ * @namespace YAHOO.widget
2834
+ * @class RootNode
2835
+ * @extends YAHOO.widget.Node
2836
+ * @param oTree {YAHOO.widget.TreeView} The tree instance this node belongs to
2837
+ * @constructor
2838
+ */
2839
+ YAHOO.widget.RootNode = function(oTree) {
2840
+ // Initialize the node with null params. The root node is a
2841
+ // special case where the node has no presentation. So we have
2842
+ // to alter the standard properties a bit.
2843
+ this.init(null, null, true);
2844
+
2845
+ /*
2846
+ * For the root node, we get the tree reference from as a param
2847
+ * to the constructor instead of from the parent element.
2848
+ */
2849
+ this.tree = oTree;
2850
+ };
2851
+
2852
+ YAHOO.extend(YAHOO.widget.RootNode, YAHOO.widget.Node, {
2853
+
2854
+ /**
2855
+ * The node type
2856
+ * @property _type
2857
+ * @type string
2858
+ * @private
2859
+ * @default "RootNode"
2860
+ */
2861
+ _type: "RootNode",
2862
+
2863
+ // overrides YAHOO.widget.Node
2864
+ getNodeHtml: function() {
2865
+ return "";
2866
+ },
2867
+
2868
+ toString: function() {
2869
+ return this._type;
2870
+ },
2871
+
2872
+ loadComplete: function() {
2873
+ this.tree.draw();
2874
+ },
2875
+
2876
+ /**
2877
+ * Count of nodes in tree.
2878
+ * It overrides Nodes.getNodeCount because the root node should not be counted.
2879
+ * @method getNodeCount
2880
+ * @return {int} number of nodes in the tree
2881
+ */
2882
+ getNodeCount: function() {
2883
+ for (var i = 0, count = 0;i< this.children.length;i++) {
2884
+ count += this.children[i].getNodeCount();
2885
+ }
2886
+ return count;
2887
+ },
2888
+
2889
+ /**
2890
+ * Returns an object which could be used to build a tree out of this node and its children.
2891
+ * It can be passed to the tree constructor to reproduce this node as a tree.
2892
+ * Since the RootNode is automatically created by treeView,
2893
+ * its own definition is excluded from the returned node definition
2894
+ * which only contains its children.
2895
+ * @method getNodeDefinition
2896
+ * @return {Object | false} definition of the tree or false if any child node is defined as dynamic
2897
+ */
2898
+ getNodeDefinition: function() {
2899
+
2900
+ for (var def, defs = [], i = 0; i < this.children.length;i++) {
2901
+ def = this.children[i].getNodeDefinition();
2902
+ if (def === false) { return false;}
2903
+ defs.push(def);
2904
+ }
2905
+ return defs;
2906
+ },
2907
+
2908
+ collapse: function() {},
2909
+ expand: function() {},
2910
+ getSiblings: function() { return null; },
2911
+ focus: function () {}
2912
+
2913
+ });
2914
+
2915
+ (function () {
2916
+ var Dom = YAHOO.util.Dom,
2917
+ Lang = YAHOO.lang,
2918
+ Event = YAHOO.util.Event;
2919
+ /**
2920
+ * The default node presentation. The first parameter should be
2921
+ * either a string that will be used as the node's label, or an object
2922
+ * that has at least a string property called label. By default, clicking the
2923
+ * label will toggle the expanded/collapsed state of the node. By
2924
+ * setting the href property of the instance, this behavior can be
2925
+ * changed so that the label will go to the specified href.
2926
+ * @namespace YAHOO.widget
2927
+ * @class TextNode
2928
+ * @extends YAHOO.widget.Node
2929
+ * @constructor
2930
+ * @param oData {object} a string or object containing the data that will
2931
+ * be used to render this node.
2932
+ * Providing a string is the same as providing an object with a single property named label.
2933
+ * All values in the oData will be used to set equally named properties in the node
2934
+ * as long as the node does have such properties, they are not undefined, private or functions.
2935
+ * All attributes are made available in noderef.data, which
2936
+ * can be used to store custom attributes. TreeView.getNode(s)ByProperty
2937
+ * can be used to retrieve a node by one of the attributes.
2938
+ * @param oParent {YAHOO.widget.Node} this node's parent node
2939
+ * @param expanded {boolean} the initial expanded/collapsed state (deprecated; use oData.expanded)
2940
+ */
2941
+ YAHOO.widget.TextNode = function(oData, oParent, expanded) {
2942
+
2943
+ if (oData) {
2944
+ if (Lang.isString(oData)) {
2945
+ oData = { label: oData };
2946
+ }
2947
+ this.init(oData, oParent, expanded);
2948
+ this.setUpLabel(oData);
2949
+ }
2950
+
2951
+ };
2952
+
2953
+ YAHOO.extend(YAHOO.widget.TextNode, YAHOO.widget.Node, {
2954
+
2955
+ /**
2956
+ * The CSS class for the label href. Defaults to ygtvlabel, but can be
2957
+ * overridden to provide a custom presentation for a specific node.
2958
+ * @property labelStyle
2959
+ * @type string
2960
+ */
2961
+ labelStyle: "ygtvlabel",
2962
+
2963
+ /**
2964
+ * The derived element id of the label for this node
2965
+ * @property labelElId
2966
+ * @type string
2967
+ */
2968
+ labelElId: null,
2969
+
2970
+ /**
2971
+ * The text for the label. It is assumed that the oData parameter will
2972
+ * either be a string that will be used as the label, or an object that
2973
+ * has a property called "label" that we will use.
2974
+ * @property label
2975
+ * @type string
2976
+ */
2977
+ label: null,
2978
+
2979
+ /**
2980
+ * The text for the title (tooltip) for the label element
2981
+ * @property title
2982
+ * @type string
2983
+ */
2984
+ title: null,
2985
+
2986
+ /**
2987
+ * The href for the node's label. If one is not specified, the href will
2988
+ * be set so that it toggles the node.
2989
+ * @property href
2990
+ * @type string
2991
+ */
2992
+ href: null,
2993
+
2994
+ /**
2995
+ * The label href target, defaults to current window
2996
+ * @property target
2997
+ * @type string
2998
+ */
2999
+ target: "_self",
3000
+
3001
+ /**
3002
+ * The node type
3003
+ * @property _type
3004
+ * @private
3005
+ * @type string
3006
+ * @default "TextNode"
3007
+ */
3008
+ _type: "TextNode",
3009
+
3010
+
3011
+ /**
3012
+ * Sets up the node label
3013
+ * @method setUpLabel
3014
+ * @param oData string containing the label, or an object with a label property
3015
+ */
3016
+ setUpLabel: function(oData) {
3017
+
3018
+ if (Lang.isString(oData)) {
3019
+ oData = {
3020
+ label: oData
3021
+ };
3022
+ } else {
3023
+ if (oData.style) {
3024
+ this.labelStyle = oData.style;
3025
+ }
3026
+ }
3027
+
3028
+ this.label = oData.label;
3029
+
3030
+ this.labelElId = "ygtvlabelel" + this.index;
3031
+
3032
+ },
3033
+
3034
+ /**
3035
+ * Returns the label element
3036
+ * @for YAHOO.widget.TextNode
3037
+ * @method getLabelEl
3038
+ * @return {object} the element
3039
+ */
3040
+ getLabelEl: function() {
3041
+ return Dom.get(this.labelElId);
3042
+ },
3043
+
3044
+ // overrides YAHOO.widget.Node
3045
+ getContentHtml: function() {
3046
+ var sb = [];
3047
+ sb[sb.length] = this.href?'<a':'<span';
3048
+ sb[sb.length] = ' id="' + this.labelElId + '"';
3049
+ sb[sb.length] = ' class="' + this.labelStyle + '"';
3050
+ if (this.href) {
3051
+ sb[sb.length] = ' href="' + this.href + '"';
3052
+ sb[sb.length] = ' target="' + this.target + '"';
3053
+ }
3054
+ if (this.title) {
3055
+ sb[sb.length] = ' title="' + this.title + '"';
3056
+ }
3057
+ sb[sb.length] = ' >';
3058
+ sb[sb.length] = this.label;
3059
+ sb[sb.length] = this.href?'</a>':'</span>';
3060
+ return sb.join("");
3061
+ },
3062
+
3063
+
3064
+
3065
+ /**
3066
+ * Returns an object which could be used to build a tree out of this node and its children.
3067
+ * It can be passed to the tree constructor to reproduce this node as a tree.
3068
+ * It will return false if the node or any descendant loads dynamically, regardless of whether it is loaded or not.
3069
+ * @method getNodeDefinition
3070
+ * @return {Object | false} definition of the tree or false if this node or any descendant is defined as dynamic
3071
+ */
3072
+ getNodeDefinition: function() {
3073
+ var def = YAHOO.widget.TextNode.superclass.getNodeDefinition.call(this);
3074
+ if (def === false) { return false; }
3075
+
3076
+ // Node specific properties
3077
+ def.label = this.label;
3078
+ if (this.labelStyle != 'ygtvlabel') { def.style = this.labelStyle; }
3079
+ if (this.title) { def.title = this.title; }
3080
+ if (this.href) { def.href = this.href; }
3081
+ if (this.target != '_self') { def.target = this.target; }
3082
+
3083
+ return def;
3084
+
3085
+ },
3086
+
3087
+ toString: function() {
3088
+ return YAHOO.widget.TextNode.superclass.toString.call(this) + ": " + this.label;
3089
+ },
3090
+
3091
+ // deprecated
3092
+ onLabelClick: function() {
3093
+ return false;
3094
+ },
3095
+ refresh: function() {
3096
+ YAHOO.widget.TextNode.superclass.refresh.call(this);
3097
+ var label = this.getLabelEl();
3098
+ label.innerHTML = this.label;
3099
+ if (label.tagName.toUpperCase() == 'A') {
3100
+ label.href = this.href;
3101
+ label.target = this.target;
3102
+ }
3103
+ }
3104
+
3105
+
3106
+
3107
+
3108
+ });
3109
+ })();
3110
+
3111
+ /**
3112
+ * A menu-specific implementation that differs from TextNode in that only
3113
+ * one sibling can be expanded at a time.
3114
+ * @namespace YAHOO.widget
3115
+ * @class MenuNode
3116
+ * @extends YAHOO.widget.TextNode
3117
+ * @param oData {object} a string or object containing the data that will
3118
+ * be used to render this node.
3119
+ * Providing a string is the same as providing an object with a single property named label.
3120
+ * All values in the oData will be used to set equally named properties in the node
3121
+ * as long as the node does have such properties, they are not undefined, private or functions.
3122
+ * All attributes are made available in noderef.data, which
3123
+ * can be used to store custom attributes. TreeView.getNode(s)ByProperty
3124
+ * can be used to retrieve a node by one of the attributes.
3125
+ * @param oParent {YAHOO.widget.Node} this node's parent node
3126
+ * @param expanded {boolean} the initial expanded/collapsed state (deprecated; use oData.expanded)
3127
+ * @constructor
3128
+ */
3129
+ YAHOO.widget.MenuNode = function(oData, oParent, expanded) {
3130
+ YAHOO.widget.MenuNode.superclass.constructor.call(this,oData,oParent,expanded);
3131
+
3132
+ /*
3133
+ * Menus usually allow only one branch to be open at a time.
3134
+ */
3135
+ this.multiExpand = false;
3136
+
3137
+ };
3138
+
3139
+ YAHOO.extend(YAHOO.widget.MenuNode, YAHOO.widget.TextNode, {
3140
+
3141
+ /**
3142
+ * The node type
3143
+ * @property _type
3144
+ * @private
3145
+ * @default "MenuNode"
3146
+ */
3147
+ _type: "MenuNode"
3148
+
3149
+ });
3150
+
3151
+ (function () {
3152
+ var Dom = YAHOO.util.Dom,
3153
+ Lang = YAHOO.lang,
3154
+ Event = YAHOO.util.Event;
3155
+
3156
+ /**
3157
+ * This implementation takes either a string or object for the
3158
+ * oData argument. If is it a string, it will use it for the display
3159
+ * of this node (and it can contain any html code). If the parameter
3160
+ * is an object,it looks for a parameter called "html" that will be
3161
+ * used for this node's display.
3162
+ * @namespace YAHOO.widget
3163
+ * @class HTMLNode
3164
+ * @extends YAHOO.widget.Node
3165
+ * @constructor
3166
+ * @param oData {object} a string or object containing the data that will
3167
+ * be used to render this node.
3168
+ * Providing a string is the same as providing an object with a single property named html.
3169
+ * All values in the oData will be used to set equally named properties in the node
3170
+ * as long as the node does have such properties, they are not undefined, private or functions.
3171
+ * All other attributes are made available in noderef.data, which
3172
+ * can be used to store custom attributes. TreeView.getNode(s)ByProperty
3173
+ * can be used to retrieve a node by one of the attributes.
3174
+ * @param oParent {YAHOO.widget.Node} this node's parent node
3175
+ * @param expanded {boolean} the initial expanded/collapsed state (deprecated; use oData.expanded)
3176
+ * @param hasIcon {boolean} specifies whether or not leaf nodes should
3177
+ * be rendered with or without a horizontal line line and/or toggle icon. If the icon
3178
+ * is not displayed, the content fills the space it would have occupied.
3179
+ * This option operates independently of the leaf node presentation logic
3180
+ * for dynamic nodes.
3181
+ * (deprecated; use oData.hasIcon)
3182
+ */
3183
+ YAHOO.widget.HTMLNode = function(oData, oParent, expanded, hasIcon) {
3184
+ if (oData) {
3185
+ this.init(oData, oParent, expanded);
3186
+ this.initContent(oData, hasIcon);
3187
+ }
3188
+ };
3189
+
3190
+ YAHOO.extend(YAHOO.widget.HTMLNode, YAHOO.widget.Node, {
3191
+
3192
+ /**
3193
+ * The CSS class for the html content container. Defaults to ygtvhtml, but
3194
+ * can be overridden to provide a custom presentation for a specific node.
3195
+ * @property contentStyle
3196
+ * @type string
3197
+ */
3198
+ contentStyle: "ygtvhtml",
3199
+
3200
+
3201
+ /**
3202
+ * The HTML content to use for this node's display
3203
+ * @property html
3204
+ * @type string
3205
+ */
3206
+ html: null,
3207
+
3208
+ /**
3209
+ * The node type
3210
+ * @property _type
3211
+ * @private
3212
+ * @type string
3213
+ * @default "HTMLNode"
3214
+ */
3215
+ _type: "HTMLNode",
3216
+
3217
+ /**
3218
+ * Sets up the node label
3219
+ * @property initContent
3220
+ * @param oData {object} An html string or object containing an html property
3221
+ * @param hasIcon {boolean} determines if the node will be rendered with an
3222
+ * icon or not
3223
+ */
3224
+ initContent: function(oData, hasIcon) {
3225
+ this.setHtml(oData);
3226
+ this.contentElId = "ygtvcontentel" + this.index;
3227
+ if (!Lang.isUndefined(hasIcon)) { this.hasIcon = hasIcon; }
3228
+
3229
+ },
3230
+
3231
+ /**
3232
+ * Synchronizes the node.html, and the node's content
3233
+ * @property setHtml
3234
+ * @param o {object} An html string or object containing an html property
3235
+ */
3236
+ setHtml: function(o) {
3237
+
3238
+ this.html = (typeof o === "string") ? o : o.html;
3239
+
3240
+ var el = this.getContentEl();
3241
+ if (el) {
3242
+ el.innerHTML = this.html;
3243
+ }
3244
+
3245
+ },
3246
+
3247
+ // overrides YAHOO.widget.Node
3248
+ getContentHtml: function() {
3249
+ return this.html;
3250
+ },
3251
+
3252
+ /**
3253
+ * Returns an object which could be used to build a tree out of this node and its children.
3254
+ * It can be passed to the tree constructor to reproduce this node as a tree.
3255
+ * It will return false if any node loads dynamically, regardless of whether it is loaded or not.
3256
+ * @method getNodeDefinition
3257
+ * @return {Object | false} definition of the tree or false if any node is defined as dynamic
3258
+ */
3259
+ getNodeDefinition: function() {
3260
+ var def = YAHOO.widget.HTMLNode.superclass.getNodeDefinition.call(this);
3261
+ if (def === false) { return false; }
3262
+ def.html = this.html;
3263
+ return def;
3264
+
3265
+ }
3266
+ });
3267
+ })();
3268
+
3269
+ (function () {
3270
+ var Dom = YAHOO.util.Dom,
3271
+ Lang = YAHOO.lang,
3272
+ Event = YAHOO.util.Event,
3273
+ Calendar = YAHOO.widget.Calendar;
3274
+
3275
+ /**
3276
+ * A Date-specific implementation that differs from TextNode in that it uses
3277
+ * YAHOO.widget.Calendar as an in-line editor, if available
3278
+ * If Calendar is not available, it behaves as a plain TextNode.
3279
+ * @namespace YAHOO.widget
3280
+ * @class DateNode
3281
+ * @extends YAHOO.widget.TextNode
3282
+ * @param oData {object} a string or object containing the data that will
3283
+ * be used to render this node.
3284
+ * Providing a string is the same as providing an object with a single property named label.
3285
+ * All values in the oData will be used to set equally named properties in the node
3286
+ * as long as the node does have such properties, they are not undefined, private nor functions.
3287
+ * All attributes are made available in noderef.data, which
3288
+ * can be used to store custom attributes. TreeView.getNode(s)ByProperty
3289
+ * can be used to retrieve a node by one of the attributes.
3290
+ * @param oParent {YAHOO.widget.Node} this node's parent node
3291
+ * @param expanded {boolean} the initial expanded/collapsed state (deprecated; use oData.expanded)
3292
+ * @constructor
3293
+ */
3294
+ YAHOO.widget.DateNode = function(oData, oParent, expanded) {
3295
+ YAHOO.widget.DateNode.superclass.constructor.call(this,oData, oParent, expanded);
3296
+ };
3297
+
3298
+ YAHOO.extend(YAHOO.widget.DateNode, YAHOO.widget.TextNode, {
3299
+
3300
+ /**
3301
+ * The node type
3302
+ * @property _type
3303
+ * @type string
3304
+ * @private
3305
+ * @default "DateNode"
3306
+ */
3307
+ _type: "DateNode",
3308
+
3309
+ /**
3310
+ * Configuration object for the Calendar editor, if used.
3311
+ * See <a href="http://developer.yahoo.com/yui/calendar/#internationalization">http://developer.yahoo.com/yui/calendar/#internationalization</a>
3312
+ * @property calendarConfig
3313
+ */
3314
+ calendarConfig: null,
3315
+
3316
+
3317
+
3318
+ /**
3319
+ * If YAHOO.widget.Calendar is available, it will pop up a Calendar to enter a new date. Otherwise, it falls back to a plain &lt;input&gt; textbox
3320
+ * @method fillEditorContainer
3321
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3322
+ * @return void
3323
+ */
3324
+ fillEditorContainer: function (editorData) {
3325
+
3326
+ var cal, container = editorData.inputContainer;
3327
+
3328
+ if (Lang.isUndefined(Calendar)) {
3329
+ Dom.replaceClass(editorData.editorPanel,'ygtv-edit-DateNode','ygtv-edit-TextNode');
3330
+ YAHOO.widget.DateNode.superclass.fillEditorContainer.call(this, editorData);
3331
+ return;
3332
+ }
3333
+
3334
+ if (editorData.nodeType != this._type) {
3335
+ editorData.nodeType = this._type;
3336
+ editorData.saveOnEnter = false;
3337
+
3338
+ editorData.node.destroyEditorContents(editorData);
3339
+
3340
+ editorData.inputObject = cal = new Calendar(container.appendChild(document.createElement('div')));
3341
+ if (this.calendarConfig) {
3342
+ cal.cfg.applyConfig(this.calendarConfig,true);
3343
+ cal.cfg.fireQueue();
3344
+ }
3345
+ cal.selectEvent.subscribe(function () {
3346
+ this.tree._closeEditor(true);
3347
+ },this,true);
3348
+ } else {
3349
+ cal = editorData.inputObject;
3350
+ }
3351
+
3352
+ editorData.oldValue = this.label;
3353
+ cal.cfg.setProperty("selected",this.label, false);
3354
+
3355
+ var delim = cal.cfg.getProperty('DATE_FIELD_DELIMITER');
3356
+ var pageDate = this.label.split(delim);
3357
+ cal.cfg.setProperty('pagedate',pageDate[cal.cfg.getProperty('MDY_MONTH_POSITION') -1] + delim + pageDate[cal.cfg.getProperty('MDY_YEAR_POSITION') -1]);
3358
+ cal.cfg.fireQueue();
3359
+
3360
+ cal.render();
3361
+ cal.oDomContainer.focus();
3362
+ },
3363
+ /**
3364
+ * Returns the value from the input element.
3365
+ * Overrides Node.getEditorValue.
3366
+ * @method getEditorValue
3367
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3368
+ * @return {string} date entered
3369
+ */
3370
+
3371
+ getEditorValue: function (editorData) {
3372
+ if (Lang.isUndefined(Calendar)) {
3373
+ return editorData.inputElement.value;
3374
+ } else {
3375
+ var cal = editorData.inputObject,
3376
+ date = cal.getSelectedDates()[0],
3377
+ dd = [];
3378
+
3379
+ dd[cal.cfg.getProperty('MDY_DAY_POSITION') -1] = date.getDate();
3380
+ dd[cal.cfg.getProperty('MDY_MONTH_POSITION') -1] = date.getMonth() + 1;
3381
+ dd[cal.cfg.getProperty('MDY_YEAR_POSITION') -1] = date.getFullYear();
3382
+ return dd.join(cal.cfg.getProperty('DATE_FIELD_DELIMITER'));
3383
+ }
3384
+ },
3385
+
3386
+ /**
3387
+ * Finally displays the newly entered date in the tree.
3388
+ * Overrides Node.displayEditedValue.
3389
+ * @method displayEditedValue
3390
+ * @param value {string} date to be displayed and stored in the node
3391
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3392
+ */
3393
+ displayEditedValue: function (value,editorData) {
3394
+ var node = editorData.node;
3395
+ node.label = value;
3396
+ node.getLabelEl().innerHTML = value;
3397
+ },
3398
+ /**
3399
+ * Returns an object which could be used to build a tree out of this node and its children.
3400
+ * It can be passed to the tree constructor to reproduce this node as a tree.
3401
+ * It will return false if the node or any descendant loads dynamically, regardless of whether it is loaded or not.
3402
+ * @method getNodeDefinition
3403
+ * @return {Object | false} definition of the node or false if this node or any descendant is defined as dynamic
3404
+ */
3405
+ getNodeDefinition: function() {
3406
+ var def = YAHOO.widget.DateNode.superclass.getNodeDefinition.call(this);
3407
+ if (def === false) { return false; }
3408
+ if (this.calendarConfig) { def.calendarConfig = this.calendarConfig; }
3409
+ return def;
3410
+ }
3411
+
3412
+
3413
+ });
3414
+ })();
3415
+
3416
+ (function () {
3417
+ var Dom = YAHOO.util.Dom,
3418
+ Lang = YAHOO.lang,
3419
+ Event = YAHOO.util.Event,
3420
+ TV = YAHOO.widget.TreeView,
3421
+ TVproto = TV.prototype;
3422
+
3423
+ /**
3424
+ * An object to store information used for in-line editing
3425
+ * for all Nodes of all TreeViews. It contains:
3426
+ * <ul>
3427
+ * <li>active {boolean}, whether there is an active cell editor </li>
3428
+ * <li>whoHasIt {YAHOO.widget.TreeView} TreeView instance that is currently using the editor</li>
3429
+ * <li>nodeType {string} value of static Node._type property, allows reuse of input element if node is of the same type.</li>
3430
+ * <li>editorPanel {HTMLelement (&lt;div&gt;)} element holding the in-line editor</li>
3431
+ * <li>inputContainer {HTMLelement (&lt;div&gt;)} element which will hold the type-specific input element(s) to be filled by the fillEditorContainer method</li>
3432
+ * <li>buttonsContainer {HTMLelement (&lt;div&gt;)} element which holds the &lt;button&gt; elements for Ok/Cancel. If you don't want any of the buttons, hide it via CSS styles, don't destroy it</li>
3433
+ * <li>node {YAHOO.widget.Node} reference to the Node being edited</li>
3434
+ * <li>saveOnEnter {boolean}, whether the Enter key should be accepted as a Save command (Esc. is always taken as Cancel), disable for multi-line input elements </li>
3435
+ * <li>oldValue {any} value before editing</li>
3436
+ * </ul>
3437
+ * Editors are free to use this object to store additional data.
3438
+ * @property editorData
3439
+ * @static
3440
+ * @for YAHOO.widget.TreeView
3441
+ */
3442
+ TV.editorData = {
3443
+ active:false,
3444
+ whoHasIt:null, // which TreeView has it
3445
+ nodeType:null,
3446
+ editorPanel:null,
3447
+ inputContainer:null,
3448
+ buttonsContainer:null,
3449
+ node:null, // which Node is being edited
3450
+ saveOnEnter:true,
3451
+ oldValue:undefined
3452
+ // Each node type is free to add its own properties to this as it sees fit.
3453
+ };
3454
+
3455
+ /**
3456
+ * Validator function for edited data, called from the TreeView instance scope,
3457
+ * receives the arguments (newValue, oldValue, nodeInstance)
3458
+ * and returns either the validated (or type-converted) value or undefined.
3459
+ * An undefined return will prevent the editor from closing
3460
+ * @property validator
3461
+ * @type function
3462
+ * @default null
3463
+ * @for YAHOO.widget.TreeView
3464
+ */
3465
+ TVproto.validator = null;
3466
+
3467
+ /**
3468
+ * Entry point for initializing the editing plug-in.
3469
+ * TreeView will call this method on initializing if it exists
3470
+ * @method _initEditor
3471
+ * @for YAHOO.widget.TreeView
3472
+ * @private
3473
+ */
3474
+
3475
+ TVproto._initEditor = function () {
3476
+ /**
3477
+ * Fires when the user clicks on the ok button of a node editor
3478
+ * @event editorSaveEvent
3479
+ * @type CustomEvent
3480
+ * @param oArgs.newValue {mixed} the new value just entered
3481
+ * @param oArgs.oldValue {mixed} the value originally in the tree
3482
+ * @param oArgs.node {YAHOO.widget.Node} the node that has the focus
3483
+ * @for YAHOO.widget.TreeView
3484
+ */
3485
+ this.createEvent("editorSaveEvent", this);
3486
+
3487
+ /**
3488
+ * Fires when the user clicks on the cancel button of a node editor
3489
+ * @event editorCancelEvent
3490
+ * @type CustomEvent
3491
+ * @param {YAHOO.widget.Node} node the node that has the focus
3492
+ * @for YAHOO.widget.TreeView
3493
+ */
3494
+ this.createEvent("editorCancelEvent", this);
3495
+
3496
+ };
3497
+
3498
+ /**
3499
+ * Entry point of the editing plug-in.
3500
+ * TreeView will call this method if it exists when a node label is clicked
3501
+ * @method _nodeEditing
3502
+ * @param node {YAHOO.widget.Node} the node to be edited
3503
+ * @return {Boolean} true to indicate that the node is editable and prevent any further bubbling of the click.
3504
+ * @for YAHOO.widget.TreeView
3505
+ * @private
3506
+ */
3507
+
3508
+
3509
+
3510
+ TVproto._nodeEditing = function (node) {
3511
+ if (node.fillEditorContainer && node.editable) {
3512
+ var ed, topLeft, buttons, button, editorData = TV.editorData;
3513
+ editorData.active = true;
3514
+ editorData.whoHasIt = this;
3515
+ if (!editorData.nodeType) {
3516
+ editorData.editorPanel = ed = document.body.appendChild(document.createElement('div'));
3517
+ Dom.addClass(ed,'ygtv-label-editor');
3518
+
3519
+ buttons = editorData.buttonsContainer = ed.appendChild(document.createElement('div'));
3520
+ Dom.addClass(buttons,'ygtv-button-container');
3521
+ button = buttons.appendChild(document.createElement('button'));
3522
+ Dom.addClass(button,'ygtvok');
3523
+ button.innerHTML = ' ';
3524
+ button = buttons.appendChild(document.createElement('button'));
3525
+ Dom.addClass(button,'ygtvcancel');
3526
+ button.innerHTML = ' ';
3527
+ Event.on(buttons, 'click', function (ev) {
3528
+ var target = Event.getTarget(ev);
3529
+ var node = TV.editorData.node;
3530
+ if (Dom.hasClass(target,'ygtvok')) {
3531
+ Event.stopEvent(ev);
3532
+ this._closeEditor(true);
3533
+ }
3534
+ if (Dom.hasClass(target,'ygtvcancel')) {
3535
+ Event.stopEvent(ev);
3536
+ this._closeEditor(false);
3537
+ }
3538
+ }, this, true);
3539
+
3540
+ editorData.inputContainer = ed.appendChild(document.createElement('div'));
3541
+ Dom.addClass(editorData.inputContainer,'ygtv-input');
3542
+
3543
+ Event.on(ed,'keydown',function (ev) {
3544
+ var editorData = TV.editorData,
3545
+ KEY = YAHOO.util.KeyListener.KEY;
3546
+ switch (ev.keyCode) {
3547
+ case KEY.ENTER:
3548
+ Event.stopEvent(ev);
3549
+ if (editorData.saveOnEnter) {
3550
+ this._closeEditor(true);
3551
+ }
3552
+ break;
3553
+ case KEY.ESCAPE:
3554
+ Event.stopEvent(ev);
3555
+ this._closeEditor(false);
3556
+ break;
3557
+ }
3558
+ },this,true);
3559
+
3560
+
3561
+
3562
+ } else {
3563
+ ed = editorData.editorPanel;
3564
+ }
3565
+ editorData.node = node;
3566
+ if (editorData.nodeType) {
3567
+ Dom.removeClass(ed,'ygtv-edit-' + editorData.nodeType);
3568
+ }
3569
+ Dom.addClass(ed,' ygtv-edit-' + node._type);
3570
+ topLeft = Dom.getXY(node.getContentEl());
3571
+ Dom.setStyle(ed,'left',topLeft[0] + 'px');
3572
+ Dom.setStyle(ed,'top',topLeft[1] + 'px');
3573
+ Dom.setStyle(ed,'display','block');
3574
+ ed.focus();
3575
+ node.fillEditorContainer(editorData);
3576
+
3577
+ return true; // If inline editor available, don't do anything else.
3578
+ }
3579
+ };
3580
+
3581
+ /**
3582
+ * Method to be associated with an event (clickEvent, dblClickEvent or enterKeyPressed) to pop up the contents editor
3583
+ * It calls the corresponding node editNode method.
3584
+ * @method onEventEditNode
3585
+ * @param oArgs {object} Object passed as arguments to TreeView event listeners
3586
+ * @for YAHOO.widget.TreeView
3587
+ */
3588
+
3589
+ TVproto.onEventEditNode = function (oArgs) {
3590
+ if (oArgs instanceof YAHOO.widget.Node) {
3591
+ oArgs.editNode();
3592
+ } else if (oArgs.node instanceof YAHOO.widget.Node) {
3593
+ oArgs.node.editNode();
3594
+ }
3595
+ };
3596
+
3597
+ /**
3598
+ * Method to be called when the inline editing is finished and the editor is to be closed
3599
+ * @method _closeEditor
3600
+ * @param save {Boolean} true if the edited value is to be saved, false if discarded
3601
+ * @private
3602
+ * @for YAHOO.widget.TreeView
3603
+ */
3604
+
3605
+ TVproto._closeEditor = function (save) {
3606
+ var ed = TV.editorData,
3607
+ node = ed.node,
3608
+ close = true;
3609
+ if (save) {
3610
+ close = ed.node.saveEditorValue(ed) !== false;
3611
+ } else {
3612
+ this.fireEvent( 'editorCancelEvent', node);
3613
+ }
3614
+
3615
+ if (close) {
3616
+ Dom.setStyle(ed.editorPanel,'display','none');
3617
+ ed.active = false;
3618
+ node.focus();
3619
+ }
3620
+ };
3621
+
3622
+ /**
3623
+ * Entry point for TreeView's destroy method to destroy whatever the editing plug-in has created
3624
+ * @method _destroyEditor
3625
+ * @private
3626
+ * @for YAHOO.widget.TreeView
3627
+ */
3628
+ TVproto._destroyEditor = function() {
3629
+ var ed = TV.editorData;
3630
+ if (ed && ed.nodeType && (!ed.active || ed.whoHasIt === this)) {
3631
+ Event.removeListener(ed.editorPanel,'keydown');
3632
+ Event.removeListener(ed.buttonContainer,'click');
3633
+ ed.node.destroyEditorContents(ed);
3634
+ document.body.removeChild(ed.editorPanel);
3635
+ ed.nodeType = ed.editorPanel = ed.inputContainer = ed.buttonsContainer = ed.whoHasIt = ed.node = null;
3636
+ ed.active = false;
3637
+ }
3638
+ };
3639
+
3640
+ var Nproto = YAHOO.widget.Node.prototype;
3641
+
3642
+ /**
3643
+ * Signals if the label is editable. (Ignored on TextNodes with href set.)
3644
+ * @property editable
3645
+ * @type boolean
3646
+ * @for YAHOO.widget.Node
3647
+ */
3648
+ Nproto.editable = false;
3649
+
3650
+ /**
3651
+ * pops up the contents editor, if there is one and the node is declared editable
3652
+ * @method editNode
3653
+ * @for YAHOO.widget.Node
3654
+ */
3655
+
3656
+ Nproto.editNode = function () {
3657
+ this.tree._nodeEditing(this);
3658
+ };
3659
+
3660
+
3661
+
3662
+
3663
+ /** Placeholder for a function that should provide the inline node label editor.
3664
+ * Leaving it set to null will indicate that this node type is not editable.
3665
+ * It should be overridden by nodes that provide inline editing.
3666
+ * The Node-specific editing element (input box, textarea or whatever) should be inserted into editorData.inputContainer.
3667
+ * @method fillEditorContainer
3668
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3669
+ * @return void
3670
+ * @for YAHOO.widget.Node
3671
+ */
3672
+ Nproto.fillEditorContainer = null;
3673
+
3674
+
3675
+ /**
3676
+ * Node-specific destroy function to empty the contents of the inline editor panel.
3677
+ * This function is the worst case alternative that will purge all possible events and remove the editor contents.
3678
+ * Method Event.purgeElement is somewhat costly so if it can be replaced by specifc Event.removeListeners, it is better to do so.
3679
+ * @method destroyEditorContents
3680
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3681
+ * @for YAHOO.widget.Node
3682
+ */
3683
+ Nproto.destroyEditorContents = function (editorData) {
3684
+ // In the worst case, if the input editor (such as the Calendar) has no destroy method
3685
+ // we can only try to remove all possible events on it.
3686
+ Event.purgeElement(editorData.inputContainer,true);
3687
+ editorData.inputContainer.innerHTML = '';
3688
+ };
3689
+
3690
+ /**
3691
+ * Saves the value entered into the editor.
3692
+ * @method saveEditorValue
3693
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3694
+ * @return {false or none} a return of exactly false will prevent the editor from closing
3695
+ * @for YAHOO.widget.Node
3696
+ */
3697
+ Nproto.saveEditorValue = function (editorData) {
3698
+ var node = editorData.node,
3699
+ value,
3700
+ validator = node.tree.validator;
3701
+
3702
+ value = this.getEditorValue(editorData);
3703
+
3704
+ if (Lang.isFunction(validator)) {
3705
+ value = validator(value,editorData.oldValue,node);
3706
+ if (Lang.isUndefined(value)) {
3707
+ return false;
3708
+ }
3709
+ }
3710
+
3711
+ if (this.tree.fireEvent( 'editorSaveEvent', {
3712
+ newValue:value,
3713
+ oldValue:editorData.oldValue,
3714
+ node:node
3715
+ }) !== false) {
3716
+ this.displayEditedValue(value,editorData);
3717
+ }
3718
+ };
3719
+
3720
+
3721
+ /**
3722
+ * Returns the value(s) from the input element(s) .
3723
+ * Should be overridden by each node type.
3724
+ * @method getEditorValue
3725
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3726
+ * @return {any} value entered
3727
+ * @for YAHOO.widget.Node
3728
+ */
3729
+
3730
+ Nproto.getEditorValue = function (editorData) {
3731
+ };
3732
+
3733
+ /**
3734
+ * Finally displays the newly edited value(s) in the tree.
3735
+ * Should be overridden by each node type.
3736
+ * @method displayEditedValue
3737
+ * @param value {any} value to be displayed and stored in the node
3738
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3739
+ * @for YAHOO.widget.Node
3740
+ */
3741
+ Nproto.displayEditedValue = function (value,editorData) {
3742
+ };
3743
+
3744
+ var TNproto = YAHOO.widget.TextNode.prototype;
3745
+
3746
+
3747
+
3748
+ /**
3749
+ * Places an &lt;input&gt; textbox in the input container and loads the label text into it.
3750
+ * @method fillEditorContainer
3751
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3752
+ * @return void
3753
+ * @for YAHOO.widget.TextNode
3754
+ */
3755
+ TNproto.fillEditorContainer = function (editorData) {
3756
+
3757
+ var input;
3758
+ // If last node edited is not of the same type as this one, delete it and fill it with our editor
3759
+ if (editorData.nodeType != this._type) {
3760
+ editorData.nodeType = this._type;
3761
+ editorData.saveOnEnter = true;
3762
+ editorData.node.destroyEditorContents(editorData);
3763
+
3764
+ editorData.inputElement = input = editorData.inputContainer.appendChild(document.createElement('input'));
3765
+
3766
+ } else {
3767
+ // if the last node edited was of the same time, reuse the input element.
3768
+ input = editorData.inputElement;
3769
+ }
3770
+ editorData.oldValue = this.label;
3771
+ input.value = this.label;
3772
+ input.focus();
3773
+ input.select();
3774
+ };
3775
+
3776
+ /**
3777
+ * Returns the value from the input element.
3778
+ * Overrides Node.getEditorValue.
3779
+ * @method getEditorValue
3780
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3781
+ * @return {string} value entered
3782
+ * @for YAHOO.widget.TextNode
3783
+ */
3784
+
3785
+ TNproto.getEditorValue = function (editorData) {
3786
+ return editorData.inputElement.value;
3787
+ };
3788
+
3789
+ /**
3790
+ * Finally displays the newly edited value in the tree.
3791
+ * Overrides Node.displayEditedValue.
3792
+ * @method displayEditedValue
3793
+ * @param value {string} value to be displayed and stored in the node
3794
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3795
+ * @for YAHOO.widget.TextNode
3796
+ */
3797
+ TNproto.displayEditedValue = function (value,editorData) {
3798
+ var node = editorData.node;
3799
+ node.label = value;
3800
+ node.getLabelEl().innerHTML = value;
3801
+ };
3802
+
3803
+ /**
3804
+ * Destroys the contents of the inline editor panel.
3805
+ * Overrides Node.destroyEditorContent.
3806
+ * Since we didn't set any event listeners on this inline editor, it is more efficient to avoid the generic method in Node.
3807
+ * @method destroyEditorContents
3808
+ * @param editorData {YAHOO.widget.TreeView.editorData} a shortcut to the static object holding editing information
3809
+ * @for YAHOO.widget.TextNode
3810
+ */
3811
+ TNproto.destroyEditorContents = function (editorData) {
3812
+ editorData.inputContainer.innerHTML = '';
3813
+ };
3814
+ })();
3815
+
3816
+ /**
3817
+ * A static factory class for tree view expand/collapse animations
3818
+ * @class TVAnim
3819
+ * @static
3820
+ */
3821
+ YAHOO.widget.TVAnim = function() {
3822
+ return {
3823
+ /**
3824
+ * Constant for the fade in animation
3825
+ * @property FADE_IN
3826
+ * @type string
3827
+ * @static
3828
+ */
3829
+ FADE_IN: "TVFadeIn",
3830
+
3831
+ /**
3832
+ * Constant for the fade out animation
3833
+ * @property FADE_OUT
3834
+ * @type string
3835
+ * @static
3836
+ */
3837
+ FADE_OUT: "TVFadeOut",
3838
+
3839
+ /**
3840
+ * Returns a ygAnim instance of the given type
3841
+ * @method getAnim
3842
+ * @param type {string} the type of animation
3843
+ * @param el {HTMLElement} the element to element (probably the children div)
3844
+ * @param callback {function} function to invoke when the animation is done.
3845
+ * @return {YAHOO.util.Animation} the animation instance
3846
+ * @static
3847
+ */
3848
+ getAnim: function(type, el, callback) {
3849
+ if (YAHOO.widget[type]) {
3850
+ return new YAHOO.widget[type](el, callback);
3851
+ } else {
3852
+ return null;
3853
+ }
3854
+ },
3855
+
3856
+ /**
3857
+ * Returns true if the specified animation class is available
3858
+ * @method isValid
3859
+ * @param type {string} the type of animation
3860
+ * @return {boolean} true if valid, false if not
3861
+ * @static
3862
+ */
3863
+ isValid: function(type) {
3864
+ return (YAHOO.widget[type]);
3865
+ }
3866
+ };
3867
+ } ();
3868
+
3869
+ /**
3870
+ * A 1/2 second fade-in animation.
3871
+ * @class TVFadeIn
3872
+ * @constructor
3873
+ * @param el {HTMLElement} the element to animate
3874
+ * @param callback {function} function to invoke when the animation is finished
3875
+ */
3876
+ YAHOO.widget.TVFadeIn = function(el, callback) {
3877
+ /**
3878
+ * The element to animate
3879
+ * @property el
3880
+ * @type HTMLElement
3881
+ */
3882
+ this.el = el;
3883
+
3884
+ /**
3885
+ * the callback to invoke when the animation is complete
3886
+ * @property callback
3887
+ * @type function
3888
+ */
3889
+ this.callback = callback;
3890
+
3891
+ };
3892
+
3893
+ YAHOO.widget.TVFadeIn.prototype = {
3894
+ /**
3895
+ * Performs the animation
3896
+ * @method animate
3897
+ */
3898
+ animate: function() {
3899
+ var tvanim = this;
3900
+
3901
+ var s = this.el.style;
3902
+ s.opacity = 0.1;
3903
+ s.filter = "alpha(opacity=10)";
3904
+ s.display = "";
3905
+
3906
+ var dur = 0.4;
3907
+ var a = new YAHOO.util.Anim(this.el, {opacity: {from: 0.1, to: 1, unit:""}}, dur);
3908
+ a.onComplete.subscribe( function() { tvanim.onComplete(); } );
3909
+ a.animate();
3910
+ },
3911
+
3912
+ /**
3913
+ * Clean up and invoke callback
3914
+ * @method onComplete
3915
+ */
3916
+ onComplete: function() {
3917
+ this.callback();
3918
+ },
3919
+
3920
+ /**
3921
+ * toString
3922
+ * @method toString
3923
+ * @return {string} the string representation of the instance
3924
+ */
3925
+ toString: function() {
3926
+ return "TVFadeIn";
3927
+ }
3928
+ };
3929
+
3930
+ /**
3931
+ * A 1/2 second fade out animation.
3932
+ * @class TVFadeOut
3933
+ * @constructor
3934
+ * @param el {HTMLElement} the element to animate
3935
+ * @param callback {Function} function to invoke when the animation is finished
3936
+ */
3937
+ YAHOO.widget.TVFadeOut = function(el, callback) {
3938
+ /**
3939
+ * The element to animate
3940
+ * @property el
3941
+ * @type HTMLElement
3942
+ */
3943
+ this.el = el;
3944
+
3945
+ /**
3946
+ * the callback to invoke when the animation is complete
3947
+ * @property callback
3948
+ * @type function
3949
+ */
3950
+ this.callback = callback;
3951
+
3952
+ };
3953
+
3954
+ YAHOO.widget.TVFadeOut.prototype = {
3955
+ /**
3956
+ * Performs the animation
3957
+ * @method animate
3958
+ */
3959
+ animate: function() {
3960
+ var tvanim = this;
3961
+ var dur = 0.4;
3962
+ var a = new YAHOO.util.Anim(this.el, {opacity: {from: 1, to: 0.1, unit:""}}, dur);
3963
+ a.onComplete.subscribe( function() { tvanim.onComplete(); } );
3964
+ a.animate();
3965
+ },
3966
+
3967
+ /**
3968
+ * Clean up and invoke callback
3969
+ * @method onComplete
3970
+ */
3971
+ onComplete: function() {
3972
+ var s = this.el.style;
3973
+ s.display = "none";
3974
+ s.opacity = 1;
3975
+ s.filter = "alpha(opacity=100)";
3976
+ this.callback();
3977
+ },
3978
+
3979
+ /**
3980
+ * toString
3981
+ * @method toString
3982
+ * @return {string} the string representation of the instance
3983
+ */
3984
+ toString: function() {
3985
+ return "TVFadeOut";
3986
+ }
3987
+ };
3988
+
3989
+ YAHOO.register("treeview", YAHOO.widget.TreeView, {version: "2.8.1", build: "19"});