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 P;YAHOO.widget.Carousel=function(s,r){YAHOO.widget.Carousel.superclass.constructor.call(this,s,r);};var U=YAHOO.widget.Carousel,e=YAHOO.util.Dom,c=YAHOO.util.Event,p=YAHOO.lang;P="Carousel";var T={},F="afterScroll",g="allItemsRemoved",b="beforeHide",J="beforePageChange",i="beforeScroll",Y="beforeShow",B="blur",X="focus",a="hide",S="itemAdded",o="itemRemoved",Q="itemReplaced",C="itemSelected",L="loadItems",I="navigationStateChange",h="pageChange",H="render",V="show",Z="startAutoPlay",q="stopAutoPlay",K="uiUpdate";function G(r,s){var t;for(t in s){if(s.hasOwnProperty(t)){e.setStyle(r,t,s[t]);}}}function W(s,r){var t=document.createElement(s);r=r||{};if(r.className){e.addClass(t,r.className);}if(r.styles){G(t,r.styles);}if(r.parent){r.parent.appendChild(t);}if(r.id){t.setAttribute("id",r.id);}if(r.content){if(r.content.nodeName){t.appendChild(r.content);}else{t.innerHTML=r.content;}}return t;}function d(t,s,r){var v;if(!t){return 0;}function u(y,x){var z;if(x=="marginRight"&&YAHOO.env.ua.webkit){z=parseInt(e.getStyle(y,"marginLeft"),10);}else{z=parseInt(e.getStyle(y,x),10);}return p.isNumber(z)?z:0;}function w(y,x){var z;if(x=="marginRight"&&YAHOO.env.ua.webkit){z=parseFloat(e.getStyle(y,"marginLeft"));}else{z=parseFloat(e.getStyle(y,x));}return p.isNumber(z)?z:0;}if(typeof r=="undefined"){r="int";}switch(s){case"height":v=t.offsetHeight;if(v>0){v+=u(t,"marginTop")+u(t,"marginBottom");}else{v=w(t,"height")+u(t,"marginTop")+u(t,"marginBottom")+u(t,"borderTopWidth")+u(t,"borderBottomWidth")+u(t,"paddingTop")+u(t,"paddingBottom");}break;case"width":v=t.offsetWidth;if(v>0){v+=u(t,"marginLeft")+u(t,"marginRight");}else{v=w(t,"width")+u(t,"marginLeft")+u(t,"marginRight")+u(t,"borderLeftWidth")+u(t,"borderRightWidth")+u(t,"paddingLeft")+u(t,"paddingRight");}break;default:if(r=="int"){v=u(t,s);}else{if(r=="float"){v=w(t,s);}else{v=e.getStyle(t,s);}}break;}return v;}function O(w){var u=this,x,t,s=0,v=u.get("firstVisible"),r=false;if(u._itemsTable.numItems===0){return 0;}t=u._itemsTable.items[v]||u._itemsTable.loading[v];if(p.isUndefined(t)){return 0;}x=e.get(t.id);if(typeof w=="undefined"){r=u.get("isVertical");}else{r=w=="height";}if(this._itemAttrCache[w]){return this._itemAttrCache[w];}if(r){s=d(x,"height");}else{s=d(x,"width");}this._itemAttrCache[w]=s;return s;}function N(){var s=this,t,r;t=s.get("isVertical");r=O.call(s,t?"height":"width");return(r*s.get("revealAmount")/100);}function m(w){var AH=this,z=AH._cols,v=AH._rows,u,AC,AB,t,x,AD,AJ=0,AE,s,AG,AA={},y=0,AI=AH._itemsTable,AF=AI.items,r=AI.loading;AB=AH.get("isVertical");AC=O.call(AH,AB?"height":"width");AG=N.call(AH);while(y<w){if(!AF[y]&&!r[y]){AJ++;}y++;}w-=AJ;if(v){u=this.getPageForItem(w);if(AB){x=Math.floor(w/z);AJ=x;AE=AJ*AC;AA.top=(AE+AG)+"px";AC=O.call(AH,"width");t=w%z;AJ=t;s=AJ*AC;AA.left=s+"px";}else{t=w%z;AD=(u-1)*z;AJ=t+AD;s=AJ*AC;AA.left=(s+AG)+"px";AC=O.call(AH,"height");x=Math.floor(w/z);AD=(u-1)*v;AJ=x-AD;AE=AJ*AC;AA.top=AE+"px";}}else{if(AB){AA.left=0;AA.top=((w*AC)+AG)+"px";}else{AA.top=0;AA.left=((w*AC)+AG)+"px";}}return AA;}function D(s){var r=this.get("numVisible");return Math.floor(s/r)*r;}function j(t){var s=0,r=0;s=O.call(this);r=s*t;return r;}function f(r,s){s.scrollPageBackward();c.preventDefault(r);}function k(r,s){s.scrollPageForward();c.preventDefault(r);}function n(w,s){var AA=this,AB=AA.CLASSES,r,y=AA._firstItem,t=AA.get("isCircular"),x=AA.get("numItems"),z=AA.get("numVisible"),v=s,u=y+z-1;if(v>=0&&v<x){if(!p.isUndefined(AA._itemsTable.items[v])){r=e.get(AA._itemsTable.items[v].id);if(r){e.removeClass(r,AB.SELECTED_ITEM);}}}if(p.isNumber(w)){w=parseInt(w,10);w=p.isNumber(w)?w:0;}else{w=y;}if(p.isUndefined(AA._itemsTable.items[w])){w=D.call(AA,w);AA.scrollTo(w);}if(!p.isUndefined(AA._itemsTable.items[w])){r=e.get(AA._itemsTable.items[w].id);if(r){e.addClass(r,AB.SELECTED_ITEM);}}if(w<y||w>u){w=D.call(AA,w);AA.scrollTo(w);}}function l(){var t=false,w=this,s=w.CLASSES,v,r,u;if(!w._hasRendered){return;}r=w.get("navigation");u=w._firstItem+w.get("numVisible");if(r.prev){if(w.get("numItems")===0||w._firstItem===0){if(w.get("numItems")===0||!w.get("isCircular")){c.removeListener(r.prev,"click",f);e.addClass(r.prev,s.FIRST_NAV_DISABLED);for(v=0;v<w._navBtns.prev.length;v++){w._navBtns.prev[v].setAttribute("disabled","true");}w._prevEnabled=false;}else{t=!w._prevEnabled;}}else{t=!w._prevEnabled;}if(t){c.on(r.prev,"click",f,w);e.removeClass(r.prev,s.FIRST_NAV_DISABLED);for(v=0;v<w._navBtns.prev.length;v++){w._navBtns.prev[v].removeAttribute("disabled");}w._prevEnabled=true;}}t=false;if(r.next){if(u>=w.get("numItems")){if(!w.get("isCircular")){c.removeListener(r.next,"click",k);e.addClass(r.next,s.DISABLED);for(v=0;v<w._navBtns.next.length;v++){w._navBtns.next[v].setAttribute("disabled","true");}w._nextEnabled=false;}else{t=!w._nextEnabled;}}else{t=!w._nextEnabled;}if(t){c.on(r.next,"click",k,w);e.removeClass(r.next,s.DISABLED);for(v=0;v<w._navBtns.next.length;v++){w._navBtns.next[v].removeAttribute("disabled");}w._nextEnabled=true;}}w.fireEvent(I,{next:w._nextEnabled,prev:w._prevEnabled});}function R(t){var u=this,r,s;if(!u._hasRendered){return;}s=u.get("numVisible");if(!p.isNumber(t)){t=Math.floor(u.get("selectedItem")/s);}r=Math.ceil(u.get("numItems")/s);u._pages.num=r;u._pages.cur=t;if(r>u.CONFIG.MAX_PAGER_BUTTONS){u._updatePagerMenu();}else{u._updatePagerButtons();}}function M(r,s){switch(s){case"height":return d(r,"marginTop")+d(r,"marginBottom")+d(r,"paddingTop")+d(r,"paddingBottom")+d(r,"borderTopWidth")+d(r,"borderBottomWidth");case"width":return d(r,"marginLeft")+d(r,"marginRight")+d(r,"paddingLeft")+d(r,"paddingRight")+d(r,"borderLeftWidth")+d(r,"borderRightWidth");default:break;}return d(r,s);}function A(s){var r=this;if(!p.isObject(s)){return;}switch(s.ev){case S:r._syncUiForItemAdd(s);break;case o:r._syncUiForItemRemove(s);break;case Q:r._syncUiForItemReplace(s);break;case L:r._syncUiForLazyLoading(s);break;}r.fireEvent(K);}function E(u,s){var w=this,v=w.get("currentPage"),t,r=w.get("numVisible");
8
+ t=parseInt(w._firstItem/r,10);if(t!=v){w.setAttributeConfig("currentPage",{value:t});w.fireEvent(h,t);}if(w.get("selectOnScroll")){if(w.get("selectedItem")!=w._selectedItem){w.set("selectedItem",w._selectedItem);}}clearTimeout(w._autoPlayTimer);delete w._autoPlayTimer;if(w.isAutoPlayOn()){w.startAutoPlay();}w.fireEvent(F,{first:w._firstItem,last:s},w);}U.getById=function(r){return T[r]?T[r].object:false;};YAHOO.extend(U,YAHOO.util.Element,{_rows:null,_cols:null,_animObj:null,_carouselEl:null,_clipEl:null,_firstItem:0,_hasFocus:false,_hasRendered:false,_isAnimationInProgress:false,_isAutoPlayInProgress:false,_itemsTable:null,_navBtns:null,_navEl:null,_nextEnabled:true,_pages:null,_pagination:{},_prevEnabled:true,_recomputeSize:true,_itemAttrCache:{},CLASSES:{BUTTON:"yui-carousel-button",CAROUSEL:"yui-carousel",CAROUSEL_EL:"yui-carousel-element",CONTAINER:"yui-carousel-container",CONTENT:"yui-carousel-content",DISABLED:"yui-carousel-button-disabled",FIRST_NAV:" yui-carousel-first-button",FIRST_NAV_DISABLED:"yui-carousel-first-button-disabled",FIRST_PAGE:"yui-carousel-nav-first-page",FOCUSSED_BUTTON:"yui-carousel-button-focus",HORIZONTAL:"yui-carousel-horizontal",ITEM_LOADING:"yui-carousel-item-loading",MIN_WIDTH:"yui-carousel-min-width",NAVIGATION:"yui-carousel-nav",NEXT_NAV:" yui-carousel-next-button",NEXT_PAGE:"yui-carousel-next",NAV_CONTAINER:"yui-carousel-buttons",PAGER_ITEM:"yui-carousel-pager-item",PAGINATION:"yui-carousel-pagination",PAGE_FOCUS:"yui-carousel-nav-page-focus",PREV_PAGE:"yui-carousel-prev",SELECTED_ITEM:"yui-carousel-item-selected",SELECTED_NAV:"yui-carousel-nav-page-selected",VERTICAL:"yui-carousel-vertical",MULTI_ROW:"yui-carousel-multi-row",ROW:"yui-carousel-row",VERTICAL_CONTAINER:"yui-carousel-vertical-container",VISIBLE:"yui-carousel-visible"},CONFIG:{FIRST_VISIBLE:0,HORZ_MIN_WIDTH:180,MAX_PAGER_BUTTONS:5,VERT_MIN_WIDTH:115,NUM_VISIBLE:3},STRINGS:{ITEM_LOADING_CONTENT:"Loading",NEXT_BUTTON_TEXT:"Next Page",PAGER_PREFIX_TEXT:"Go to page ",PREVIOUS_BUTTON_TEXT:"Previous Page"},addItem:function(y,s){var x=this,u,t,r,z=0,w,v=x.get("numItems");if(!y){return false;}if(p.isString(y)||y.nodeName){t=y.nodeName?y.innerHTML:y;}else{if(p.isObject(y)){t=y.content;}else{return false;}}u=y.className||"";r=y.id?y.id:e.generateId();if(p.isUndefined(s)){x._itemsTable.items.push({item:t,className:u,id:r});w=x._itemsTable.items.length-1;}else{if(s<0||s>v){return false;}if(!x._itemsTable.items[s]){x._itemsTable.items[s]=undefined;z=1;}x._itemsTable.items.splice(s,z,{item:t,className:u,id:r});}x._itemsTable.numItems++;if(v<x._itemsTable.items.length){x.set("numItems",x._itemsTable.items.length);}x.fireEvent(S,{pos:s,ev:S,newPos:w});return true;},addItems:function(r){var s,u,t=true;if(!p.isArray(r)){return false;}for(s=0,u=r.length;s<u;s++){if(this.addItem(r[s][0],r[s][1])===false){t=false;}}return t;},blur:function(){this._carouselEl.blur();this.fireEvent(B);},clearItems:function(){var r=this,s=r.get("numItems");while(s>0){if(!r.removeItem(0)){}if(r._itemsTable.numItems===0){r.set("numItems",0);break;}s--;}r.fireEvent(g);},focus:function(){var AA=this,v,w,x,u,z,AB,s,t,r;if(!AA._hasRendered){return;}if(AA.isAnimating()){return;}r=AA.get("selectedItem");AB=AA.get("numVisible");s=AA.get("selectOnScroll");t=(r>=0)?AA.getItem(r):null;v=AA.get("firstVisible");z=v+AB-1;x=(r<v||r>z);w=(t&&t.id)?e.get(t.id):null;u=AA._itemsTable;if(!s&&x){w=(u&&u.items&&u.items[v])?e.get(u.items[v].id):null;}if(w){try{w.focus();}catch(y){}}AA.fireEvent(X);},hide:function(){var r=this;if(r.fireEvent(b)!==false){r.removeClass(r.CLASSES.VISIBLE);r.fireEvent(a);}},init:function(u,s){var v=this,r=u,w=false,t;if(!u){return;}v._hasRendered=false;v._navBtns={prev:[],next:[]};v._pages={el:null,num:0,cur:0};v._pagination={};v._itemAttrCache={};v._itemsTable={loading:{},numItems:0,items:[],size:0};if(p.isString(u)){u=e.get(u);}else{if(!u.nodeName){return;}}U.superclass.init.call(v,u,s);t=v.get("selectedItem");if(t>0){v.set("firstVisible",D.call(v,t));}if(u){if(!u.id){u.setAttribute("id",e.generateId());}w=v._parseCarousel(u);if(!w){v._createCarousel(r);}}else{u=v._createCarousel(r);}r=u.id;v.initEvents();if(w){v._parseCarouselItems();}if(t>0){n.call(v,t,0);}if(!s||typeof s.isVertical=="undefined"){v.set("isVertical",false);}v._parseCarouselNavigation(u);v._navEl=v._setupCarouselNavigation();T[r]={object:v};v._loadItems(Math.min(v.get("firstVisible")+v.get("numVisible"),v.get("numItems"))-1);},initAttributes:function(r){var s=this;r=r||{};U.superclass.initAttributes.call(s,r);s.setAttributeConfig("carouselEl",{validator:p.isString,value:r.carouselEl||"OL"});s.setAttributeConfig("carouselItemEl",{validator:p.isString,value:r.carouselItemEl||"LI"});s.setAttributeConfig("currentPage",{readOnly:true,value:0});s.setAttributeConfig("firstVisible",{method:s._setFirstVisible,validator:s._validateFirstVisible,value:r.firstVisible||s.CONFIG.FIRST_VISIBLE});s.setAttributeConfig("selectOnScroll",{validator:p.isBoolean,value:r.selectOnScroll||true});s.setAttributeConfig("numVisible",{setter:s._numVisibleSetter,method:s._setNumVisible,validator:s._validateNumVisible,value:r.numVisible||s.CONFIG.NUM_VISIBLE});s.setAttributeConfig("numItems",{method:s._setNumItems,validator:s._validateNumItems,value:s._itemsTable.numItems});s.setAttributeConfig("scrollIncrement",{validator:s._validateScrollIncrement,value:r.scrollIncrement||1});s.setAttributeConfig("selectedItem",{setter:s._selectedItemSetter,method:s._setSelectedItem,validator:p.isNumber,value:-1});s.setAttributeConfig("revealAmount",{method:s._setRevealAmount,validator:s._validateRevealAmount,value:r.revealAmount||0});s.setAttributeConfig("isCircular",{validator:p.isBoolean,value:r.isCircular||false});s.setAttributeConfig("isVertical",{method:s._setOrientation,validator:p.isBoolean,value:r.isVertical||false});s.setAttributeConfig("navigation",{method:s._setNavigation,validator:s._validateNavigation,value:r.navigation||{prev:null,next:null,page:null}});s.setAttributeConfig("animation",{validator:s._validateAnimation,value:r.animation||{speed:0,effect:null}});
9
+ s.setAttributeConfig("autoPlay",{validator:p.isNumber,value:r.autoPlay||0});s.setAttributeConfig("autoPlayInterval",{validator:p.isNumber,value:r.autoPlayInterval||0});s.setAttributeConfig("numPages",{readOnly:true,getter:s._getNumPages});s.setAttributeConfig("lastVisible",{readOnly:true,getter:s._getLastVisible});},initEvents:function(){var t=this,s=t.CLASSES,r;t.on("keydown",t._keyboardEventHandler);t.on(F,l);t.on(S,A);t.on(o,A);t.on(Q,A);t.on(C,function(){if(t._hasFocus){t.focus();}});t.on(L,A);t.on(g,function(u){t.scrollTo(0);l.call(t);R.call(t);});t.on(h,R,t);t.on(H,function(u){if(t.get("selectedItem")===null||t.get("selectedItem")<=0){t.set("selectedItem",t.get("firstVisible"));}l.call(t,u);R.call(t,u);t._setClipContainerSize();t.show();});t.on("selectedItemChange",function(u){n.call(t,u.newValue,u.prevValue);if(u.newValue>=0){t._updateTabIndex(t.getElementForItem(u.newValue));}t.fireEvent(C,u.newValue);});t.on(K,function(u){l.call(t,u);R.call(t,u);});t.on("firstVisibleChange",function(u){if(!t.get("selectOnScroll")){if(u.newValue>=0){t._updateTabIndex(t.getElementForItem(u.newValue));}}});t.on("click",function(u){if(t.isAutoPlayOn()){t.stopAutoPlay();}t._itemClickHandler(u);t._pagerClickHandler(u);});c.onFocus(t.get("element"),function(u,w){var v=c.getTarget(u);if(v&&v.nodeName.toUpperCase()=="A"&&e.getAncestorByClassName(v,s.NAVIGATION)){if(r){e.removeClass(r,s.PAGE_FOCUS);}r=v.parentNode;e.addClass(r,s.PAGE_FOCUS);}else{if(r){e.removeClass(r,s.PAGE_FOCUS);}}w._hasFocus=true;w._updateNavButtons(c.getTarget(u),true);},t);c.onBlur(t.get("element"),function(u,v){v._hasFocus=false;v._updateNavButtons(c.getTarget(u),false);},t);},isAnimating:function(){return this._isAnimationInProgress;},isAutoPlayOn:function(){return this._isAutoPlayInProgress;},getElementForItem:function(r){var s=this;if(r<0||r>=s.get("numItems")){return null;}if(s._itemsTable.items[r]){return e.get(s._itemsTable.items[r].id);}return null;},getElementForItems:function(){var t=this,s=[],r;for(r=0;r<t._itemsTable.numItems;r++){s.push(t.getElementForItem(r));}return s;},getItem:function(r){var s=this;if(r<0||r>=s.get("numItems")){return null;}if(s._itemsTable.numItems>r){if(!p.isUndefined(s._itemsTable.items[r])){return s._itemsTable.items[r];}}return null;},getItems:function(){return this._itemsTable.items;},getLoadingItems:function(){return this._itemsTable.loading;},getRows:function(){return this._rows;},getCols:function(){return this._cols;},getItemPositionById:function(w){var u=this,v=u.get("numItems"),s=0,r=u._itemsTable.items,t;while(s<v){t=r[s]||{};if(t.id==w){return s;}s++;}return -1;},getVisibleItems:function(){var u=this,s=u.get("firstVisible"),v=s+u.get("numVisible"),t=[];while(s<v){t.push(u.getElementForItem(s));s++;}return t;},removeItem:function(s){var u=this,t,r=u.get("numItems");if(s<0||s>=r){return false;}t=u._itemsTable.items.splice(s,1);if(t&&t.length==1){u._itemsTable.numItems--;u.set("numItems",r-1);u.fireEvent(o,{item:t[0],pos:s,ev:o});return true;}return false;},replaceItem:function(z,u){var y=this,w,v,t,x=y.get("numItems"),s,r=z;if(!z){return false;}if(p.isString(z)||z.nodeName){v=z.nodeName?z.innerHTML:z;}else{if(p.isObject(z)){v=z.content;}else{return false;}}if(p.isUndefined(u)){return false;}else{if(u<0||u>=x){return false;}s=y._itemsTable.items[u];if(!s){s=y._itemsTable.loading[u];y._itemsTable.items[u]=undefined;}y._itemsTable.items.splice(u,1,{item:v,className:z.className||"",id:e.generateId()});r=y._itemsTable.items[u];}y.fireEvent(Q,{newItem:r,oldItem:s,pos:u,ev:Q});return true;},replaceItems:function(r){var s,u,t=true;if(!p.isArray(r)){return false;}for(s=0,u=r.length;s<u;s++){if(this.replaceItem(r[s][0],r[s][1])===false){t=false;}}return t;},render:function(s){var u=this,r=u.CLASSES,t=u._rows;u.addClass(r.CAROUSEL);if(!u._clipEl){u._clipEl=u._createCarouselClip();u._clipEl.appendChild(u._carouselEl);}if(s){u.appendChild(u._clipEl);u.appendTo(s);}else{if(!e.inDocument(u.get("element"))){return false;}u.appendChild(u._clipEl);}if(t){e.addClass(u._clipEl,r.MULTI_ROW);}if(u.get("isVertical")){u.addClass(r.VERTICAL);}else{u.addClass(r.HORIZONTAL);}if(u.get("numItems")<1){return false;}u._refreshUi();return true;},scrollBackward:function(){var r=this;r.scrollTo(r._firstItem-r.get("scrollIncrement"));},scrollForward:function(){var r=this;r.scrollTo(r._firstItem+r.get("scrollIncrement"));},scrollPageBackward:function(){var t=this,u=t.get("isVertical"),s=t._cols,r=t._firstItem-t.get("numVisible");if(r<0){if(s){r=t._firstItem-s;}}if(t.get("selectOnScroll")){t._selectedItem=t._getSelectedItem(r);}t.scrollTo(r);},scrollPageForward:function(){var s=this,r=s._firstItem+s.get("numVisible");if(r>s.get("numItems")){r=0;}if(s.get("selectOnScroll")){s._selectedItem=s._getSelectedItem(r);}s.scrollTo(r);},scrollTo:function(AL,AI){var AH=this,u,AJ,z,AB,AC,AM,AN,AO,AD,AA,v,AF,s,w,t,x,AE,y,AP,AK=AH._itemsTable,AG=AK.items,r=AK.loading;if(p.isUndefined(AL)||AL==AH._firstItem||AH.isAnimating()){return;}AJ=AH.get("animation");z=AH.get("isCircular");AB=AH.get("isVertical");AA=AH._cols;v=AH._rows;AO=AH._firstItem;AF=AH.get("numItems");s=AH.get("numVisible");t=AH.get("currentPage");AP=function(){if(AH.isAutoPlayOn()){AH.stopAutoPlay();}};if(AL<0){if(z){AL=AF+AL;}else{AP.call(AH);return;}}else{if(AF>0&&AL>AF-1){if(AH.get("isCircular")){AL=AF-AL;}else{AP.call(AH);return;}}}if(isNaN(AL)){return;}AN=(AH._firstItem>AL)?"backward":"forward";AE=AO+s;AE=(AE>AF-1)?AF-1:AE;x=AH.fireEvent(i,{dir:AN,first:AO,last:AE});if(x===false){return;}AH.fireEvent(J,{page:t});AD=AL+s-1;AH._loadItems(AD>AF-1?AF-1:AD);AM=0-AL;if(v){if(AB){AM=parseInt(AM/AA,10);}else{AM=parseInt(AM/v,10);}}y=0;while(AM<0&&y<AL+s-1&&y<AF){if(!AG[y]&&!r[y]){AM++;}y+=v?v:1;}AH._firstItem=AL;AH.set("firstVisible",AL);AE=AL+s;AE=(AE>AF-1)?AF-1:AE;w=j.call(AH,AM);u=AJ.speed>0;if(u){AH._animateAndSetCarouselOffset(w,AL,AE,AI);}else{AH._setCarouselOffset(w);E.call(AH,AL,AE);}},getPageForItem:function(r){return Math.ceil((r+1)/parseInt(this.get("numVisible"),10));},getFirstVisibleOnPage:function(r){return(r-1)*this.get("numVisible");
10
+ },selectPreviousItem:function(){var t=this,s=0,r=t.get("selectedItem");if(r==this._firstItem){s=r-t.get("numVisible");t._selectedItem=t._getSelectedItem(r-1);t.scrollTo(s);}else{s=t.get("selectedItem")-t.get("scrollIncrement");t.set("selectedItem",t._getSelectedItem(s));}},selectNextItem:function(){var s=this,r=0;r=s.get("selectedItem")+s.get("scrollIncrement");s.set("selectedItem",s._getSelectedItem(r));},show:function(){var s=this,r=s.CLASSES;if(s.fireEvent(Y)!==false){s.addClass(r.VISIBLE);s.fireEvent(V);}},startAutoPlay:function(){var r=this,s;if(p.isUndefined(r._autoPlayTimer)){s=r.get("autoPlayInterval");if(s<=0){return;}r._isAutoPlayInProgress=true;r.fireEvent(Z);r._autoPlayTimer=setTimeout(function(){r._autoScroll();},s);}},stopAutoPlay:function(){var r=this;if(!p.isUndefined(r._autoPlayTimer)){clearTimeout(r._autoPlayTimer);delete r._autoPlayTimer;r._isAutoPlayInProgress=false;r.fireEvent(q);}},updatePagination:function(){var z=this,x=z._pagination;if(!x.el){return false;}var w=z.get("numItems"),AA=z.get("numVisible"),u=z.get("firstVisible")+1,v=z.get("currentPage")+1,r=z.get("numPages"),t={"numVisible":AA,"numPages":r,"numItems":w,"selectedItem":z.get("selectedItem")+1,"currentPage":v,"firstVisible":u,"lastVisible":z.get("lastVisible")+1},s=x.callback||{},y=s.scope&&s.obj?s.obj:z;x.el.innerHTML=p.isFunction(s.fn)?s.fn.apply(y,[x.template,t]):YAHOO.lang.substitute(x.template,t);},registerPagination:function(s,u,r){var t=this;t._pagination.template=s;t._pagination.callback=r||{};if(!t._pagination.el){t._pagination.el=W("DIV",{className:t.CLASSES.PAGINATION});if(u=="before"){t._navEl.insertBefore(t._pagination.el,t._navEl.firstChild);}else{t._navEl.appendChild(t._pagination.el);}t.on("itemSelected",t.updatePagination);t.on("pageChange",t.updatePagination);}t.updatePagination();},toString:function(){return P+(this.get?" (#"+this.get("id")+")":"");},_animateAndSetCarouselOffset:function(w,u,s){var v=this,t=v.get("animation"),r=null;if(v.get("isVertical")){r=new YAHOO.util.Motion(v._carouselEl,{top:{to:w}},t.speed,t.effect);}else{r=new YAHOO.util.Motion(v._carouselEl,{left:{to:w}},t.speed,t.effect);}v._isAnimationInProgress=true;r.onComplete.subscribe(v._animationCompleteHandler,{scope:v,item:u,last:s});r.animate();},_animationCompleteHandler:function(r,s,t){t.scope._isAnimationInProgress=false;E.call(t.scope,t.item,t.last);},_autoScroll:function(){var s=this,t=s._firstItem,r;if(t>=s.get("numItems")-1){if(s.get("isCircular")){r=0;}else{s.stopAutoPlay();}}else{r=t+s.get("numVisible");}s._selectedItem=s._getSelectedItem(r);s.scrollTo.call(s,r);},_createCarousel:function(s){var u=this,r=u.CLASSES,t=e.get(s);if(!t){t=W("DIV",{className:r.CAROUSEL,id:s});}if(!u._carouselEl){u._carouselEl=W(u.get("carouselEl"),{className:r.CAROUSEL_EL});}return t;},_createCarouselClip:function(){return W("DIV",{className:this.CLASSES.CONTENT});},_createCarouselItem:function(u){var r,t=this,s=m.call(t,u.pos);return W(t.get("carouselItemEl"),{className:u.className,styles:u.styles,content:u.content,id:u.id});},_getValidIndex:function(t){var w=this,r=w.get("isCircular"),u=w.get("numItems"),v=w.get("numVisible"),s=u-1;if(t<0){t=r?Math.ceil(u/v)*v+t:0;}else{if(t>s){t=r?0:s;}}return t;},_getSelectedItem:function(v){var u=this,r=u.get("isCircular"),t=u.get("numItems"),s=t-1;if(v<0){if(r){v=t+v;}else{v=u.get("selectedItem");}}else{if(v>s){if(r){v=v-t;}else{v=u.get("selectedItem");}}}return v;},_itemClickHandler:function(v){var y=this,w=y.get("carouselItemEl"),s=y.get("element"),t,u,x=c.getTarget(v),r=x.tagName.toUpperCase();if(r==="INPUT"||r==="SELECT"||r==="TEXTAREA"){return;}while(x&&x!=s&&x.id!=y._carouselEl){t=x.nodeName;if(t.toUpperCase()==w){break;}x=x.parentNode;}if((u=y.getItemPositionById(x.id))>=0){y.set("selectedItem",y._getSelectedItem(u));y.focus();}},_keyboardEventHandler:function(t){var v=this,s=c.getCharCode(t),u=c.getTarget(t),r=false;if(v.isAnimating()||u.tagName.toUpperCase()==="SELECT"){return;}switch(s){case 37:case 38:v.selectPreviousItem();r=true;break;case 39:case 40:v.selectNextItem();r=true;break;case 33:v.scrollPageBackward();r=true;break;case 34:v.scrollPageForward();r=true;break;}if(r){if(v.isAutoPlayOn()){v.stopAutoPlay();}c.preventDefault(t);}},_loadItems:function(t){var w=this,s=w.get("numItems"),u=w.get("numVisible"),v=w.get("revealAmount"),x=w._itemsTable.items.length,r=w.get("lastVisible");if(x>t&&t+1>=u){x=t%u||t==r?t-t%u:t-u+1;}if(v&&t<s-1){t++;}if(t>=x&&(!w.getItem(x)||!w.getItem(t))){w.fireEvent(L,{ev:L,first:x,last:t,num:t-x+1});}},_pagerChangeHandler:function(s){var v=this,u=c.getTarget(s),t=u.value,r;if(t){r=v.getFirstVisibleOnPage(t);v._selectedItem=r;v.scrollTo(r);v.focus();}},_pagerClickHandler:function(x){var z=this,t=z.CLASSES,u=c.getTarget(x),s=u.nodeName.toUpperCase(),r,w,v,y;if(e.hasClass(u,t.PAGER_ITEM)||e.hasClass(u.parentNode,t.PAGER_ITEM)){if(s=="EM"){u=u.parentNode;}r=u.href;w=r.lastIndexOf("#");v=parseInt(r.substring(w+1),10);if(v!=-1){y=z.getFirstVisibleOnPage(v);z._selectedItem=y;z.scrollTo(y);z.focus();}c.preventDefault(x);}},_parseCarousel:function(t){var w=this,x,r,s,v,u;r=w.CLASSES;s=w.get("carouselEl");v=false;for(x=t.firstChild;x;x=x.nextSibling){if(x.nodeType==1){u=x.nodeName;if(u.toUpperCase()==s){w._carouselEl=x;e.addClass(w._carouselEl,w.CLASSES.CAROUSEL_EL);v=true;}}}return v;},_parseCarouselItems:function(){var y=this,AA=y.CLASSES,v=0,z,r,t,u,s,w=y.get("firstVisible"),x=y._carouselEl;z=y._rows;t=y.get("carouselItemEl");for(r=x.firstChild;r;r=r.nextSibling){if(r.nodeType==1){s=r.nodeName;if(s.toUpperCase()==t){if(r.id){u=r.id;}else{u=e.generateId();r.setAttribute("id",u);}y.addItem(r,w);w++;}}}},_parseCarouselNavigation:function(x){var y=this,w,z=y.CLASSES,s,v,u,r,t=false;r=e.getElementsByClassName(z.PREV_PAGE,"*",x);if(r.length>0){for(v in r){if(r.hasOwnProperty(v)){s=r[v];if(s.nodeName=="INPUT"||s.nodeName=="BUTTON"||s.nodeName=="A"){y._navBtns.prev.push(s);}else{u=s.getElementsByTagName("INPUT");if(p.isArray(u)&&u.length>0){y._navBtns.prev.push(u[0]);
11
+ }else{u=s.getElementsByTagName("BUTTON");if(p.isArray(u)&&u.length>0){y._navBtns.prev.push(u[0]);}}}}}w={prev:r};}r=e.getElementsByClassName(z.NEXT_PAGE,"*",x);if(r.length>0){for(v in r){if(r.hasOwnProperty(v)){s=r[v];if(s.nodeName=="INPUT"||s.nodeName=="BUTTON"||s.nodeName=="A"){y._navBtns.next.push(s);}else{u=s.getElementsByTagName("INPUT");if(p.isArray(u)&&u.length>0){y._navBtns.next.push(u[0]);}else{u=s.getElementsByTagName("BUTTON");if(p.isArray(u)&&u.length>0){y._navBtns.next.push(u[0]);}}}}}if(w){w.next=r;}else{w={next:r};}}if(w){y.set("navigation",w);t=true;}return t;},_refreshUi:function(){var v=this,s,w=v.get("isVertical"),y=v.get("firstVisible"),t,x,r,u;if(v._itemsTable.numItems<1){return;}u=O.call(v,w?"height":"width");t=v._itemsTable.items[y].id;u=w?d(t,"width"):d(t,"height");e.setStyle(v._carouselEl,w?"width":"height",u+"px");v._hasRendered=true;v.fireEvent(H);},_setCarouselOffset:function(t){var r=this,s;s=r.get("isVertical")?"top":"left";e.setStyle(r._carouselEl,s,t+"px");},_setupCarouselNavigation:function(){var w=this,u,s,r,y,v,x,t;r=w.CLASSES;v=e.getElementsByClassName(r.NAVIGATION,"DIV",w.get("element"));if(v.length===0){v=W("DIV",{className:r.NAVIGATION});w.insertBefore(v,e.getFirstChild(w.get("element")));}else{v=v[0];}w._pages.el=W("UL");v.appendChild(w._pages.el);y=w.get("navigation");if(p.isString(y.prev)||p.isArray(y.prev)){if(p.isString(y.prev)){y.prev=[y.prev];}for(u in y.prev){if(y.prev.hasOwnProperty(u)){w._navBtns.prev.push(e.get(y.prev[u]));}}}else{t=W("SPAN",{className:r.BUTTON+r.FIRST_NAV});e.setStyle(t,"visibility","visible");u=e.generateId();t.innerHTML='<button type="button" '+'id="'+u+'" name="'+w.STRINGS.PREVIOUS_BUTTON_TEXT+'">'+w.STRINGS.PREVIOUS_BUTTON_TEXT+"</button>";v.appendChild(t);u=e.get(u);w._navBtns.prev=[u];s={prev:[t]};}if(p.isString(y.next)||p.isArray(y.next)){if(p.isString(y.next)){y.next=[y.next];}for(u in y.next){if(y.next.hasOwnProperty(u)){w._navBtns.next.push(e.get(y.next[u]));}}}else{x=W("SPAN",{className:r.BUTTON+r.NEXT_NAV});e.setStyle(x,"visibility","visible");u=e.generateId();x.innerHTML='<button type="button" '+'id="'+u+'" name="'+w.STRINGS.NEXT_BUTTON_TEXT+'">'+w.STRINGS.NEXT_BUTTON_TEXT+"</button>";v.appendChild(x);u=e.get(u);w._navBtns.next=[u];if(s){s.next=[x];}else{s={next:[x]};}}if(s){w.set("navigation",s);}return v;},_setClipContainerSize:function(r,t){var z=this,x=z.get("isVertical"),AB=z._rows,v=z._cols,y=z.get("revealAmount"),s=O.call(z,"height"),u=O.call(z,"width"),AA,w;r=r||z._clipEl;if(AB){AA=s*AB;w=u*v;}else{t=t||z.get("numVisible");if(x){AA=s*t;}else{w=u*t;}}z._recomputeSize=(AA===0);if(z._recomputeSize){z._hasRendered=false;return;}y=N.call(z);if(x){AA+=(y*2);}else{w+=(y*2);}if(x){AA+=M(z._carouselEl,"height");e.setStyle(r,"height",AA+"px");if(v){w+=M(z._carouselEl,"width");e.setStyle(r,"width",w+(0)+"px");}}else{w+=M(z._carouselEl,"width");e.setStyle(r,"width",w+"px");if(AB){AA+=M(z._carouselEl,"height");e.setStyle(r,"height",AA+"px");}}z._setContainerSize(r);},_setContainerSize:function(s,t){var w=this,r=w.CONFIG,z=w.CLASSES,v,y,u,x;v=w.get("isVertical");y=w._rows;u=w._cols;s=s||w._clipEl;t=t||(v?"height":"width");x=parseFloat(e.getStyle(s,t),10);x=p.isNumber(x)?x:0;if(v){x+=M(w._carouselEl,"height")+d(w._navEl,"height");}else{x+=M(w._carouselEl,"width");}if(!v){if(x<r.HORZ_MIN_WIDTH){x=r.HORZ_MIN_WIDTH;w.addClass(z.MIN_WIDTH);}}w.setStyle(t,x+"px");if(v){x=O.call(w,"width");if(u){x=x*u;}e.setStyle(w._carouselEl,"width",x+"px");if(x<r.VERT_MIN_WIDTH){x=r.VERT_MIN_WIDTH;w.addClass(z.MIN_WIDTH);}w.setStyle("width",x+"px");}else{if(y){x=O.call(w,"height");x=x*y;e.setStyle(w._carouselEl,"height",x+"px");}}},_setFirstVisible:function(s){var r=this;if(s>=0&&s<r.get("numItems")){r.scrollTo(s);}else{s=r.get("firstVisible");}return s;},_setNavigation:function(r){var s=this;if(r.prev){c.on(r.prev,"click",f,s);}if(r.next){c.on(r.next,"click",k,s);}},_setNumVisible:function(s){var r=this;r._setClipContainerSize(r._clipEl,s);},_numVisibleSetter:function(t){var s=this,r=t;if(p.isArray(t)){s._cols=t[0];s._rows=t[1];r=t[0]*t[1];}return r;},_selectedItemSetter:function(s){var r=this;return(s<r.get("numItems"))?s:0;},_setNumItems:function(t){var s=this,r=s._itemsTable.numItems;if(p.isArray(s._itemsTable.items)){if(s._itemsTable.items.length!=r){r=s._itemsTable.items.length;s._itemsTable.numItems=r;}}if(t<r){while(r>t){s.removeItem(r-1);r--;}}return t;},_setOrientation:function(t){var s=this,r=s.CLASSES;if(t){s.replaceClass(r.HORIZONTAL,r.VERTICAL);}else{s.replaceClass(r.VERTICAL,r.HORIZONTAL);}this._itemAttrCache={};return t;},_setRevealAmount:function(s){var r=this;if(s>=0&&s<=100){s=parseInt(s,10);s=p.isNumber(s)?s:0;r._setClipContainerSize();}else{s=r.get("revealAmount");}return s;},_setSelectedItem:function(r){this._selectedItem=r;},_getNumPages:function(){return Math.ceil(parseInt(this.get("numItems"),10)/parseInt(this.get("numVisible"),10));},_getLastVisible:function(){var r=this;return r.get("currentPage")+1==r.get("numPages")?r.get("numItems")-1:r.get("firstVisible")+r.get("numVisible")-1;},_syncUiForItemAdd:function(u){var v,AA=this,x=AA._carouselEl,r,AB,t=AA._itemsTable,s,w,y,z;w=p.isUndefined(u.pos)?u.newPos||t.numItems-1:u.pos;if(!s){AB=t.items[w]||{};r=AA._createCarouselItem({className:AB.className,styles:AB.styles,content:AB.item,id:AB.id,pos:w});if(p.isUndefined(u.pos)){if(!p.isUndefined(t.loading[w])){s=t.loading[w];}if(s){x.replaceChild(r,s);delete t.loading[w];}else{x.appendChild(r);}}else{if(!p.isUndefined(t.items[u.pos+1])){y=e.get(t.items[u.pos+1].id);}if(y){x.insertBefore(r,y);}else{}}}else{if(p.isUndefined(u.pos)){if(!e.isAncestor(AA._carouselEl,s)){x.appendChild(s);}}else{if(!e.isAncestor(x,s)){if(!p.isUndefined(t.items[u.pos+1])){x.insertBefore(s,e.get(t.items[u.pos+1].id));}}}}if(!AA._hasRendered){AA._refreshUi();}if(AA.get("selectedItem")<0){AA.set("selectedItem",AA.get("firstVisible"));}AA._syncUiItems();},_syncUiForItemReplace:function(x){var w=this,t=w._carouselEl,r=w._itemsTable,y=x.pos,v=x.newItem,s=x.oldItem,u;
12
+ u=w._createCarouselItem({className:v.className,styles:v.styles,content:v.item,id:v.id,pos:y});if(u&&s){c.purgeElement(s,true);t.replaceChild(u,e.get(s.id));if(!p.isUndefined(r.loading[y])){r.numItems++;delete r.loading[y];}}if(!w._hasRendered){w._refreshUi();}w._syncUiItems();},_syncUiForItemRemove:function(w){var v=this,r=v._carouselEl,t,u,s,x;s=v.get("numItems");u=w.item;x=w.pos;if(u&&(t=e.get(u.id))){if(t&&e.isAncestor(r,t)){c.purgeElement(t,true);r.removeChild(t);}if(v.get("selectedItem")==x){x=x>=s?s-1:x;}}else{}v._syncUiItems();},_syncUiForLazyLoading:function(v){var z=this,x=z._carouselEl,t=z._itemsTable,w=t.items.length,y=t.items[v.last+1],r,s;if(!y&&v.last<w){s=v.first;do{y=t.items[s];s++;}while(s<w&&!y);}for(var u=v.first;u<=v.last;u++){if(p.isUndefined(t.loading[u])&&p.isUndefined(t.items[u])){r=z._createCarouselItem({className:z.CLASSES.ITEM_LOADING,content:z.STRINGS.ITEM_LOADING_CONTENT,id:e.generateId(),pos:u});if(r){if(y){y=e.get(y.id);if(y){x.insertBefore(r,y);}else{}}else{x.appendChild(r);}}t.loading[u]=r;}}z._syncUiItems();},_syncUiItems:function(){var u,y=this,w=y.get("numItems"),t,s=y._itemsTable,v=s.items,r=s.loading,z,x;for(t=0;t<w;t++){z=v[t]||r[t];if(z&&z.id){x=m.call(y,t);z.styles=z.styles||{};for(u in x){if(x.hasOwnProperty(u)){z.styles[u]=x[u];}}G(e.get(z.id),x);}}},_updateNavButtons:function(v,s){var t,r=this.CLASSES,w,u=v.parentNode;if(!u){return;}w=u.parentNode;if(v.nodeName.toUpperCase()=="BUTTON"&&e.hasClass(u,r.BUTTON)){if(s){if(w){t=e.getChildren(w);if(t){e.removeClass(t,r.FOCUSSED_BUTTON);}}e.addClass(u,r.FOCUSSED_BUTTON);}else{e.removeClass(u,r.FOCUSSED_BUTTON);}}},_updatePagerButtons:function(){var z=this,x=z.CLASSES,y=z._pages.cur,r,w,u,AA,s=z.get("numVisible"),v=z._pages.num,t=z._pages.el;if(v===0||!t){return;}e.setStyle(t,"visibility","hidden");while(t.firstChild){t.removeChild(t.firstChild);}for(u=0;u<v;u++){r=document.createElement("LI");if(u===0){e.addClass(r,x.FIRST_PAGE);}if(u==y){e.addClass(r,x.SELECTED_NAV);}w="<a class="+x.PAGER_ITEM+' href="#'+(u+1)+'" tabindex="0"><em>'+z.STRINGS.PAGER_PREFIX_TEXT+" "+(u+1)+"</em></a>";r.innerHTML=w;t.appendChild(r);}e.setStyle(t,"visibility","visible");},_updatePagerMenu:function(){var z=this,x=z.CLASSES,y=z._pages.cur,s,v,AA,t=z.get("numVisible"),w=z._pages.num,u=z._pages.el,r;if(w===0){return;}r=document.createElement("SELECT");if(!r){return;}e.setStyle(u,"visibility","hidden");while(u.firstChild){u.removeChild(u.firstChild);}for(v=0;v<w;v++){s=document.createElement("OPTION");s.value=v+1;s.innerHTML=z.STRINGS.PAGER_PREFIX_TEXT+" "+(v+1);if(v==y){s.setAttribute("selected","selected");}r.appendChild(s);}s=document.createElement("FORM");if(!s){}else{s.appendChild(r);u.appendChild(s);}c.addListener(r,"change",z._pagerChangeHandler,this,true);e.setStyle(u,"visibility","visible");},_updateTabIndex:function(r){var s=this;if(r){if(s._focusableItemEl){s._focusableItemEl.tabIndex=-1;}s._focusableItemEl=r;r.tabIndex=0;}},_validateAnimation:function(r){var s=true;if(p.isObject(r)){if(r.speed){s=s&&p.isNumber(r.speed);}if(r.effect){s=s&&p.isFunction(r.effect);}else{if(!p.isUndefined(YAHOO.util.Easing)){r.effect=YAHOO.util.Easing.easeOut;}}}else{s=false;}return s;},_validateFirstVisible:function(t){var s=this,r=s.get("numItems");if(p.isNumber(t)){if(r===0&&t==r){return true;}else{return(t>=0&&t<r);}}return false;},_validateNavigation:function(r){var s;if(!p.isObject(r)){return false;}if(r.prev){if(!p.isArray(r.prev)){return false;}for(s in r.prev){if(r.prev.hasOwnProperty(s)){if(!p.isString(r.prev[s].nodeName)){return false;}}}}if(r.next){if(!p.isArray(r.next)){return false;}for(s in r.next){if(r.next.hasOwnProperty(s)){if(!p.isString(r.next[s].nodeName)){return false;}}}}return true;},_validateNumItems:function(r){return p.isNumber(r)&&(r>=0);},_validateNumVisible:function(r){var s=false;if(p.isNumber(r)){s=r>0&&r<=this.get("numItems");}else{if(p.isArray(r)){if(p.isNumber(r[0])&&p.isNumber(r[1])){s=r[0]*r[1]>0&&r.length==2;}}}return s;},_validateRevealAmount:function(r){var s=false;if(p.isNumber(r)){s=r>=0&&r<100;}return s;},_validateScrollIncrement:function(r){var s=false;if(p.isNumber(r)){s=(r>0&&r<this.get("numItems"));}return s;}});})();YAHOO.register("carousel",YAHOO.widget.Carousel,{version:"2.8.1",build:"19"});
@@ -0,0 +1,4349 @@
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
+ /**
8
+ * The Carousel module provides a widget for browsing among a set of like
9
+ * objects represented pictorially.
10
+ *
11
+ * @module carousel
12
+ * @requires yahoo, dom, event, element
13
+ * @optional animation
14
+ * @namespace YAHOO.widget
15
+ * @title Carousel Widget
16
+ * @beta
17
+ */
18
+ (function () {
19
+
20
+ var WidgetName; // forward declaration
21
+
22
+ /**
23
+ * The Carousel widget.
24
+ *
25
+ * @class Carousel
26
+ * @extends YAHOO.util.Element
27
+ * @constructor
28
+ * @param el {HTMLElement | String} The HTML element that represents the
29
+ * the container that houses the Carousel.
30
+ * @param cfg {Object} (optional) The configuration values
31
+ */
32
+ YAHOO.widget.Carousel = function (el, cfg) {
33
+
34
+ YAHOO.widget.Carousel.superclass.constructor.call(this, el, cfg);
35
+ };
36
+
37
+ /*
38
+ * Private variables of the Carousel component
39
+ */
40
+
41
+ /* Some abbreviations to avoid lengthy typing and lookups. */
42
+ var Carousel = YAHOO.widget.Carousel,
43
+ Dom = YAHOO.util.Dom,
44
+ Event = YAHOO.util.Event,
45
+ JS = YAHOO.lang;
46
+
47
+ /**
48
+ * The widget name.
49
+ * @private
50
+ * @static
51
+ */
52
+ WidgetName = "Carousel";
53
+
54
+ /**
55
+ * The internal table of Carousel instances.
56
+ * @private
57
+ * @static
58
+ */
59
+ var instances = {},
60
+
61
+ /*
62
+ * Custom events of the Carousel component
63
+ */
64
+
65
+ /**
66
+ * @event afterScroll
67
+ * @description Fires when the Carousel has scrolled to the previous or
68
+ * next page. Passes back the index of the first and last visible items in
69
+ * the Carousel. See
70
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
71
+ * for more information on listening for this event.
72
+ * @type YAHOO.util.CustomEvent
73
+ */
74
+ afterScrollEvent = "afterScroll",
75
+
76
+ /**
77
+ * @event allItemsRemovedEvent
78
+ * @description Fires when all items have been removed from the Carousel.
79
+ * See
80
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
81
+ * for more information on listening for this event.
82
+ * @type YAHOO.util.CustomEvent
83
+ */
84
+ allItemsRemovedEvent = "allItemsRemoved",
85
+
86
+ /**
87
+ * @event beforeHide
88
+ * @description Fires before the Carousel is hidden. See
89
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
90
+ * for more information on listening for this event.
91
+ * @type YAHOO.util.CustomEvent
92
+ */
93
+ beforeHideEvent = "beforeHide",
94
+
95
+ /**
96
+ * @event beforePageChange
97
+ * @description Fires when the Carousel is about to scroll to the previous
98
+ * or next page. Passes back the page number of the current page. Note
99
+ * that the first page number is zero. See
100
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
101
+ * for more information on listening for this event.
102
+ * @type YAHOO.util.CustomEvent
103
+ */
104
+ beforePageChangeEvent = "beforePageChange",
105
+
106
+ /**
107
+ * @event beforeScroll
108
+ * @description Fires when the Carousel is about to scroll to the previous
109
+ * or next page. Passes back the index of the first and last visible items
110
+ * in the Carousel and the direction (backward/forward) of the scroll. See
111
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
112
+ * for more information on listening for this event.
113
+ * @type YAHOO.util.CustomEvent
114
+ */
115
+ beforeScrollEvent = "beforeScroll",
116
+
117
+ /**
118
+ * @event beforeShow
119
+ * @description Fires when the Carousel is about to be shown. See
120
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
121
+ * for more information on listening for this event.
122
+ * @type YAHOO.util.CustomEvent
123
+ */
124
+ beforeShowEvent = "beforeShow",
125
+
126
+ /**
127
+ * @event blur
128
+ * @description Fires when the Carousel loses focus. See
129
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
130
+ * for more information on listening for this event.
131
+ * @type YAHOO.util.CustomEvent
132
+ */
133
+ blurEvent = "blur",
134
+
135
+ /**
136
+ * @event focus
137
+ * @description Fires when the Carousel gains focus. See
138
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
139
+ * for more information on listening for this event.
140
+ * @type YAHOO.util.CustomEvent
141
+ */
142
+ focusEvent = "focus",
143
+
144
+ /**
145
+ * @event hide
146
+ * @description Fires when the Carousel is hidden. See
147
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
148
+ * for more information on listening for this event.
149
+ * @type YAHOO.util.CustomEvent
150
+ */
151
+ hideEvent = "hide",
152
+
153
+ /**
154
+ * @event itemAdded
155
+ * @description Fires when an item has been added to the Carousel. Passes
156
+ * back the content of the item that would be added, the index at which the
157
+ * item would be added, and the event itself. See
158
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
159
+ * for more information on listening for this event.
160
+ * @type YAHOO.util.CustomEvent
161
+ */
162
+ itemAddedEvent = "itemAdded",
163
+
164
+ /**
165
+ * @event itemRemoved
166
+ * @description Fires when an item has been removed from the Carousel.
167
+ * Passes back the content of the item that would be removed, the index
168
+ * from which the item would be removed, and the event itself. See
169
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
170
+ * for more information on listening for this event.
171
+ * @type YAHOO.util.CustomEvent
172
+ */
173
+ itemRemovedEvent = "itemRemoved",
174
+
175
+ /**
176
+ * @event itemReplaced
177
+ * @description Fires when an item has been replaced in the Carousel.
178
+ * Passes back the content of the item that was replaced, the content
179
+ * of the new item, the index where the replacement occurred, and the event
180
+ * itself. See
181
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
182
+ * for more information on listening for this event.
183
+ * @type YAHOO.util.CustomEvent
184
+ */
185
+ itemReplacedEvent = "itemReplaced",
186
+
187
+ /**
188
+ * @event itemSelected
189
+ * @description Fires when an item has been selected in the Carousel.
190
+ * Passes back the index of the selected item in the Carousel. Note, that
191
+ * the index begins from zero. See
192
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
193
+ * for more information on listening for this event.
194
+ * @type YAHOO.util.CustomEvent
195
+ */
196
+ itemSelectedEvent = "itemSelected",
197
+
198
+ /**
199
+ * @event loadItems
200
+ * @description Fires when the Carousel needs more items to be loaded for
201
+ * displaying them. Passes back the first and last visible items in the
202
+ * Carousel, and the number of items needed to be loaded. See
203
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
204
+ * for more information on listening for this event.
205
+ * @type YAHOO.util.CustomEvent
206
+ */
207
+ loadItemsEvent = "loadItems",
208
+
209
+ /**
210
+ * @event navigationStateChange
211
+ * @description Fires when the state of either one of the navigation
212
+ * buttons are changed from enabled to disabled or vice versa. Passes back
213
+ * the state (true/false) of the previous and next buttons. The value true
214
+ * signifies the button is enabled, false signifies disabled. See
215
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
216
+ * for more information on listening for this event.
217
+ * @type YAHOO.util.CustomEvent
218
+ */
219
+ navigationStateChangeEvent = "navigationStateChange",
220
+
221
+ /**
222
+ * @event pageChange
223
+ * @description Fires after the Carousel has scrolled to the previous or
224
+ * next page. Passes back the page number of the current page. Note
225
+ * that the first page number is zero. See
226
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
227
+ * for more information on listening for this event.
228
+ * @type YAHOO.util.CustomEvent
229
+ */
230
+ pageChangeEvent = "pageChange",
231
+
232
+ /*
233
+ * Internal event.
234
+ * @event render
235
+ * @description Fires when the Carousel is rendered. See
236
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
237
+ * for more information on listening for this event.
238
+ * @type YAHOO.util.CustomEvent
239
+ */
240
+ renderEvent = "render",
241
+
242
+ /**
243
+ * @event show
244
+ * @description Fires when the Carousel is shown. See
245
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
246
+ * for more information on listening for this event.
247
+ * @type YAHOO.util.CustomEvent
248
+ */
249
+ showEvent = "show",
250
+
251
+ /**
252
+ * @event startAutoPlay
253
+ * @description Fires when the auto play has started in the Carousel. See
254
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
255
+ * for more information on listening for this event.
256
+ * @type YAHOO.util.CustomEvent
257
+ */
258
+ startAutoPlayEvent = "startAutoPlay",
259
+
260
+ /**
261
+ * @event stopAutoPlay
262
+ * @description Fires when the auto play has been stopped in the Carousel.
263
+ * See
264
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
265
+ * for more information on listening for this event.
266
+ * @type YAHOO.util.CustomEvent
267
+ */
268
+ stopAutoPlayEvent = "stopAutoPlay",
269
+
270
+ /*
271
+ * Internal event.
272
+ * @event uiUpdateEvent
273
+ * @description Fires when the UI has been updated.
274
+ * See
275
+ * <a href="YAHOO.util.Element.html#addListener">Element.addListener</a>
276
+ * for more information on listening for this event.
277
+ * @type YAHOO.util.CustomEvent
278
+ */
279
+ uiUpdateEvent = "uiUpdate";
280
+
281
+ /*
282
+ * Private helper functions used by the Carousel component
283
+ */
284
+
285
+ /**
286
+ * Set multiple styles on one element.
287
+ * @method setStyles
288
+ * @param el {HTMLElement} The element to set styles on
289
+ * @param style {Object} top:"10px", left:"0px", etc.
290
+ * @private
291
+ */
292
+ function setStyles(el, styles) {
293
+ var which;
294
+
295
+ for (which in styles) {
296
+ if (styles.hasOwnProperty(which)) {
297
+ Dom.setStyle(el, which, styles[which]);
298
+ }
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Create an element, set its class name and optionally install the element
304
+ * to its parent.
305
+ * @method createElement
306
+ * @param el {String} The element to be created
307
+ * @param attrs {Object} Configuration of parent, class and id attributes.
308
+ * If the content is specified, it is inserted after creation of the
309
+ * element. The content can also be an HTML element in which case it would
310
+ * be appended as a child node of the created element.
311
+ * @private
312
+ */
313
+ function createElement(el, attrs) {
314
+ var newEl = document.createElement(el);
315
+
316
+ attrs = attrs || {};
317
+ if (attrs.className) {
318
+ Dom.addClass(newEl, attrs.className);
319
+ }
320
+
321
+ if (attrs.styles) {
322
+ setStyles(newEl, attrs.styles);
323
+ }
324
+
325
+ if (attrs.parent) {
326
+ attrs.parent.appendChild(newEl);
327
+ }
328
+
329
+ if (attrs.id) {
330
+ newEl.setAttribute("id", attrs.id);
331
+ }
332
+
333
+ if (attrs.content) {
334
+ if (attrs.content.nodeName) {
335
+ newEl.appendChild(attrs.content);
336
+ } else {
337
+ newEl.innerHTML = attrs.content;
338
+ }
339
+ }
340
+
341
+ return newEl;
342
+ }
343
+
344
+ /**
345
+ * Get the computed style of an element.
346
+ *
347
+ * @method getStyle
348
+ * @param el {HTMLElement} The element for which the style needs to be
349
+ * returned.
350
+ * @param style {String} The style attribute
351
+ * @param type {String} "int", "float", etc. (defaults to int)
352
+ * @private
353
+ */
354
+ function getStyle(el, style, type) {
355
+ var value;
356
+
357
+ if (!el) {
358
+ return 0;
359
+ }
360
+
361
+ function getStyleIntVal(el, style) {
362
+ var val;
363
+
364
+ /*
365
+ * XXX: Safari calculates incorrect marginRight for an element
366
+ * which has its parent element style set to overflow: hidden
367
+ * https://bugs.webkit.org/show_bug.cgi?id=13343
368
+ * Let us assume marginLeft == marginRight
369
+ */
370
+ if (style == "marginRight" && YAHOO.env.ua.webkit) {
371
+ val = parseInt(Dom.getStyle(el, "marginLeft"), 10);
372
+ } else {
373
+ val = parseInt(Dom.getStyle(el, style), 10);
374
+ }
375
+
376
+ return JS.isNumber(val) ? val : 0;
377
+ }
378
+
379
+ function getStyleFloatVal(el, style) {
380
+ var val;
381
+
382
+ /*
383
+ * XXX: Safari calculates incorrect marginRight for an element
384
+ * which has its parent element style set to overflow: hidden
385
+ * https://bugs.webkit.org/show_bug.cgi?id=13343
386
+ * Let us assume marginLeft == marginRight
387
+ */
388
+ if (style == "marginRight" && YAHOO.env.ua.webkit) {
389
+ val = parseFloat(Dom.getStyle(el, "marginLeft"));
390
+ } else {
391
+ val = parseFloat(Dom.getStyle(el, style));
392
+ }
393
+
394
+ return JS.isNumber(val) ? val : 0;
395
+ }
396
+
397
+ if (typeof type == "undefined") {
398
+ type = "int";
399
+ }
400
+
401
+ switch (style) {
402
+ case "height":
403
+ value = el.offsetHeight;
404
+ if (value > 0) {
405
+ value += getStyleIntVal(el, "marginTop") +
406
+ getStyleIntVal(el, "marginBottom");
407
+ } else {
408
+ value = getStyleFloatVal(el, "height") +
409
+ getStyleIntVal(el, "marginTop") +
410
+ getStyleIntVal(el, "marginBottom") +
411
+ getStyleIntVal(el, "borderTopWidth") +
412
+ getStyleIntVal(el, "borderBottomWidth") +
413
+ getStyleIntVal(el, "paddingTop") +
414
+ getStyleIntVal(el, "paddingBottom");
415
+ }
416
+ break;
417
+ case "width":
418
+ value = el.offsetWidth;
419
+ if (value > 0) {
420
+ value += getStyleIntVal(el, "marginLeft") +
421
+ getStyleIntVal(el, "marginRight");
422
+ } else {
423
+ value = getStyleFloatVal(el, "width") +
424
+ getStyleIntVal(el, "marginLeft") +
425
+ getStyleIntVal(el, "marginRight") +
426
+ getStyleIntVal(el, "borderLeftWidth") +
427
+ getStyleIntVal(el, "borderRightWidth") +
428
+ getStyleIntVal(el, "paddingLeft") +
429
+ getStyleIntVal(el, "paddingRight");
430
+ }
431
+ break;
432
+ default:
433
+ if (type == "int") {
434
+ value = getStyleIntVal(el, style);
435
+ } else if (type == "float") {
436
+ value = getStyleFloatVal(el, style);
437
+ } else {
438
+ value = Dom.getStyle(el, style);
439
+ }
440
+ break;
441
+ }
442
+
443
+ return value;
444
+ }
445
+
446
+ /**
447
+ * Compute and return the height or width of a single Carousel item
448
+ * depending upon the orientation.
449
+ *
450
+ * @method getCarouselItemSize
451
+ * @param which {String} "height" or "width" to be returned. If this is
452
+ * passed explicitly, the calculated size is not cached.
453
+ * @private
454
+ */
455
+ function getCarouselItemSize(which) {
456
+ var carousel = this,
457
+ child,
458
+ item,
459
+ size = 0,
460
+ first = carousel.get("firstVisible"),
461
+ vertical = false;
462
+
463
+ if (carousel._itemsTable.numItems === 0) {
464
+ return 0;
465
+ }
466
+
467
+ item = carousel._itemsTable.items[first] ||
468
+ carousel._itemsTable.loading[first];
469
+
470
+ if (JS.isUndefined(item)) {
471
+ return 0;
472
+ }
473
+
474
+ child = Dom.get(item.id);
475
+
476
+ if (typeof which == "undefined") {
477
+ vertical = carousel.get("isVertical");
478
+ } else {
479
+ vertical = which == "height";
480
+ }
481
+
482
+ if (this._itemAttrCache[which]) {
483
+ return this._itemAttrCache[which];
484
+ }
485
+
486
+ if (vertical) {
487
+ size = getStyle(child, "height");
488
+ } else {
489
+ size = getStyle(child, "width");
490
+ }
491
+
492
+ this._itemAttrCache[which] = size;
493
+
494
+ return size;
495
+ }
496
+
497
+ /**
498
+ * Return the size of a part of the item (reveal).
499
+ *
500
+ * @method getRevealSize
501
+ * @private
502
+ */
503
+ function getRevealSize() {
504
+ var carousel = this, isVertical, sz;
505
+
506
+ isVertical = carousel.get("isVertical");
507
+ sz = getCarouselItemSize.call(carousel,
508
+ isVertical ? "height" : "width");
509
+ return (sz * carousel.get("revealAmount") / 100);
510
+ }
511
+
512
+ /**
513
+ * Compute and return the position of a Carousel item based on its
514
+ * position.
515
+ *
516
+ * @method getCarouselItemPosition
517
+ * @param position {Number} The position of the Carousel item.
518
+ * @private
519
+ */
520
+ function getCarouselItemPosition(pos) {
521
+ var carousel = this,
522
+ itemsPerRow = carousel._cols,
523
+ itemsPerCol = carousel._rows,
524
+ page,
525
+ sz,
526
+ isVertical,
527
+ itemsCol,
528
+ itemsRow,
529
+ sentinel,
530
+ delta = 0,
531
+ top,
532
+ left,
533
+ rsz,
534
+ styles = {},
535
+ index = 0,
536
+ itemsTable = carousel._itemsTable,
537
+ items = itemsTable.items,
538
+ loading = itemsTable.loading;
539
+
540
+ isVertical = carousel.get("isVertical");
541
+ sz = getCarouselItemSize.call(carousel,
542
+ isVertical ? "height" : "width");
543
+ rsz = getRevealSize.call(carousel);
544
+
545
+ // adjust for items not yet loaded
546
+ while (index < pos) {
547
+ if (!items[index] && !loading[index]) {
548
+ delta++;
549
+ }
550
+ index++;
551
+ }
552
+ pos -= delta;
553
+
554
+ if (itemsPerCol) {
555
+ page = this.getPageForItem(pos);
556
+ if (isVertical) {
557
+ itemsRow = Math.floor(pos/itemsPerRow);
558
+ delta = itemsRow;
559
+ top = delta * sz;
560
+ styles.top = (top + rsz) + "px";
561
+
562
+ sz = getCarouselItemSize.call(carousel, "width");
563
+
564
+ itemsCol = pos % itemsPerRow;
565
+ delta = itemsCol;
566
+ left = delta * sz;
567
+ styles.left = left + "px";
568
+ } else {
569
+ itemsCol = pos % itemsPerRow;
570
+ sentinel = (page - 1) * itemsPerRow;
571
+ delta = itemsCol + sentinel;
572
+ left = delta * sz;
573
+ styles.left = (left + rsz) + "px";
574
+
575
+ sz = getCarouselItemSize.call(carousel, "height");
576
+
577
+ itemsRow = Math.floor(pos/itemsPerRow);
578
+ sentinel = (page - 1) * itemsPerCol;
579
+ delta = itemsRow - sentinel;
580
+ top = delta * sz;
581
+
582
+ styles.top = top + "px";
583
+ }
584
+ } else {
585
+ if (isVertical) {
586
+ styles.left = 0;
587
+ styles.top = ((pos * sz) + rsz) + "px";
588
+ } else {
589
+ styles.top = 0;
590
+ styles.left = ((pos * sz) + rsz) + "px";
591
+ }
592
+ }
593
+
594
+ return styles;
595
+ }
596
+
597
+ /**
598
+ * Return the index of the first item in the view port for displaying item
599
+ * in "pos".
600
+ *
601
+ * @method getFirstVisibleForPosition
602
+ * @param pos {Number} The position of the item to be displayed
603
+ * @private
604
+ */
605
+ function getFirstVisibleForPosition(pos) {
606
+ var num = this.get("numVisible");
607
+ return Math.floor(pos / num) * num;
608
+ }
609
+
610
+ /**
611
+ * Return the scrolling offset size given the number of elements to
612
+ * scroll.
613
+ *
614
+ * @method getScrollOffset
615
+ * @param delta {Number} The delta number of elements to scroll by.
616
+ * @private
617
+ */
618
+ function getScrollOffset(delta) {
619
+ var itemSize = 0,
620
+ size = 0;
621
+
622
+ itemSize = getCarouselItemSize.call(this);
623
+ size = itemSize * delta;
624
+
625
+ return size;
626
+ }
627
+
628
+ /**
629
+ * Scroll the Carousel by a page backward.
630
+ *
631
+ * @method scrollPageBackward
632
+ * @param {Event} ev The event object
633
+ * @param {Object} obj The context object
634
+ * @private
635
+ */
636
+ function scrollPageBackward(ev, obj) {
637
+ obj.scrollPageBackward();
638
+ Event.preventDefault(ev);
639
+ }
640
+
641
+ /**
642
+ * Scroll the Carousel by a page forward.
643
+ *
644
+ * @method scrollPageForward
645
+ * @param {Event} ev The event object
646
+ * @param {Object} obj The context object
647
+ * @private
648
+ */
649
+ function scrollPageForward(ev, obj) {
650
+ obj.scrollPageForward();
651
+ Event.preventDefault(ev);
652
+ }
653
+
654
+ /**
655
+ * Set the selected item.
656
+ *
657
+ * @method setItemSelection
658
+ * @param {Number} newpos The index of the new position
659
+ * @param {Number} oldpos The index of the previous position
660
+ * @private
661
+ */
662
+ function setItemSelection(newpos, oldpos) {
663
+ var carousel = this,
664
+ cssClass = carousel.CLASSES,
665
+ el,
666
+ firstItem = carousel._firstItem,
667
+ isCircular = carousel.get("isCircular"),
668
+ numItems = carousel.get("numItems"),
669
+ numVisible = carousel.get("numVisible"),
670
+ position = oldpos,
671
+ sentinel = firstItem + numVisible - 1;
672
+
673
+ if (position >= 0 && position < numItems) {
674
+ if (!JS.isUndefined(carousel._itemsTable.items[position])) {
675
+ el = Dom.get(carousel._itemsTable.items[position].id);
676
+ if (el) {
677
+ Dom.removeClass(el, cssClass.SELECTED_ITEM);
678
+ }
679
+ }
680
+ }
681
+
682
+ if (JS.isNumber(newpos)) {
683
+ newpos = parseInt(newpos, 10);
684
+ newpos = JS.isNumber(newpos) ? newpos : 0;
685
+ } else {
686
+ newpos = firstItem;
687
+ }
688
+
689
+ if (JS.isUndefined(carousel._itemsTable.items[newpos])) {
690
+ newpos = getFirstVisibleForPosition.call(carousel, newpos);
691
+ carousel.scrollTo(newpos); // still loading the item
692
+ }
693
+
694
+ if (!JS.isUndefined(carousel._itemsTable.items[newpos])) {
695
+ el = Dom.get(carousel._itemsTable.items[newpos].id);
696
+ if (el) {
697
+ Dom.addClass(el, cssClass.SELECTED_ITEM);
698
+ }
699
+ }
700
+
701
+ if (newpos < firstItem || newpos > sentinel) { // out of focus
702
+ newpos = getFirstVisibleForPosition.call(carousel, newpos);
703
+ carousel.scrollTo(newpos);
704
+ }
705
+ }
706
+
707
+ /**
708
+ * Fire custom events for enabling/disabling navigation elements.
709
+ *
710
+ * @method syncNavigation
711
+ * @private
712
+ */
713
+ function syncNavigation() {
714
+ var attach = false,
715
+ carousel = this,
716
+ cssClass = carousel.CLASSES,
717
+ i,
718
+ navigation,
719
+ sentinel;
720
+
721
+ // Don't do anything if the Carousel is not rendered
722
+ if (!carousel._hasRendered) {
723
+ return;
724
+ }
725
+
726
+ navigation = carousel.get("navigation");
727
+ sentinel = carousel._firstItem + carousel.get("numVisible");
728
+
729
+ if (navigation.prev) {
730
+ if (carousel.get("numItems") === 0 || carousel._firstItem === 0) {
731
+ if (carousel.get("numItems") === 0 ||
732
+ !carousel.get("isCircular")) {
733
+ Event.removeListener(navigation.prev, "click",
734
+ scrollPageBackward);
735
+ Dom.addClass(navigation.prev, cssClass.FIRST_NAV_DISABLED);
736
+ for (i = 0; i < carousel._navBtns.prev.length; i++) {
737
+ carousel._navBtns.prev[i].setAttribute("disabled",
738
+ "true");
739
+ }
740
+ carousel._prevEnabled = false;
741
+ } else {
742
+ attach = !carousel._prevEnabled;
743
+ }
744
+ } else {
745
+ attach = !carousel._prevEnabled;
746
+ }
747
+
748
+ if (attach) {
749
+ Event.on(navigation.prev, "click", scrollPageBackward,
750
+ carousel);
751
+ Dom.removeClass(navigation.prev, cssClass.FIRST_NAV_DISABLED);
752
+ for (i = 0; i < carousel._navBtns.prev.length; i++) {
753
+ carousel._navBtns.prev[i].removeAttribute("disabled");
754
+ }
755
+ carousel._prevEnabled = true;
756
+ }
757
+ }
758
+
759
+ attach = false;
760
+ if (navigation.next) {
761
+ if (sentinel >= carousel.get("numItems")) {
762
+ if (!carousel.get("isCircular")) {
763
+ Event.removeListener(navigation.next, "click",
764
+ scrollPageForward);
765
+ Dom.addClass(navigation.next, cssClass.DISABLED);
766
+ for (i = 0; i < carousel._navBtns.next.length; i++) {
767
+ carousel._navBtns.next[i].setAttribute("disabled",
768
+ "true");
769
+ }
770
+ carousel._nextEnabled = false;
771
+ } else {
772
+ attach = !carousel._nextEnabled;
773
+ }
774
+ } else {
775
+ attach = !carousel._nextEnabled;
776
+ }
777
+
778
+ if (attach) {
779
+ Event.on(navigation.next, "click", scrollPageForward,
780
+ carousel);
781
+ Dom.removeClass(navigation.next, cssClass.DISABLED);
782
+ for (i = 0; i < carousel._navBtns.next.length; i++) {
783
+ carousel._navBtns.next[i].removeAttribute("disabled");
784
+ }
785
+ carousel._nextEnabled = true;
786
+ }
787
+ }
788
+
789
+ carousel.fireEvent(navigationStateChangeEvent,
790
+ { next: carousel._nextEnabled, prev: carousel._prevEnabled });
791
+ }
792
+
793
+ /**
794
+ * Synchronize and redraw the Pager UI if necessary.
795
+ *
796
+ * @method syncPagerUi
797
+ * @private
798
+ */
799
+ function syncPagerUi(page) {
800
+ var carousel = this, numPages, numVisible;
801
+
802
+ // Don't do anything if the Carousel is not rendered
803
+ if (!carousel._hasRendered) {
804
+ return;
805
+ }
806
+
807
+ numVisible = carousel.get("numVisible");
808
+
809
+ if (!JS.isNumber(page)) {
810
+ page = Math.floor(carousel.get("selectedItem") / numVisible);
811
+ }
812
+
813
+ numPages = Math.ceil(carousel.get("numItems") / numVisible);
814
+
815
+ carousel._pages.num = numPages;
816
+ carousel._pages.cur = page;
817
+
818
+ if (numPages > carousel.CONFIG.MAX_PAGER_BUTTONS) {
819
+ carousel._updatePagerMenu();
820
+ } else {
821
+ carousel._updatePagerButtons();
822
+ }
823
+ }
824
+
825
+ /**
826
+ * Get full dimensions of an element.
827
+ *
828
+ * @method getDimensions
829
+ * @param {Object} el The element to get the dimensions of
830
+ * @param {String} which Get the height or width of an element
831
+ * @private
832
+ */
833
+ function getDimensions(el, which) {
834
+ switch (which) {
835
+ case 'height':
836
+ return getStyle(el, "marginTop") +
837
+ getStyle(el, "marginBottom") +
838
+ getStyle(el, "paddingTop") +
839
+ getStyle(el, "paddingBottom") +
840
+ getStyle(el, "borderTopWidth") +
841
+ getStyle(el, "borderBottomWidth");
842
+ case 'width':
843
+ return getStyle(el, "marginLeft") +
844
+ getStyle(el, "marginRight") +
845
+ getStyle(el, "paddingLeft") +
846
+ getStyle(el, "paddingRight") +
847
+ getStyle(el, "borderLeftWidth") +
848
+ getStyle(el, "borderRightWidth");
849
+ default:
850
+ break;
851
+ }
852
+
853
+ return getStyle(el, which);
854
+ }
855
+
856
+ /**
857
+ * Handle UI update.
858
+ * Call the appropriate methods on events fired when an item is added, or
859
+ * removed for synchronizing the DOM.
860
+ *
861
+ * @method syncUi
862
+ * @param {Object} o The item that needs to be added or removed
863
+ * @private
864
+ */
865
+ function syncUi(o) {
866
+ var carousel = this;
867
+
868
+ if (!JS.isObject(o)) {
869
+ return;
870
+ }
871
+
872
+ switch (o.ev) {
873
+ case itemAddedEvent:
874
+ carousel._syncUiForItemAdd(o);
875
+ break;
876
+ case itemRemovedEvent:
877
+ carousel._syncUiForItemRemove(o);
878
+ break;
879
+ case itemReplacedEvent:
880
+ carousel._syncUiForItemReplace(o);
881
+ break;
882
+ case loadItemsEvent:
883
+ carousel._syncUiForLazyLoading(o);
884
+ break;
885
+ }
886
+
887
+ carousel.fireEvent(uiUpdateEvent);
888
+ }
889
+
890
+ /**
891
+ * Update the state variables after scrolling the Carousel view port.
892
+ *
893
+ * @method updateStateAfterScroll
894
+ * @param {Integer} item The index to which the Carousel has scrolled to.
895
+ * @param {Integer} sentinel The last element in the view port.
896
+ * @private
897
+ */
898
+ function updateStateAfterScroll(item, sentinel) {
899
+ var carousel = this,
900
+ page = carousel.get("currentPage"),
901
+ newPage,
902
+ numPerPage = carousel.get("numVisible");
903
+
904
+ newPage = parseInt(carousel._firstItem / numPerPage, 10);
905
+ if (newPage != page) {
906
+ carousel.setAttributeConfig("currentPage", { value: newPage });
907
+ carousel.fireEvent(pageChangeEvent, newPage);
908
+ }
909
+
910
+ if (carousel.get("selectOnScroll")) {
911
+ if (carousel.get("selectedItem") != carousel._selectedItem) {
912
+ carousel.set("selectedItem", carousel._selectedItem);
913
+ }
914
+ }
915
+
916
+ clearTimeout(carousel._autoPlayTimer);
917
+ delete carousel._autoPlayTimer;
918
+ if (carousel.isAutoPlayOn()) {
919
+ carousel.startAutoPlay();
920
+ }
921
+
922
+ carousel.fireEvent(afterScrollEvent,
923
+ { first: carousel._firstItem,
924
+ last: sentinel },
925
+ carousel);
926
+ }
927
+
928
+ /*
929
+ * Static members and methods of the Carousel component
930
+ */
931
+
932
+ /**
933
+ * Return the appropriate Carousel object based on the id associated with
934
+ * the Carousel element or false if none match.
935
+ * @method getById
936
+ * @public
937
+ * @static
938
+ */
939
+ Carousel.getById = function (id) {
940
+ return instances[id] ? instances[id].object : false;
941
+ };
942
+
943
+ YAHOO.extend(Carousel, YAHOO.util.Element, {
944
+
945
+ /*
946
+ * Internal variables used within the Carousel component
947
+ */
948
+
949
+ /**
950
+ * Number of rows for a multirow carousel.
951
+ *
952
+ * @property _rows
953
+ * @private
954
+ */
955
+ _rows: null,
956
+
957
+ /**
958
+ * Number of cols for a multirow carousel.
959
+ *
960
+ * @property _cols
961
+ * @private
962
+ */
963
+ _cols: null,
964
+
965
+ /**
966
+ * The Animation object.
967
+ *
968
+ * @property _animObj
969
+ * @private
970
+ */
971
+ _animObj: null,
972
+
973
+ /**
974
+ * The Carousel element.
975
+ *
976
+ * @property _carouselEl
977
+ * @private
978
+ */
979
+ _carouselEl: null,
980
+
981
+ /**
982
+ * The Carousel clipping container element.
983
+ *
984
+ * @property _clipEl
985
+ * @private
986
+ */
987
+ _clipEl: null,
988
+
989
+ /**
990
+ * The current first index of the Carousel.
991
+ *
992
+ * @property _firstItem
993
+ * @private
994
+ */
995
+ _firstItem: 0,
996
+
997
+ /**
998
+ * Does the Carousel element have focus?
999
+ *
1000
+ * @property _hasFocus
1001
+ * @private
1002
+ */
1003
+ _hasFocus: false,
1004
+
1005
+ /**
1006
+ * Is the Carousel rendered already?
1007
+ *
1008
+ * @property _hasRendered
1009
+ * @private
1010
+ */
1011
+ _hasRendered: false,
1012
+
1013
+ /**
1014
+ * Is the animation still in progress?
1015
+ *
1016
+ * @property _isAnimationInProgress
1017
+ * @private
1018
+ */
1019
+ _isAnimationInProgress: false,
1020
+
1021
+ /**
1022
+ * Is the auto-scrolling of Carousel in progress?
1023
+ *
1024
+ * @property _isAutoPlayInProgress
1025
+ * @private
1026
+ */
1027
+ _isAutoPlayInProgress: false,
1028
+
1029
+ /**
1030
+ * The table of items in the Carousel.
1031
+ * The numItems is the number of items in the Carousel, items being the
1032
+ * array of items in the Carousel. The size is the size of a single
1033
+ * item in the Carousel. It is cached here for efficiency (to avoid
1034
+ * computing the size multiple times).
1035
+ *
1036
+ * @property _itemsTable
1037
+ * @private
1038
+ */
1039
+ _itemsTable: null,
1040
+
1041
+ /**
1042
+ * The Carousel navigation buttons.
1043
+ *
1044
+ * @property _navBtns
1045
+ * @private
1046
+ */
1047
+ _navBtns: null,
1048
+
1049
+ /**
1050
+ * The Carousel navigation.
1051
+ *
1052
+ * @property _navEl
1053
+ * @private
1054
+ */
1055
+ _navEl: null,
1056
+
1057
+ /**
1058
+ * Status of the next navigation item.
1059
+ *
1060
+ * @property _nextEnabled
1061
+ * @private
1062
+ */
1063
+ _nextEnabled: true,
1064
+
1065
+ /**
1066
+ * The Carousel pages structure.
1067
+ * This is an object of the total number of pages and the current page.
1068
+ *
1069
+ * @property _pages
1070
+ * @private
1071
+ */
1072
+ _pages: null,
1073
+
1074
+ /**
1075
+ * The Carousel pagination structure.
1076
+ *
1077
+ * @property _pagination
1078
+ * @private
1079
+ */
1080
+ _pagination: {},
1081
+
1082
+ /**
1083
+ * Status of the previous navigation item.
1084
+ *
1085
+ * @property _prevEnabled
1086
+ * @private
1087
+ */
1088
+ _prevEnabled: true,
1089
+
1090
+ /**
1091
+ * Whether the Carousel size needs to be recomputed or not?
1092
+ *
1093
+ * @property _recomputeSize
1094
+ * @private
1095
+ */
1096
+ _recomputeSize: true,
1097
+
1098
+ /**
1099
+ * Cache the Carousel item attributes.
1100
+ *
1101
+ * @property _itemAttrCache
1102
+ * @private
1103
+ */
1104
+ _itemAttrCache: {},
1105
+
1106
+ /*
1107
+ * CSS classes used by the Carousel component
1108
+ */
1109
+
1110
+ CLASSES: {
1111
+
1112
+ /**
1113
+ * The class name of the Carousel navigation buttons.
1114
+ *
1115
+ * @property BUTTON
1116
+ * @default "yui-carousel-button"
1117
+ */
1118
+ BUTTON: "yui-carousel-button",
1119
+
1120
+ /**
1121
+ * The class name of the Carousel element.
1122
+ *
1123
+ * @property CAROUSEL
1124
+ * @default "yui-carousel"
1125
+ */
1126
+ CAROUSEL: "yui-carousel",
1127
+
1128
+ /**
1129
+ * The class name of the container of the items in the Carousel.
1130
+ *
1131
+ * @property CAROUSEL_EL
1132
+ * @default "yui-carousel-element"
1133
+ */
1134
+ CAROUSEL_EL: "yui-carousel-element",
1135
+
1136
+ /**
1137
+ * The class name of the Carousel's container element.
1138
+ *
1139
+ * @property CONTAINER
1140
+ * @default "yui-carousel-container"
1141
+ */
1142
+ CONTAINER: "yui-carousel-container",
1143
+
1144
+ /**
1145
+ * The class name of the Carousel's container element.
1146
+ *
1147
+ * @property CONTENT
1148
+ * @default "yui-carousel-content"
1149
+ */
1150
+ CONTENT: "yui-carousel-content",
1151
+
1152
+ /**
1153
+ * The class name of a disabled navigation button.
1154
+ *
1155
+ * @property DISABLED
1156
+ * @default "yui-carousel-button-disabled"
1157
+ */
1158
+ DISABLED: "yui-carousel-button-disabled",
1159
+
1160
+ /**
1161
+ * The class name of the first Carousel navigation button.
1162
+ *
1163
+ * @property FIRST_NAV
1164
+ * @default " yui-carousel-first-button"
1165
+ */
1166
+ FIRST_NAV: " yui-carousel-first-button",
1167
+
1168
+ /**
1169
+ * The class name of a first disabled navigation button.
1170
+ *
1171
+ * @property FIRST_NAV_DISABLED
1172
+ * @default "yui-carousel-first-button-disabled"
1173
+ */
1174
+ FIRST_NAV_DISABLED: "yui-carousel-first-button-disabled",
1175
+
1176
+ /**
1177
+ * The class name of a first page element.
1178
+ *
1179
+ * @property FIRST_PAGE
1180
+ * @default "yui-carousel-nav-first-page"
1181
+ */
1182
+ FIRST_PAGE: "yui-carousel-nav-first-page",
1183
+
1184
+ /**
1185
+ * The class name of the Carousel navigation button that has focus.
1186
+ *
1187
+ * @property FOCUSSED_BUTTON
1188
+ * @default "yui-carousel-button-focus"
1189
+ */
1190
+ FOCUSSED_BUTTON: "yui-carousel-button-focus",
1191
+
1192
+ /**
1193
+ * The class name of a horizontally oriented Carousel.
1194
+ *
1195
+ * @property HORIZONTAL
1196
+ * @default "yui-carousel-horizontal"
1197
+ */
1198
+ HORIZONTAL: "yui-carousel-horizontal",
1199
+
1200
+ /**
1201
+ * The element to be used as the progress indicator when the item
1202
+ * is still being loaded.
1203
+ *
1204
+ * @property ITEM_LOADING
1205
+ * @default The progress indicator (spinner) image CSS class
1206
+ */
1207
+ ITEM_LOADING: "yui-carousel-item-loading",
1208
+
1209
+ /**
1210
+ * The class name that will be set if the Carousel adjusts itself
1211
+ * for a minimum width.
1212
+ *
1213
+ * @property MIN_WIDTH
1214
+ * @default "yui-carousel-min-width"
1215
+ */
1216
+ MIN_WIDTH: "yui-carousel-min-width",
1217
+
1218
+ /**
1219
+ * The navigation element container class name.
1220
+ *
1221
+ * @property NAVIGATION
1222
+ * @default "yui-carousel-nav"
1223
+ */
1224
+ NAVIGATION: "yui-carousel-nav",
1225
+
1226
+ /**
1227
+ * The class name of the next Carousel navigation button.
1228
+ *
1229
+ * @property NEXT_NAV
1230
+ * @default " yui-carousel-next-button"
1231
+ */
1232
+ NEXT_NAV: " yui-carousel-next-button",
1233
+
1234
+ /**
1235
+ * The class name of the next navigation link. This variable is
1236
+ * not only used for styling, but also for identifying the link
1237
+ * within the Carousel container.
1238
+ *
1239
+ * @property NEXT_PAGE
1240
+ * @default "yui-carousel-next"
1241
+ */
1242
+ NEXT_PAGE: "yui-carousel-next",
1243
+
1244
+ /**
1245
+ * The class name for the navigation container for prev/next.
1246
+ *
1247
+ * @property NAV_CONTAINER
1248
+ * @default "yui-carousel-buttons"
1249
+ */
1250
+ NAV_CONTAINER: "yui-carousel-buttons",
1251
+
1252
+ /**
1253
+ * The class name for an item in the pager UL or dropdown menu.
1254
+ *
1255
+ * @property PAGER_ITEM
1256
+ * @default "yui-carousel-pager-item"
1257
+ */
1258
+ PAGER_ITEM: "yui-carousel-pager-item",
1259
+
1260
+ /**
1261
+ * The class name for the pagination container
1262
+ *
1263
+ * @property PAGINATION
1264
+ * @default "yui-carousel-pagination"
1265
+ */
1266
+ PAGINATION: "yui-carousel-pagination",
1267
+
1268
+ /**
1269
+ * The class name of the focussed page navigation. This class is
1270
+ * specifically used for the ugly focus handling in Opera.
1271
+ *
1272
+ * @property PAGE_FOCUS
1273
+ * @default "yui-carousel-nav-page-focus"
1274
+ */
1275
+ PAGE_FOCUS: "yui-carousel-nav-page-focus",
1276
+
1277
+ /**
1278
+ * The class name of the previous navigation link. This variable
1279
+ * is not only used for styling, but also for identifying the link
1280
+ * within the Carousel container.
1281
+ *
1282
+ * @property PREV_PAGE
1283
+ * @default "yui-carousel-prev"
1284
+ */
1285
+ PREV_PAGE: "yui-carousel-prev",
1286
+
1287
+ /**
1288
+ * The class name of the selected item.
1289
+ *
1290
+ * @property SELECTED_ITEM
1291
+ * @default "yui-carousel-item-selected"
1292
+ */
1293
+ SELECTED_ITEM: "yui-carousel-item-selected",
1294
+
1295
+ /**
1296
+ * The class name of the selected paging navigation.
1297
+ *
1298
+ * @property SELECTED_NAV
1299
+ * @default "yui-carousel-nav-page-selected"
1300
+ */
1301
+ SELECTED_NAV: "yui-carousel-nav-page-selected",
1302
+
1303
+ /**
1304
+ * The class name of a vertically oriented Carousel.
1305
+ *
1306
+ * @property VERTICAL
1307
+ * @default "yui-carousel-vertical"
1308
+ */
1309
+ VERTICAL: "yui-carousel-vertical",
1310
+
1311
+ /**
1312
+ * The class name of a multirow Carousel.
1313
+ *
1314
+ * @property MULTI_ROW
1315
+ * @default "yui-carousel-multi-row"
1316
+ */
1317
+ MULTI_ROW: "yui-carousel-multi-row",
1318
+
1319
+ /**
1320
+ * The class name of a row in a multirow Carousel.
1321
+ *
1322
+ * @property ROW
1323
+ * @default "yui-carousel-new-row"
1324
+ */
1325
+ ROW: "yui-carousel-row",
1326
+
1327
+ /**
1328
+ * The class name of a vertical Carousel's container element.
1329
+ *
1330
+ * @property VERTICAL_CONTAINER
1331
+ * @default "yui-carousel-vertical-container"
1332
+ */
1333
+ VERTICAL_CONTAINER: "yui-carousel-vertical-container",
1334
+
1335
+ /**
1336
+ * The class name of a visible Carousel.
1337
+ *
1338
+ * @property VISIBLE
1339
+ * @default "yui-carousel-visible"
1340
+ */
1341
+ VISIBLE: "yui-carousel-visible"
1342
+
1343
+ },
1344
+
1345
+ /*
1346
+ * Configuration attributes for configuring the Carousel component
1347
+ */
1348
+
1349
+ CONFIG: {
1350
+
1351
+ /**
1352
+ * The offset of the first visible item in the Carousel.
1353
+ *
1354
+ * @property FIRST_VISIBLE
1355
+ * @default 0
1356
+ */
1357
+ FIRST_VISIBLE: 0,
1358
+
1359
+ /**
1360
+ * The minimum width of the horizontal Carousel container to support
1361
+ * the navigation buttons.
1362
+ *
1363
+ * @property HORZ_MIN_WIDTH
1364
+ * @default 180
1365
+ */
1366
+ HORZ_MIN_WIDTH: 180,
1367
+
1368
+ /**
1369
+ * The maximum number of pager buttons allowed beyond which the UI
1370
+ * of the pager would be a drop-down of pages instead of buttons.
1371
+ *
1372
+ * @property MAX_PAGER_BUTTONS
1373
+ * @default 5
1374
+ */
1375
+ MAX_PAGER_BUTTONS: 5,
1376
+
1377
+ /**
1378
+ * The minimum width of the vertical Carousel container to support
1379
+ * the navigation buttons.
1380
+ *
1381
+ * @property VERT_MIN_WIDTH
1382
+ * @default 155
1383
+ */
1384
+ VERT_MIN_WIDTH: 115,
1385
+
1386
+ /**
1387
+ * The number of visible items in the Carousel.
1388
+ *
1389
+ * @property NUM_VISIBLE
1390
+ * @default 3
1391
+ */
1392
+ NUM_VISIBLE: 3
1393
+
1394
+ },
1395
+
1396
+ /*
1397
+ * Internationalizable strings in the Carousel component
1398
+ */
1399
+
1400
+ STRINGS: {
1401
+
1402
+ /**
1403
+ * The content to be used as the progress indicator when the item
1404
+ * is still being loaded.
1405
+ *
1406
+ * @property ITEM_LOADING_CONTENT
1407
+ * @default "Loading"
1408
+ */
1409
+ ITEM_LOADING_CONTENT: "Loading",
1410
+
1411
+ /**
1412
+ * The next navigation button name/text.
1413
+ *
1414
+ * @property NEXT_BUTTON_TEXT
1415
+ * @default "Next Page"
1416
+ */
1417
+ NEXT_BUTTON_TEXT: "Next Page",
1418
+
1419
+ /**
1420
+ * The prefix text for the pager in case the UI is a drop-down.
1421
+ *
1422
+ * @property PAGER_PREFIX_TEXT
1423
+ * @default "Go to page "
1424
+ */
1425
+ PAGER_PREFIX_TEXT: "Go to page ",
1426
+
1427
+ /**
1428
+ * The previous navigation button name/text.
1429
+ *
1430
+ * @property PREVIOUS_BUTTON_TEXT
1431
+ * @default "Previous Page"
1432
+ */
1433
+ PREVIOUS_BUTTON_TEXT: "Previous Page"
1434
+
1435
+ },
1436
+
1437
+ /*
1438
+ * Public methods of the Carousel component
1439
+ */
1440
+
1441
+ /**
1442
+ * Insert or append an item to the Carousel.
1443
+ * E.g. if Object: ({content:"Your Content", id:"", className:""}, index)
1444
+ *
1445
+ * @method addItem
1446
+ * @public
1447
+ * @param item {String | Object | HTMLElement} The item to be appended
1448
+ * to the Carousel. If the parameter is a string, it is assumed to be
1449
+ * the content of the newly created item. If the parameter is an
1450
+ * object, it is assumed to supply the content and an optional class
1451
+ * and an optional id of the newly created item.
1452
+ * @param index {Number} optional The position to where in the list
1453
+ * (starts from zero).
1454
+ * @return {Boolean} Return true on success, false otherwise
1455
+ */
1456
+ addItem: function (item, index) {
1457
+ var carousel = this,
1458
+ className,
1459
+ content,
1460
+ elId,
1461
+ replaceItems = 0,
1462
+ newIndex, // Add newIndex as workaround for undefined pos
1463
+ numItems = carousel.get("numItems");
1464
+
1465
+ if (!item) {
1466
+ return false;
1467
+ }
1468
+
1469
+ if (JS.isString(item) || item.nodeName) {
1470
+ content = item.nodeName ? item.innerHTML : item;
1471
+ } else if (JS.isObject(item)) {
1472
+ content = item.content;
1473
+ } else {
1474
+ return false;
1475
+ }
1476
+
1477
+ className = item.className || "";
1478
+ elId = item.id ? item.id : Dom.generateId();
1479
+
1480
+ if (JS.isUndefined(index)) {
1481
+ carousel._itemsTable.items.push({
1482
+ item : content,
1483
+ className : className,
1484
+ id : elId
1485
+ });
1486
+ // Add newIndex as workaround for undefined pos
1487
+ newIndex = carousel._itemsTable.items.length-1;
1488
+ } else {
1489
+ if (index < 0 || index > numItems) {
1490
+ return false;
1491
+ }
1492
+
1493
+ // make sure we splice into the correct position
1494
+ if(!carousel._itemsTable.items[index]){
1495
+ carousel._itemsTable.items[index] = undefined;
1496
+ replaceItems = 1;
1497
+ }
1498
+
1499
+ carousel._itemsTable.items.splice(index, replaceItems, {
1500
+ item : content,
1501
+ className : className,
1502
+ id : elId
1503
+ });
1504
+ }
1505
+ carousel._itemsTable.numItems++;
1506
+
1507
+ if (numItems < carousel._itemsTable.items.length) {
1508
+ carousel.set("numItems", carousel._itemsTable.items.length);
1509
+ }
1510
+
1511
+ // Add newPos as workaround for undefined pos
1512
+ carousel.fireEvent(itemAddedEvent, { pos: index, ev: itemAddedEvent, newPos:newIndex });
1513
+
1514
+ return true;
1515
+ },
1516
+
1517
+ /**
1518
+ * Insert or append multiple items to the Carousel.
1519
+ *
1520
+ * @method addItems
1521
+ * @public
1522
+ * @param items {Array} An array containing an array of new items each linked to the
1523
+ * index where the insertion should take place.
1524
+ * E.g. [[{content:'<img/>'}, index1], [{content:'<img/>'}, index2]]
1525
+ * NOTE: An item at index must already exist.
1526
+ * @return {Boolean} Return true on success, false otherwise
1527
+ */
1528
+ addItems: function (items) {
1529
+ var i, n, rv = true;
1530
+
1531
+ if (!JS.isArray(items)) {
1532
+ return false;
1533
+ }
1534
+
1535
+ for (i = 0, n = items.length; i < n; i++) {
1536
+ if (this.addItem(items[i][0], items[i][1]) === false) {
1537
+ rv = false;
1538
+ }
1539
+ }
1540
+
1541
+ return rv;
1542
+ },
1543
+
1544
+ /**
1545
+ * Remove focus from the Carousel.
1546
+ *
1547
+ * @method blur
1548
+ * @public
1549
+ */
1550
+ blur: function () {
1551
+ this._carouselEl.blur();
1552
+ this.fireEvent(blurEvent);
1553
+ },
1554
+
1555
+ /**
1556
+ * Clears the items from Carousel.
1557
+ *
1558
+ * @method clearItems
1559
+ * @public
1560
+ */
1561
+ clearItems: function () {
1562
+ var carousel = this, n = carousel.get("numItems");
1563
+
1564
+ while (n > 0) {
1565
+ if (!carousel.removeItem(0)) {
1566
+ }
1567
+ /*
1568
+ For dynamic loading, the numItems may be much larger than
1569
+ the actual number of items in the table. So, set the
1570
+ numItems to zero, and break out of the loop if the table
1571
+ is already empty.
1572
+ */
1573
+ if (carousel._itemsTable.numItems === 0) {
1574
+ carousel.set("numItems", 0);
1575
+ break;
1576
+ }
1577
+ n--;
1578
+ }
1579
+
1580
+ carousel.fireEvent(allItemsRemovedEvent);
1581
+ },
1582
+
1583
+ /**
1584
+ * Set focus on the Carousel.
1585
+ *
1586
+ * @method focus
1587
+ * @public
1588
+ */
1589
+ focus: function () {
1590
+ var carousel = this,
1591
+ first,
1592
+ focusEl,
1593
+ isSelectionInvisible,
1594
+ itemsTable,
1595
+ last,
1596
+ numVisible,
1597
+ selectOnScroll,
1598
+ selected,
1599
+ selItem;
1600
+
1601
+ // Don't do anything if the Carousel is not rendered
1602
+ if (!carousel._hasRendered) {
1603
+ return;
1604
+ }
1605
+
1606
+ if (carousel.isAnimating()) {
1607
+ // this messes up real bad!
1608
+ return;
1609
+ }
1610
+
1611
+ selItem = carousel.get("selectedItem");
1612
+ numVisible = carousel.get("numVisible");
1613
+ selectOnScroll = carousel.get("selectOnScroll");
1614
+ selected = (selItem >= 0) ?
1615
+ carousel.getItem(selItem) : null;
1616
+ first = carousel.get("firstVisible");
1617
+ last = first + numVisible - 1;
1618
+ isSelectionInvisible = (selItem < first || selItem > last);
1619
+ focusEl = (selected && selected.id) ?
1620
+ Dom.get(selected.id) : null;
1621
+ itemsTable = carousel._itemsTable;
1622
+
1623
+ if (!selectOnScroll && isSelectionInvisible) {
1624
+ focusEl = (itemsTable && itemsTable.items &&
1625
+ itemsTable.items[first]) ?
1626
+ Dom.get(itemsTable.items[first].id) : null;
1627
+ }
1628
+
1629
+ if (focusEl) {
1630
+ try {
1631
+ focusEl.focus();
1632
+ } catch (ex) {
1633
+ // ignore focus errors
1634
+ }
1635
+ }
1636
+
1637
+ carousel.fireEvent(focusEvent);
1638
+ },
1639
+
1640
+ /**
1641
+ * Hide the Carousel.
1642
+ *
1643
+ * @method hide
1644
+ * @public
1645
+ */
1646
+ hide: function () {
1647
+ var carousel = this;
1648
+
1649
+ if (carousel.fireEvent(beforeHideEvent) !== false) {
1650
+ carousel.removeClass(carousel.CLASSES.VISIBLE);
1651
+ carousel.fireEvent(hideEvent);
1652
+ }
1653
+ },
1654
+
1655
+ /**
1656
+ * Initialize the Carousel.
1657
+ *
1658
+ * @method init
1659
+ * @public
1660
+ * @param el {HTMLElement | String} The html element that represents
1661
+ * the Carousel container.
1662
+ * @param attrs {Object} The set of configuration attributes for
1663
+ * creating the Carousel.
1664
+ */
1665
+ init: function (el, attrs) {
1666
+ var carousel = this,
1667
+ elId = el, // save for a rainy day
1668
+ parse = false,
1669
+ selected;
1670
+
1671
+ if (!el) {
1672
+ return;
1673
+ }
1674
+
1675
+ carousel._hasRendered = false;
1676
+ carousel._navBtns = { prev: [], next: [] };
1677
+ carousel._pages = { el: null, num: 0, cur: 0 };
1678
+ carousel._pagination = {};
1679
+ carousel._itemAttrCache = {};
1680
+
1681
+ carousel._itemsTable = { loading: {}, numItems: 0,
1682
+ items: [], size: 0 };
1683
+
1684
+
1685
+ if (JS.isString(el)) {
1686
+ el = Dom.get(el);
1687
+ } else if (!el.nodeName) {
1688
+ return;
1689
+ }
1690
+
1691
+ Carousel.superclass.init.call(carousel, el, attrs);
1692
+
1693
+ // check if we're starting somewhere in the middle
1694
+ selected = carousel.get("selectedItem");
1695
+ if(selected > 0){
1696
+ carousel.set("firstVisible",getFirstVisibleForPosition.call(carousel,selected));
1697
+ }
1698
+
1699
+ if (el) {
1700
+ if (!el.id) { // in case the HTML element is passed
1701
+ el.setAttribute("id", Dom.generateId());
1702
+ }
1703
+ parse = carousel._parseCarousel(el);
1704
+ if (!parse) {
1705
+ carousel._createCarousel(elId);
1706
+ }
1707
+ } else {
1708
+ el = carousel._createCarousel(elId);
1709
+ }
1710
+ elId = el.id;
1711
+
1712
+ carousel.initEvents();
1713
+
1714
+ if (parse) {
1715
+ carousel._parseCarouselItems();
1716
+ }
1717
+
1718
+ // add the selected class
1719
+ if(selected > 0){
1720
+ setItemSelection.call(carousel,selected,0);
1721
+ }
1722
+
1723
+ if (!attrs || typeof attrs.isVertical == "undefined") {
1724
+ carousel.set("isVertical", false);
1725
+ }
1726
+
1727
+ carousel._parseCarouselNavigation(el);
1728
+ carousel._navEl = carousel._setupCarouselNavigation();
1729
+
1730
+ instances[elId] = { object: carousel };
1731
+ carousel._loadItems(Math.min(carousel.get("firstVisible")+carousel.get("numVisible"),carousel.get("numItems"))-1);
1732
+ },
1733
+
1734
+ /**
1735
+ * Initialize the configuration attributes used to create the Carousel.
1736
+ *
1737
+ * @method initAttributes
1738
+ * @public
1739
+ * @param attrs {Object} The set of configuration attributes for
1740
+ * creating the Carousel.
1741
+ */
1742
+ initAttributes: function (attrs) {
1743
+ var carousel = this;
1744
+
1745
+ attrs = attrs || {};
1746
+ Carousel.superclass.initAttributes.call(carousel, attrs);
1747
+
1748
+ /**
1749
+ * @attribute carouselEl
1750
+ * @description The type of the Carousel element.
1751
+ * @default OL
1752
+ * @type Boolean
1753
+ */
1754
+ carousel.setAttributeConfig("carouselEl", {
1755
+ validator : JS.isString,
1756
+ value : attrs.carouselEl || "OL"
1757
+ });
1758
+
1759
+ /**
1760
+ * @attribute carouselItemEl
1761
+ * @description The type of the list of items within the Carousel.
1762
+ * @default LI
1763
+ * @type Boolean
1764
+ */
1765
+ carousel.setAttributeConfig("carouselItemEl", {
1766
+ validator : JS.isString,
1767
+ value : attrs.carouselItemEl || "LI"
1768
+ });
1769
+
1770
+ /**
1771
+ * @attribute currentPage
1772
+ * @description The current page number (read-only.)
1773
+ * @type Number
1774
+ */
1775
+ carousel.setAttributeConfig("currentPage", {
1776
+ readOnly : true,
1777
+ value : 0
1778
+ });
1779
+
1780
+ /**
1781
+ * @attribute firstVisible
1782
+ * @description The index to start the Carousel from (indexes begin
1783
+ * from zero)
1784
+ * @default 0
1785
+ * @type Number
1786
+ */
1787
+ carousel.setAttributeConfig("firstVisible", {
1788
+ method : carousel._setFirstVisible,
1789
+ validator : carousel._validateFirstVisible,
1790
+ value :
1791
+ attrs.firstVisible || carousel.CONFIG.FIRST_VISIBLE
1792
+ });
1793
+
1794
+ /**
1795
+ * @attribute selectOnScroll
1796
+ * @description Set this to true to automatically set focus to
1797
+ * follow scrolling in the Carousel.
1798
+ * @default true
1799
+ * @type Boolean
1800
+ */
1801
+ carousel.setAttributeConfig("selectOnScroll", {
1802
+ validator : JS.isBoolean,
1803
+ value : attrs.selectOnScroll || true
1804
+ });
1805
+
1806
+ /**
1807
+ * @attribute numVisible
1808
+ * @description The number of visible items in the Carousel's
1809
+ * viewport.
1810
+ * @default 3
1811
+ * @type Number
1812
+ */
1813
+ carousel.setAttributeConfig("numVisible", {
1814
+ setter : carousel._numVisibleSetter,
1815
+ method : carousel._setNumVisible,
1816
+ validator : carousel._validateNumVisible,
1817
+ value : attrs.numVisible || carousel.CONFIG.NUM_VISIBLE
1818
+ });
1819
+
1820
+ /**
1821
+ * @attribute numItems
1822
+ * @description The number of items in the Carousel.
1823
+ * @type Number
1824
+ */
1825
+ carousel.setAttributeConfig("numItems", {
1826
+ method : carousel._setNumItems,
1827
+ validator : carousel._validateNumItems,
1828
+ value : carousel._itemsTable.numItems
1829
+ });
1830
+
1831
+ /**
1832
+ * @attribute scrollIncrement
1833
+ * @description The number of items to scroll by for arrow keys.
1834
+ * @default 1
1835
+ * @type Number
1836
+ */
1837
+ carousel.setAttributeConfig("scrollIncrement", {
1838
+ validator : carousel._validateScrollIncrement,
1839
+ value : attrs.scrollIncrement || 1
1840
+ });
1841
+
1842
+ /**
1843
+ * @attribute selectedItem
1844
+ * @description The index of the selected item.
1845
+ * @type Number
1846
+ */
1847
+ carousel.setAttributeConfig("selectedItem", {
1848
+ setter : carousel._selectedItemSetter,
1849
+ method : carousel._setSelectedItem,
1850
+ validator : JS.isNumber,
1851
+ value : -1
1852
+ });
1853
+
1854
+ /**
1855
+ * @attribute revealAmount
1856
+ * @description The percentage of the item to be revealed on each
1857
+ * side of the Carousel (before and after the first and last item
1858
+ * in the Carousel's viewport.)
1859
+ * @default 0
1860
+ * @type Number
1861
+ */
1862
+ carousel.setAttributeConfig("revealAmount", {
1863
+ method : carousel._setRevealAmount,
1864
+ validator : carousel._validateRevealAmount,
1865
+ value : attrs.revealAmount || 0
1866
+ });
1867
+
1868
+ /**
1869
+ * @attribute isCircular
1870
+ * @description Set this to true to wrap scrolling of the contents
1871
+ * in the Carousel.
1872
+ * @default false
1873
+ * @type Boolean
1874
+ */
1875
+ carousel.setAttributeConfig("isCircular", {
1876
+ validator : JS.isBoolean,
1877
+ value : attrs.isCircular || false
1878
+ });
1879
+
1880
+ /**
1881
+ * @attribute isVertical
1882
+ * @description True if the orientation of the Carousel is vertical
1883
+ * @default false
1884
+ * @type Boolean
1885
+ */
1886
+ carousel.setAttributeConfig("isVertical", {
1887
+ method : carousel._setOrientation,
1888
+ validator : JS.isBoolean,
1889
+ value : attrs.isVertical || false
1890
+ });
1891
+
1892
+ /**
1893
+ * @attribute navigation
1894
+ * @description The set of navigation controls for Carousel
1895
+ * @default <br>
1896
+ * { prev: null, // the previous navigation element<br>
1897
+ * next: null } // the next navigation element
1898
+ * @type Object
1899
+ */
1900
+ carousel.setAttributeConfig("navigation", {
1901
+ method : carousel._setNavigation,
1902
+ validator : carousel._validateNavigation,
1903
+ value :
1904
+ attrs.navigation || {prev: null,next: null,page: null}
1905
+ });
1906
+
1907
+ /**
1908
+ * @attribute animation
1909
+ * @description The optional animation attributes for the Carousel.
1910
+ * @default <br>
1911
+ * { speed: 0, // the animation speed (in seconds)<br>
1912
+ * effect: null } // the animation effect (like
1913
+ * YAHOO.util.Easing.easeOut)
1914
+ * @type Object
1915
+ */
1916
+ carousel.setAttributeConfig("animation", {
1917
+ validator : carousel._validateAnimation,
1918
+ value : attrs.animation || { speed: 0, effect: null }
1919
+ });
1920
+
1921
+ /**
1922
+ * @attribute autoPlay
1923
+ * @description Set this to time in milli-seconds to have the
1924
+ * Carousel automatically scroll the contents.
1925
+ * @type Number
1926
+ * @deprecated Use autoPlayInterval instead.
1927
+ */
1928
+ carousel.setAttributeConfig("autoPlay", {
1929
+ validator : JS.isNumber,
1930
+ value : attrs.autoPlay || 0
1931
+ });
1932
+
1933
+ /**
1934
+ * @attribute autoPlayInterval
1935
+ * @description The delay in milli-seconds for scrolling the
1936
+ * Carousel during auto-play.
1937
+ * Note: The startAutoPlay() method needs to be invoked to trigger
1938
+ * automatic scrolling of Carousel.
1939
+ * @type Number
1940
+ */
1941
+ carousel.setAttributeConfig("autoPlayInterval", {
1942
+ validator : JS.isNumber,
1943
+ value : attrs.autoPlayInterval || 0
1944
+ });
1945
+
1946
+ /**
1947
+ * @attribute numPages
1948
+ * @description The number of pages in the carousel.
1949
+ * @type Number
1950
+ */
1951
+ carousel.setAttributeConfig("numPages", {
1952
+ readOnly : true,
1953
+ getter : carousel._getNumPages
1954
+ });
1955
+
1956
+ /**
1957
+ * @attribute lastVisible
1958
+ * @description The last item visible in the carousel.
1959
+ * @type Number
1960
+ */
1961
+ carousel.setAttributeConfig("lastVisible", {
1962
+ readOnly : true,
1963
+ getter : carousel._getLastVisible
1964
+ });
1965
+ },
1966
+
1967
+ /**
1968
+ * Initialize and bind the event handlers.
1969
+ *
1970
+ * @method initEvents
1971
+ * @public
1972
+ */
1973
+ initEvents: function () {
1974
+ var carousel = this,
1975
+ cssClass = carousel.CLASSES,
1976
+ focussedLi;
1977
+
1978
+ carousel.on("keydown", carousel._keyboardEventHandler);
1979
+
1980
+ carousel.on(afterScrollEvent, syncNavigation);
1981
+
1982
+ carousel.on(itemAddedEvent, syncUi);
1983
+
1984
+ carousel.on(itemRemovedEvent, syncUi);
1985
+
1986
+ carousel.on(itemReplacedEvent, syncUi);
1987
+
1988
+ carousel.on(itemSelectedEvent, function () {
1989
+ if (carousel._hasFocus) {
1990
+ carousel.focus();
1991
+ }
1992
+ });
1993
+
1994
+ carousel.on(loadItemsEvent, syncUi);
1995
+
1996
+ carousel.on(allItemsRemovedEvent, function (ev) {
1997
+ carousel.scrollTo(0);
1998
+ syncNavigation.call(carousel);
1999
+ syncPagerUi.call(carousel);
2000
+ });
2001
+
2002
+ carousel.on(pageChangeEvent, syncPagerUi, carousel);
2003
+
2004
+ carousel.on(renderEvent, function (ev) {
2005
+ if (carousel.get("selectedItem") === null ||
2006
+ carousel.get("selectedItem") <= 0) { //in either case
2007
+ carousel.set("selectedItem", carousel.get("firstVisible"));
2008
+ }
2009
+ syncNavigation.call(carousel, ev);
2010
+ syncPagerUi.call(carousel, ev);
2011
+ carousel._setClipContainerSize();
2012
+ carousel.show();
2013
+ });
2014
+
2015
+ carousel.on("selectedItemChange", function (ev) {
2016
+ setItemSelection.call(carousel, ev.newValue, ev.prevValue);
2017
+ if (ev.newValue >= 0) {
2018
+ carousel._updateTabIndex(
2019
+ carousel.getElementForItem(ev.newValue));
2020
+ }
2021
+ carousel.fireEvent(itemSelectedEvent, ev.newValue);
2022
+ });
2023
+
2024
+ carousel.on(uiUpdateEvent, function (ev) {
2025
+ syncNavigation.call(carousel, ev);
2026
+ syncPagerUi.call(carousel, ev);
2027
+ });
2028
+
2029
+ carousel.on("firstVisibleChange", function (ev) {
2030
+ if (!carousel.get("selectOnScroll")) {
2031
+ if (ev.newValue >= 0) {
2032
+ carousel._updateTabIndex(
2033
+ carousel.getElementForItem(ev.newValue));
2034
+ }
2035
+ }
2036
+ });
2037
+
2038
+ // Handle item selection on mouse click
2039
+ carousel.on("click", function (ev) {
2040
+ if (carousel.isAutoPlayOn()) {
2041
+ carousel.stopAutoPlay();
2042
+ }
2043
+ carousel._itemClickHandler(ev);
2044
+ carousel._pagerClickHandler(ev);
2045
+ });
2046
+
2047
+ // Restore the focus on the navigation buttons
2048
+
2049
+ Event.onFocus(carousel.get("element"), function (ev, obj) {
2050
+ var target = Event.getTarget(ev);
2051
+
2052
+ if (target && target.nodeName.toUpperCase() == "A" &&
2053
+ Dom.getAncestorByClassName(target, cssClass.NAVIGATION)) {
2054
+ if (focussedLi) {
2055
+ Dom.removeClass(focussedLi, cssClass.PAGE_FOCUS);
2056
+ }
2057
+ focussedLi = target.parentNode;
2058
+ Dom.addClass(focussedLi, cssClass.PAGE_FOCUS);
2059
+ } else {
2060
+ if (focussedLi) {
2061
+ Dom.removeClass(focussedLi, cssClass.PAGE_FOCUS);
2062
+ }
2063
+ }
2064
+
2065
+ obj._hasFocus = true;
2066
+ obj._updateNavButtons(Event.getTarget(ev), true);
2067
+ }, carousel);
2068
+
2069
+ Event.onBlur(carousel.get("element"), function (ev, obj) {
2070
+ obj._hasFocus = false;
2071
+ obj._updateNavButtons(Event.getTarget(ev), false);
2072
+ }, carousel);
2073
+ },
2074
+
2075
+ /**
2076
+ * Return true if the Carousel is still animating, or false otherwise.
2077
+ *
2078
+ * @method isAnimating
2079
+ * @return {Boolean} Return true if animation is still in progress, or
2080
+ * false otherwise.
2081
+ * @public
2082
+ */
2083
+ isAnimating: function () {
2084
+ return this._isAnimationInProgress;
2085
+ },
2086
+
2087
+ /**
2088
+ * Return true if the auto-scrolling of Carousel is "on", or false
2089
+ * otherwise.
2090
+ *
2091
+ * @method isAutoPlayOn
2092
+ * @return {Boolean} Return true if autoPlay is "on", or false
2093
+ * otherwise.
2094
+ * @public
2095
+ */
2096
+ isAutoPlayOn: function () {
2097
+ return this._isAutoPlayInProgress;
2098
+ },
2099
+
2100
+ /**
2101
+ * Return the carouselItemEl at index or null if the index is not
2102
+ * found.
2103
+ *
2104
+ * @method getElementForItem
2105
+ * @param index {Number} The index of the item to be returned
2106
+ * @return {Element} Return the item at index or null if not found
2107
+ * @public
2108
+ */
2109
+ getElementForItem: function (index) {
2110
+ var carousel = this;
2111
+
2112
+ if (index < 0 || index >= carousel.get("numItems")) {
2113
+ return null;
2114
+ }
2115
+
2116
+ if (carousel._itemsTable.items[index]) {
2117
+ return Dom.get(carousel._itemsTable.items[index].id);
2118
+ }
2119
+
2120
+ return null;
2121
+ },
2122
+
2123
+ /**
2124
+ * Return the carouselItemEl for all items in the Carousel.
2125
+ *
2126
+ * @method getElementForItems
2127
+ * @return {Array} Return all the items
2128
+ * @public
2129
+ */
2130
+ getElementForItems: function () {
2131
+ var carousel = this, els = [], i;
2132
+
2133
+ for (i = 0; i < carousel._itemsTable.numItems; i++) {
2134
+ els.push(carousel.getElementForItem(i));
2135
+ }
2136
+
2137
+ return els;
2138
+ },
2139
+
2140
+ /**
2141
+ * Return the item at index or null if the index is not found.
2142
+ *
2143
+ * @method getItem
2144
+ * @param index {Number} The index of the item to be returned
2145
+ * @return {Object} Return the item at index or null if not found
2146
+ * @public
2147
+ */
2148
+ getItem: function (index) {
2149
+ var carousel = this;
2150
+
2151
+ if (index < 0 || index >= carousel.get("numItems")) {
2152
+ return null;
2153
+ }
2154
+
2155
+ if (carousel._itemsTable.numItems > index) {
2156
+ if (!JS.isUndefined(carousel._itemsTable.items[index])) {
2157
+ return carousel._itemsTable.items[index];
2158
+ }
2159
+ }
2160
+
2161
+ return null;
2162
+ },
2163
+
2164
+ /**
2165
+ * Return all items as an array.
2166
+ *
2167
+ * @method getItems
2168
+ * @return {Array} Return all items in the Carousel
2169
+ * @public
2170
+ */
2171
+ getItems: function () {
2172
+ return this._itemsTable.items;
2173
+ },
2174
+
2175
+ /**
2176
+ * Return all loading items as an array.
2177
+ *
2178
+ * @method getLoadingItems
2179
+ * @return {Array} Return all items that are loading in the Carousel.
2180
+ * @public
2181
+ */
2182
+ getLoadingItems: function () {
2183
+ return this._itemsTable.loading;
2184
+ },
2185
+
2186
+ /**
2187
+ * For a multirow carousel, return the number of rows specified by user.
2188
+ *
2189
+ * @method getItems
2190
+ * @return {Number} Number of rows
2191
+ * @public
2192
+ */
2193
+ getRows: function () {
2194
+ return this._rows;
2195
+ },
2196
+
2197
+ /**
2198
+ * For a multirow carousel, return the number of cols specified by user.
2199
+ *
2200
+ * @method getItems
2201
+ * @return {Array} Return all items in the Carousel
2202
+ * @public
2203
+ */
2204
+ getCols: function () {
2205
+ return this._cols;
2206
+ },
2207
+
2208
+ /**
2209
+ * Return the position of the Carousel item that has the id "id", or -1
2210
+ * if the id is not found.
2211
+ *
2212
+ * @method getItemPositionById
2213
+ * @param index {Number} The index of the item to be returned
2214
+ * @public
2215
+ */
2216
+ getItemPositionById: function (id) {
2217
+ var carousel = this,
2218
+ n = carousel.get("numItems"),
2219
+ i = 0,
2220
+ items = carousel._itemsTable.items,
2221
+ item;
2222
+
2223
+ while (i < n) {
2224
+ item = items[i] || {};
2225
+ if(item.id == id) {
2226
+ return i;
2227
+ }
2228
+ i++;
2229
+ }
2230
+
2231
+ return -1;
2232
+ },
2233
+
2234
+ /**
2235
+ * Return all visible items as an array.
2236
+ *
2237
+ * @method getVisibleItems
2238
+ * @return {Array} The array of visible items
2239
+ * @public
2240
+ */
2241
+ getVisibleItems: function () {
2242
+ var carousel = this,
2243
+ i = carousel.get("firstVisible"),
2244
+ n = i + carousel.get("numVisible"),
2245
+ r = [];
2246
+
2247
+ while (i < n) {
2248
+ r.push(carousel.getElementForItem(i));
2249
+ i++;
2250
+ }
2251
+
2252
+ return r;
2253
+ },
2254
+
2255
+ /**
2256
+ * Remove an item at index from the Carousel.
2257
+ *
2258
+ * @method removeItem
2259
+ * @public
2260
+ * @param index {Number} The position to where in the list (starts from
2261
+ * zero).
2262
+ * @return {Boolean} Return true on success, false otherwise
2263
+ */
2264
+ removeItem: function (index) {
2265
+ var carousel = this,
2266
+ item,
2267
+ num = carousel.get("numItems");
2268
+
2269
+ if (index < 0 || index >= num) {
2270
+ return false;
2271
+ }
2272
+
2273
+ item = carousel._itemsTable.items.splice(index, 1);
2274
+ if (item && item.length == 1) {
2275
+ carousel._itemsTable.numItems--;
2276
+ carousel.set("numItems", num - 1);
2277
+
2278
+ carousel.fireEvent(itemRemovedEvent,
2279
+ { item: item[0], pos: index, ev: itemRemovedEvent });
2280
+ return true;
2281
+ }
2282
+
2283
+ return false;
2284
+ },
2285
+
2286
+ /**
2287
+ * Replace an item at index witin Carousel.
2288
+ *
2289
+ * @method replaceItem
2290
+ * @public
2291
+ * @param item {String | Object | HTMLElement} The item to be appended
2292
+ * to the Carousel. If the parameter is a string, it is assumed to be
2293
+ * the content of the newly created item. If the parameter is an
2294
+ * object, it is assumed to supply the content and an optional class
2295
+ * and an optional id of the newly created item.
2296
+ * @param index {Number} The position to where in the list (starts from
2297
+ * zero).
2298
+ * @return {Boolean} Return true on success, false otherwise
2299
+ */
2300
+ replaceItem: function (item, index) {
2301
+ var carousel = this,
2302
+ className,
2303
+ content,
2304
+ elId,
2305
+ numItems = carousel.get("numItems"),
2306
+ oel,
2307
+ el = item;
2308
+
2309
+ if (!item) {
2310
+ return false;
2311
+ }
2312
+
2313
+ if (JS.isString(item) || item.nodeName) {
2314
+ content = item.nodeName ? item.innerHTML : item;
2315
+ } else if (JS.isObject(item)) {
2316
+ content = item.content;
2317
+ } else {
2318
+ return false;
2319
+ }
2320
+
2321
+ if (JS.isUndefined(index)) {
2322
+ return false;
2323
+ } else {
2324
+ if (index < 0 || index >= numItems) {
2325
+ return false;
2326
+ }
2327
+
2328
+ oel = carousel._itemsTable.items[index];
2329
+ if(!oel){
2330
+ oel = carousel._itemsTable.loading[index];
2331
+ carousel._itemsTable.items[index] = undefined;
2332
+ }
2333
+
2334
+ carousel._itemsTable.items.splice(index, 1, {
2335
+ item : content,
2336
+ className : item.className || "",
2337
+ id : Dom.generateId()
2338
+ });
2339
+
2340
+ el = carousel._itemsTable.items[index];
2341
+ }
2342
+ carousel.fireEvent(itemReplacedEvent,
2343
+ { newItem: el, oldItem: oel, pos: index, ev: itemReplacedEvent });
2344
+
2345
+ return true;
2346
+ },
2347
+
2348
+ /**
2349
+ * Replace multiple items at specified indexes.
2350
+ * NOTE: item at index must already exist.
2351
+ *
2352
+ * @method replaceItems
2353
+ * @public
2354
+ * @param items {Array} An array containing an array of replacement items each linked to the
2355
+ * index where the substitution should take place.
2356
+ * E.g. [[{content:'<img/>'}, index1], [{content:'<img/>'}, index2]]
2357
+ * @return {Boolean} Return true on success, false otherwise
2358
+ */
2359
+ replaceItems: function (items) {
2360
+ var i, n, rv = true;
2361
+
2362
+ if (!JS.isArray(items)) {
2363
+ return false;
2364
+ }
2365
+
2366
+ for (i = 0, n = items.length; i < n; i++) {
2367
+ if (this.replaceItem(items[i][0], items[i][1]) === false) {
2368
+ rv = false;
2369
+ }
2370
+ }
2371
+
2372
+ return rv;
2373
+ },
2374
+
2375
+ /**
2376
+ * Render the Carousel.
2377
+ *
2378
+ * @method render
2379
+ * @public
2380
+ * @param appendTo {HTMLElement | String} The element to which the
2381
+ * Carousel should be appended prior to rendering.
2382
+ * @return {Boolean} Status of the operation
2383
+ */
2384
+ render: function (appendTo) {
2385
+ var carousel = this,
2386
+ cssClass = carousel.CLASSES,
2387
+ rows = carousel._rows;
2388
+
2389
+ carousel.addClass(cssClass.CAROUSEL);
2390
+
2391
+ if (!carousel._clipEl) {
2392
+ carousel._clipEl = carousel._createCarouselClip();
2393
+ carousel._clipEl.appendChild(carousel._carouselEl);
2394
+ }
2395
+
2396
+ if (appendTo) {
2397
+ carousel.appendChild(carousel._clipEl);
2398
+ carousel.appendTo(appendTo);
2399
+ } else {
2400
+ if (!Dom.inDocument(carousel.get("element"))) {
2401
+ return false;
2402
+ }
2403
+ carousel.appendChild(carousel._clipEl);
2404
+ }
2405
+
2406
+ if (rows) {
2407
+ Dom.addClass(carousel._clipEl, cssClass.MULTI_ROW);
2408
+ }
2409
+
2410
+ if (carousel.get("isVertical")) {
2411
+ carousel.addClass(cssClass.VERTICAL);
2412
+ } else {
2413
+ carousel.addClass(cssClass.HORIZONTAL);
2414
+ }
2415
+
2416
+ if (carousel.get("numItems") < 1) {
2417
+ return false;
2418
+ }
2419
+
2420
+ carousel._refreshUi();
2421
+
2422
+ return true;
2423
+ },
2424
+
2425
+ /**
2426
+ * Scroll the Carousel by an item backward.
2427
+ *
2428
+ * @method scrollBackward
2429
+ * @public
2430
+ */
2431
+ scrollBackward: function () {
2432
+ var carousel = this;
2433
+ carousel.scrollTo(carousel._firstItem -
2434
+ carousel.get("scrollIncrement"));
2435
+ },
2436
+
2437
+ /**
2438
+ * Scroll the Carousel by an item forward.
2439
+ *
2440
+ * @method scrollForward
2441
+ * @public
2442
+ */
2443
+ scrollForward: function () {
2444
+ var carousel = this;
2445
+ carousel.scrollTo(carousel._firstItem +
2446
+ carousel.get("scrollIncrement"));
2447
+ },
2448
+
2449
+ /**
2450
+ * Scroll the Carousel by a page backward.
2451
+ *
2452
+ * @method scrollPageBackward
2453
+ * @public
2454
+ */
2455
+ scrollPageBackward: function () {
2456
+ var carousel = this,
2457
+ isVertical = carousel.get("isVertical"),
2458
+ cols = carousel._cols,
2459
+ item = carousel._firstItem - carousel.get("numVisible");
2460
+
2461
+ if (item < 0) { // only account for multi-row when scrolling backwards from item 0
2462
+ if (cols) {
2463
+ item = carousel._firstItem - cols;
2464
+ }
2465
+ }
2466
+
2467
+ if (carousel.get("selectOnScroll")) {
2468
+ carousel._selectedItem = carousel._getSelectedItem(item);
2469
+ }
2470
+
2471
+ carousel.scrollTo(item);
2472
+ },
2473
+
2474
+ /**
2475
+ * Scroll the Carousel by a page forward.
2476
+ *
2477
+ * @method scrollPageForward
2478
+ * @public
2479
+ */
2480
+ scrollPageForward: function () {
2481
+ var carousel = this,
2482
+ item = carousel._firstItem + carousel.get("numVisible");
2483
+
2484
+ if (item > carousel.get("numItems")) {
2485
+ item = 0;
2486
+ }
2487
+
2488
+ if (carousel.get("selectOnScroll")) {
2489
+ carousel._selectedItem = carousel._getSelectedItem(item);
2490
+ }
2491
+
2492
+ carousel.scrollTo(item);
2493
+ },
2494
+
2495
+ /**
2496
+ * Scroll the Carousel to make the item the first visible item.
2497
+ *
2498
+ * @method scrollTo
2499
+ * @public
2500
+ * @param item Number The index of the element to position at.
2501
+ * @param dontSelect Boolean True if select should be avoided
2502
+ */
2503
+ scrollTo: function (item, dontSelect) {
2504
+ var carousel = this, animate, animCfg, isCircular, isVertical,
2505
+ rows, delta, direction, firstItem, lastItem, itemsPerRow,
2506
+ itemsPerCol, numItems, numPerPage, offset, page, rv, sentinel,
2507
+ index, stopAutoScroll,
2508
+ itemsTable = carousel._itemsTable,
2509
+ items = itemsTable.items,
2510
+ loading = itemsTable.loading;
2511
+
2512
+ if (JS.isUndefined(item) || item == carousel._firstItem ||
2513
+ carousel.isAnimating()) {
2514
+ return; // nothing to do!
2515
+ }
2516
+
2517
+ animCfg = carousel.get("animation");
2518
+ isCircular = carousel.get("isCircular");
2519
+ isVertical = carousel.get("isVertical");
2520
+ itemsPerRow = carousel._cols;
2521
+ itemsPerCol = carousel._rows;
2522
+ firstItem = carousel._firstItem;
2523
+ numItems = carousel.get("numItems");
2524
+ numPerPage = carousel.get("numVisible");
2525
+ page = carousel.get("currentPage");
2526
+
2527
+ stopAutoScroll = function () {
2528
+ if (carousel.isAutoPlayOn()) {
2529
+ carousel.stopAutoPlay();
2530
+ }
2531
+ };
2532
+
2533
+ if (item < 0) {
2534
+ if (isCircular) {
2535
+ item = numItems + item;
2536
+ } else {
2537
+ stopAutoScroll.call(carousel);
2538
+ return;
2539
+ }
2540
+ } else if (numItems > 0 && item > numItems - 1) {
2541
+
2542
+ if (carousel.get("isCircular")) {
2543
+ item = numItems - item;
2544
+ } else {
2545
+ stopAutoScroll.call(carousel);
2546
+ return;
2547
+ }
2548
+ }
2549
+
2550
+ if (isNaN(item)) {
2551
+ return;
2552
+ }
2553
+
2554
+ direction = (carousel._firstItem > item) ? "backward" : "forward";
2555
+
2556
+ sentinel = firstItem + numPerPage;
2557
+ sentinel = (sentinel > numItems - 1) ? numItems - 1 : sentinel;
2558
+ rv = carousel.fireEvent(beforeScrollEvent,
2559
+ { dir: direction, first: firstItem, last: sentinel });
2560
+ if (rv === false) { // scrolling is prevented
2561
+ return;
2562
+ }
2563
+
2564
+ carousel.fireEvent(beforePageChangeEvent, { page: page });
2565
+
2566
+ // call loaditems to check if we have all the items to display
2567
+ lastItem = item + numPerPage - 1;
2568
+ carousel._loadItems(lastItem > numItems-1 ? numItems-1 : lastItem);
2569
+
2570
+ // Calculate the delta relative to the first item, the delta is
2571
+ // always negative.
2572
+ delta = 0 - item;
2573
+
2574
+ if (itemsPerCol) {
2575
+ // offset calculations for multirow Carousel
2576
+ if (isVertical) {
2577
+ delta = parseInt(delta / itemsPerRow, 10);
2578
+ } else {
2579
+ delta = parseInt(delta / itemsPerCol, 10);
2580
+ }
2581
+ }
2582
+
2583
+ // adjust for items not yet loaded
2584
+ index = 0;
2585
+ while (delta < 0 && index < item+numPerPage-1 && index < numItems) {
2586
+ if (!items[index] && !loading[index]) {
2587
+ delta++;
2588
+ }
2589
+ index += itemsPerCol ? itemsPerCol : 1;
2590
+ }
2591
+
2592
+ carousel._firstItem = item;
2593
+ carousel.set("firstVisible", item);
2594
+
2595
+
2596
+ sentinel = item + numPerPage;
2597
+ sentinel = (sentinel > numItems - 1) ? numItems - 1 : sentinel;
2598
+
2599
+ offset = getScrollOffset.call(carousel, delta);
2600
+
2601
+ animate = animCfg.speed > 0;
2602
+
2603
+ if (animate) {
2604
+ carousel._animateAndSetCarouselOffset(offset, item, sentinel,
2605
+ dontSelect);
2606
+ } else {
2607
+ carousel._setCarouselOffset(offset);
2608
+ updateStateAfterScroll.call(carousel, item, sentinel);
2609
+ }
2610
+ },
2611
+
2612
+ /**
2613
+ * Get the page an item is on within carousel.
2614
+ *
2615
+ * @method getPageForItem
2616
+ * @public
2617
+ * @param index {Number} Index of item
2618
+ * @return {Number} Page item is on
2619
+ */
2620
+ getPageForItem : function(item) {
2621
+ return Math.ceil(
2622
+ (item+1) / parseInt(this.get("numVisible"),10)
2623
+ );
2624
+ },
2625
+
2626
+ /**
2627
+ * Get the first visible item's index on any given page.
2628
+ *
2629
+ * @method getFirstVisibleOnpage
2630
+ * @public
2631
+ * @param page {Number} Page
2632
+ * @return {Number} First item's index
2633
+ */
2634
+ getFirstVisibleOnPage : function(page) {
2635
+ return (page - 1) * this.get("numVisible");
2636
+ },
2637
+
2638
+ /**
2639
+ * Select the previous item in the Carousel.
2640
+ *
2641
+ * @method selectPreviousItem
2642
+ * @public
2643
+ */
2644
+ selectPreviousItem: function () {
2645
+ var carousel = this,
2646
+ newpos = 0,
2647
+ selected = carousel.get("selectedItem");
2648
+
2649
+ if (selected == this._firstItem) {
2650
+ newpos = selected - carousel.get("numVisible");
2651
+ carousel._selectedItem = carousel._getSelectedItem(selected-1);
2652
+ carousel.scrollTo(newpos);
2653
+ } else {
2654
+ newpos = carousel.get("selectedItem") -
2655
+ carousel.get("scrollIncrement");
2656
+ carousel.set("selectedItem",carousel._getSelectedItem(newpos));
2657
+ }
2658
+ },
2659
+
2660
+ /**
2661
+ * Select the next item in the Carousel.
2662
+ *
2663
+ * @method selectNextItem
2664
+ * @public
2665
+ */
2666
+ selectNextItem: function () {
2667
+ var carousel = this, newpos = 0;
2668
+
2669
+ newpos = carousel.get("selectedItem") +
2670
+ carousel.get("scrollIncrement");
2671
+ carousel.set("selectedItem", carousel._getSelectedItem(newpos));
2672
+ },
2673
+
2674
+ /**
2675
+ * Display the Carousel.
2676
+ *
2677
+ * @method show
2678
+ * @public
2679
+ */
2680
+ show: function () {
2681
+ var carousel = this,
2682
+ cssClass = carousel.CLASSES;
2683
+
2684
+ if (carousel.fireEvent(beforeShowEvent) !== false) {
2685
+ carousel.addClass(cssClass.VISIBLE);
2686
+ carousel.fireEvent(showEvent);
2687
+ }
2688
+ },
2689
+
2690
+ /**
2691
+ * Start auto-playing the Carousel.
2692
+ *
2693
+ * @method startAutoPlay
2694
+ * @public
2695
+ */
2696
+ startAutoPlay: function () {
2697
+ var carousel = this, timer;
2698
+
2699
+ if (JS.isUndefined(carousel._autoPlayTimer)) {
2700
+ timer = carousel.get("autoPlayInterval");
2701
+ if (timer <= 0) {
2702
+ return;
2703
+ }
2704
+ carousel._isAutoPlayInProgress = true;
2705
+ carousel.fireEvent(startAutoPlayEvent);
2706
+ carousel._autoPlayTimer = setTimeout(function () {
2707
+ carousel._autoScroll();
2708
+ }, timer);
2709
+ }
2710
+ },
2711
+
2712
+ /**
2713
+ * Stop auto-playing the Carousel.
2714
+ *
2715
+ * @method stopAutoPlay
2716
+ * @public
2717
+ */
2718
+ stopAutoPlay: function () {
2719
+ var carousel = this;
2720
+
2721
+ if (!JS.isUndefined(carousel._autoPlayTimer)) {
2722
+ clearTimeout(carousel._autoPlayTimer);
2723
+ delete carousel._autoPlayTimer;
2724
+ carousel._isAutoPlayInProgress = false;
2725
+ carousel.fireEvent(stopAutoPlayEvent);
2726
+ }
2727
+ },
2728
+
2729
+ /**
2730
+ * Update interface's pagination data within a registered template.
2731
+ *
2732
+ * @method updatePagination
2733
+ * @public
2734
+ */
2735
+ updatePagination: function () {
2736
+ var carousel = this,
2737
+ pagination = carousel._pagination;
2738
+ if(!pagination.el){ return false; }
2739
+
2740
+ var numItems = carousel.get('numItems'),
2741
+ numVisible = carousel.get('numVisible'),
2742
+ firstVisible = carousel.get('firstVisible')+1,
2743
+ currentPage = carousel.get('currentPage')+1,
2744
+ numPages = carousel.get('numPages'),
2745
+ replacements = {
2746
+ 'numVisible' : numVisible,
2747
+ 'numPages' : numPages,
2748
+ 'numItems' : numItems,
2749
+ 'selectedItem' : carousel.get('selectedItem')+1,
2750
+ 'currentPage' : currentPage,
2751
+ 'firstVisible' : firstVisible,
2752
+ 'lastVisible' : carousel.get("lastVisible")+1
2753
+ },
2754
+ cb = pagination.callback || {},
2755
+ scope = cb.scope && cb.obj ? cb.obj : carousel;
2756
+
2757
+ pagination.el.innerHTML = JS.isFunction(cb.fn) ? cb.fn.apply(scope, [pagination.template, replacements]) : YAHOO.lang.substitute(pagination.template, replacements);
2758
+ },
2759
+
2760
+ /**
2761
+ * Register carousels pagination template, append to interface, and populate.
2762
+ *
2763
+ * @method registerPagination
2764
+ * @param template {String} Pagination template as passed to lang.substitute
2765
+ * @public
2766
+ */
2767
+ registerPagination: function (tpl, pos, cb) {
2768
+ var carousel = this;
2769
+
2770
+ carousel._pagination.template = tpl;
2771
+ carousel._pagination.callback = cb || {};
2772
+
2773
+ if(!carousel._pagination.el){
2774
+ carousel._pagination.el = createElement('DIV', {className:carousel.CLASSES.PAGINATION});
2775
+
2776
+ if(pos == "before"){
2777
+ carousel._navEl.insertBefore(carousel._pagination.el, carousel._navEl.firstChild);
2778
+ } else {
2779
+ carousel._navEl.appendChild(carousel._pagination.el);
2780
+ }
2781
+
2782
+ carousel.on('itemSelected', carousel.updatePagination);
2783
+ carousel.on('pageChange', carousel.updatePagination);
2784
+ }
2785
+
2786
+ carousel.updatePagination();
2787
+ },
2788
+
2789
+ /**
2790
+ * Return the string representation of the Carousel.
2791
+ *
2792
+ * @method toString
2793
+ * @public
2794
+ * @return {String}
2795
+ */
2796
+ toString: function () {
2797
+ return WidgetName + (this.get ? " (#" + this.get("id") + ")" : "");
2798
+ },
2799
+
2800
+ /*
2801
+ * Protected methods of the Carousel component
2802
+ */
2803
+
2804
+ /**
2805
+ * Set the Carousel offset to the passed offset after animating.
2806
+ *
2807
+ * @method _animateAndSetCarouselOffset
2808
+ * @param {Integer} offset The offset to which the Carousel has to be
2809
+ * scrolled to.
2810
+ * @param {Integer} item The index to which the Carousel will scroll.
2811
+ * @param {Integer} sentinel The last element in the view port.
2812
+ * @protected
2813
+ */
2814
+ _animateAndSetCarouselOffset: function (offset, item, sentinel) {
2815
+ var carousel = this,
2816
+ animCfg = carousel.get("animation"),
2817
+ animObj = null;
2818
+
2819
+ if (carousel.get("isVertical")) {
2820
+ animObj = new YAHOO.util.Motion(carousel._carouselEl,
2821
+ { top: { to: offset } },
2822
+ animCfg.speed, animCfg.effect);
2823
+ } else {
2824
+ animObj = new YAHOO.util.Motion(carousel._carouselEl,
2825
+ { left: { to: offset } },
2826
+ animCfg.speed, animCfg.effect);
2827
+ }
2828
+
2829
+ carousel._isAnimationInProgress = true;
2830
+ animObj.onComplete.subscribe(carousel._animationCompleteHandler,
2831
+ { scope: carousel, item: item,
2832
+ last: sentinel });
2833
+ animObj.animate();
2834
+ },
2835
+
2836
+ /**
2837
+ * Handle the animation complete event.
2838
+ *
2839
+ * @method _animationCompleteHandler
2840
+ * @param {Event} ev The event.
2841
+ * @param {Array} p The event parameters.
2842
+ * @param {Object} o The object that has the state of the Carousel
2843
+ * @protected
2844
+ */
2845
+ _animationCompleteHandler: function (ev, p, o) {
2846
+ o.scope._isAnimationInProgress = false;
2847
+ updateStateAfterScroll.call(o.scope, o.item, o.last);
2848
+ },
2849
+
2850
+ /**
2851
+ * Automatically scroll the contents of the Carousel.
2852
+ * @method _autoScroll
2853
+ * @protected
2854
+ */
2855
+ _autoScroll: function() {
2856
+ var carousel = this,
2857
+ currIndex = carousel._firstItem,
2858
+ index;
2859
+
2860
+ if (currIndex >= carousel.get("numItems") - 1) {
2861
+ if (carousel.get("isCircular")) {
2862
+ index = 0;
2863
+ } else {
2864
+ carousel.stopAutoPlay();
2865
+ }
2866
+ } else {
2867
+ index = currIndex + carousel.get("numVisible");
2868
+ }
2869
+
2870
+ carousel._selectedItem = carousel._getSelectedItem(index);
2871
+ carousel.scrollTo.call(carousel, index);
2872
+ },
2873
+
2874
+ /**
2875
+ * Create the Carousel.
2876
+ *
2877
+ * @method createCarousel
2878
+ * @param elId {String} The id of the element to be created
2879
+ * @protected
2880
+ */
2881
+ _createCarousel: function (elId) {
2882
+ var carousel = this,
2883
+ cssClass = carousel.CLASSES,
2884
+ el = Dom.get(elId);
2885
+
2886
+ if (!el) {
2887
+ el = createElement("DIV", {
2888
+ className : cssClass.CAROUSEL,
2889
+ id : elId
2890
+ });
2891
+ }
2892
+
2893
+ if (!carousel._carouselEl) {
2894
+ carousel._carouselEl=createElement(carousel.get("carouselEl"),
2895
+ { className: cssClass.CAROUSEL_EL });
2896
+ }
2897
+
2898
+ return el;
2899
+ },
2900
+
2901
+ /**
2902
+ * Create the Carousel clip container.
2903
+ *
2904
+ * @method createCarouselClip
2905
+ * @protected
2906
+ */
2907
+ _createCarouselClip: function () {
2908
+ return createElement("DIV", { className: this.CLASSES.CONTENT });
2909
+ },
2910
+
2911
+ /**
2912
+ * Create the Carousel item.
2913
+ *
2914
+ * @method createCarouselItem
2915
+ * @param obj {Object} The attributes of the element to be created
2916
+ * @protected
2917
+ */
2918
+ _createCarouselItem: function (obj) {
2919
+ var attr, carousel = this,
2920
+ styles = getCarouselItemPosition.call(carousel, obj.pos);
2921
+
2922
+ return createElement(carousel.get("carouselItemEl"), {
2923
+ className : obj.className,
2924
+ styles : obj.styles,
2925
+ content : obj.content,
2926
+ id : obj.id
2927
+ });
2928
+ },
2929
+
2930
+ /**
2931
+ * Return a valid item for a possibly out of bounds index considering
2932
+ * the isCircular property.
2933
+ *
2934
+ * @method _getValidIndex
2935
+ * @param index {Number} The index of the item to be returned
2936
+ * @return {Object} Return a valid item index
2937
+ * @protected
2938
+ */
2939
+ _getValidIndex: function (index) {
2940
+ var carousel = this,
2941
+ isCircular = carousel.get("isCircular"),
2942
+ numItems = carousel.get("numItems"),
2943
+ numVisible = carousel.get("numVisible"),
2944
+ sentinel = numItems - 1;
2945
+
2946
+ if (index < 0) {
2947
+ index = isCircular ?
2948
+ Math.ceil(numItems/numVisible)*numVisible + index : 0;
2949
+ } else if (index > sentinel) {
2950
+ index = isCircular ? 0 : sentinel;
2951
+ }
2952
+
2953
+ return index;
2954
+ },
2955
+
2956
+ /**
2957
+ * Get the value for the selected item.
2958
+ *
2959
+ * @method _getSelectedItem
2960
+ * @param val {Number} The new value for "selected" item
2961
+ * @return {Number} The new value that would be set
2962
+ * @protected
2963
+ */
2964
+ _getSelectedItem: function (val) {
2965
+ var carousel = this,
2966
+ isCircular = carousel.get("isCircular"),
2967
+ numItems = carousel.get("numItems"),
2968
+ sentinel = numItems - 1;
2969
+
2970
+ if (val < 0) {
2971
+ if (isCircular) {
2972
+ val = numItems + val;
2973
+ } else {
2974
+ val = carousel.get("selectedItem");
2975
+ }
2976
+ } else if (val > sentinel) {
2977
+ if (isCircular) {
2978
+ val = val - numItems;
2979
+ } else {
2980
+ val = carousel.get("selectedItem");
2981
+ }
2982
+ }
2983
+ return val;
2984
+ },
2985
+
2986
+ /**
2987
+ * The "click" handler for the item.
2988
+ *
2989
+ * @method _itemClickHandler
2990
+ * @param {Event} ev The event object
2991
+ * @protected
2992
+ */
2993
+ _itemClickHandler: function (ev) {
2994
+ var carousel = this,
2995
+ carouselItem = carousel.get("carouselItemEl"),
2996
+ container = carousel.get("element"),
2997
+ el,
2998
+ item,
2999
+ target = Event.getTarget(ev),
3000
+ tag = target.tagName.toUpperCase();
3001
+
3002
+ if(tag === "INPUT" ||
3003
+ tag === "SELECT" ||
3004
+ tag === "TEXTAREA") {
3005
+ return;
3006
+ }
3007
+
3008
+ while (target && target != container &&
3009
+ target.id != carousel._carouselEl) {
3010
+ el = target.nodeName;
3011
+ if (el.toUpperCase() == carouselItem) {
3012
+ break;
3013
+ }
3014
+ target = target.parentNode;
3015
+ }
3016
+
3017
+ if ((item = carousel.getItemPositionById(target.id)) >= 0) {
3018
+ carousel.set("selectedItem", carousel._getSelectedItem(item));
3019
+ carousel.focus();
3020
+ }
3021
+ },
3022
+
3023
+ /**
3024
+ * The keyboard event handler for Carousel.
3025
+ *
3026
+ * @method _keyboardEventHandler
3027
+ * @param ev {Event} The event that is being handled.
3028
+ * @protected
3029
+ */
3030
+ _keyboardEventHandler: function (ev) {
3031
+ var carousel = this,
3032
+ key = Event.getCharCode(ev),
3033
+ target = Event.getTarget(ev),
3034
+ prevent = false;
3035
+
3036
+ // do not mess while animation is in progress or naving via select
3037
+ if (carousel.isAnimating() || target.tagName.toUpperCase() === "SELECT") {
3038
+ return;
3039
+ }
3040
+
3041
+ switch (key) {
3042
+ case 0x25: // left arrow
3043
+ case 0x26: // up arrow
3044
+ carousel.selectPreviousItem();
3045
+ prevent = true;
3046
+ break;
3047
+ case 0x27: // right arrow
3048
+ case 0x28: // down arrow
3049
+ carousel.selectNextItem();
3050
+ prevent = true;
3051
+ break;
3052
+ case 0x21: // page-up
3053
+ carousel.scrollPageBackward();
3054
+ prevent = true;
3055
+ break;
3056
+ case 0x22: // page-down
3057
+ carousel.scrollPageForward();
3058
+ prevent = true;
3059
+ break;
3060
+ }
3061
+
3062
+ if (prevent) {
3063
+ if (carousel.isAutoPlayOn()) {
3064
+ carousel.stopAutoPlay();
3065
+ }
3066
+ Event.preventDefault(ev);
3067
+ }
3068
+ },
3069
+
3070
+ /**
3071
+ * The load the required set of items that are needed for display.
3072
+ *
3073
+ * @method _loadItems
3074
+ * @protected
3075
+ */
3076
+ _loadItems: function(last) {
3077
+ var carousel = this,
3078
+ numItems = carousel.get("numItems"),
3079
+ numVisible = carousel.get("numVisible"),
3080
+ reveal = carousel.get("revealAmount"),
3081
+ first = carousel._itemsTable.items.length,
3082
+ lastVisible = carousel.get("lastVisible");
3083
+
3084
+ // adjust if going backwards
3085
+ if(first > last && last+1 >= numVisible){
3086
+ // need to get first a bit differently for the last page
3087
+ first = last % numVisible || last == lastVisible ? last - last % numVisible : last - numVisible + 1;
3088
+ }
3089
+
3090
+ if(reveal && last < numItems - 1){ last++; }
3091
+
3092
+ if (last >= first && (!carousel.getItem(first) || !carousel.getItem(last))) {
3093
+ carousel.fireEvent(loadItemsEvent, {
3094
+ ev: loadItemsEvent, first: first, last: last,
3095
+ num: last - first + 1
3096
+ });
3097
+ }
3098
+
3099
+ },
3100
+
3101
+ /**
3102
+ * The "onchange" handler for select box pagination.
3103
+ *
3104
+ * @method _pagerChangeHandler
3105
+ * @param {Event} ev The event object
3106
+ * @protected
3107
+ */
3108
+ _pagerChangeHandler: function (ev) {
3109
+ var carousel = this,
3110
+ target = Event.getTarget(ev),
3111
+ page = target.value,
3112
+ item;
3113
+
3114
+ if (page) {
3115
+ item = carousel.getFirstVisibleOnPage(page);
3116
+ carousel._selectedItem = item;
3117
+ carousel.scrollTo(item);
3118
+ carousel.focus();
3119
+ }
3120
+ },
3121
+ /**
3122
+ * The "click" handler for anchor pagination.
3123
+ *
3124
+ * @method _pagerClickHandler
3125
+ * @param {Event} ev The event object
3126
+ * @protected
3127
+ */
3128
+ _pagerClickHandler: function (ev) {
3129
+ var carousel = this,
3130
+ css = carousel.CLASSES,
3131
+ target = Event.getTarget(ev),
3132
+ elNode = target.nodeName.toUpperCase(),
3133
+ val,
3134
+ stringIndex,
3135
+ page,
3136
+ item;
3137
+
3138
+ if (Dom.hasClass(target, css.PAGER_ITEM) || Dom.hasClass(target.parentNode, css.PAGER_ITEM)) {
3139
+ if (elNode == "EM") {
3140
+ target = target.parentNode;// item is an em and not an anchor (when text is visible)
3141
+ }
3142
+ val = target.href;
3143
+ stringIndex = val.lastIndexOf("#");
3144
+ page = parseInt(val.substring(stringIndex+1), 10);
3145
+ if (page != -1) {
3146
+ item = carousel.getFirstVisibleOnPage(page);
3147
+ carousel._selectedItem = item;
3148
+ carousel.scrollTo(item);
3149
+ carousel.focus();
3150
+ }
3151
+ Event.preventDefault(ev);
3152
+ }
3153
+ },
3154
+
3155
+ /**
3156
+ * Find the Carousel within a container. The Carousel is identified by
3157
+ * the first element that matches the carousel element tag or the
3158
+ * element that has the Carousel class.
3159
+ *
3160
+ * @method parseCarousel
3161
+ * @param parent {HTMLElement} The parent element to look under
3162
+ * @return {Boolean} True if Carousel is found, false otherwise
3163
+ * @protected
3164
+ */
3165
+ _parseCarousel: function (parent) {
3166
+ var carousel = this, child, cssClass, domEl, found, node;
3167
+
3168
+ cssClass = carousel.CLASSES;
3169
+ domEl = carousel.get("carouselEl");
3170
+ found = false;
3171
+
3172
+ for (child = parent.firstChild; child; child = child.nextSibling) {
3173
+ if (child.nodeType == 1) {
3174
+ node = child.nodeName;
3175
+ if (node.toUpperCase() == domEl) {
3176
+ carousel._carouselEl = child;
3177
+ Dom.addClass(carousel._carouselEl,
3178
+ carousel.CLASSES.CAROUSEL_EL);
3179
+ found = true;
3180
+ }
3181
+ }
3182
+ }
3183
+
3184
+ return found;
3185
+ },
3186
+
3187
+ /**
3188
+ * Find the items within the Carousel and add them to the items table.
3189
+ * A Carousel item is identified by elements that matches the carousel
3190
+ * item element tag.
3191
+ *
3192
+ * @method parseCarouselItems
3193
+ * @protected
3194
+ */
3195
+ _parseCarouselItems: function () {
3196
+ var carousel = this,
3197
+ cssClass = carousel.CLASSES,
3198
+ i=0,
3199
+ rows,
3200
+ child,
3201
+ domItemEl,
3202
+ elId,
3203
+ node,
3204
+ index = carousel.get("firstVisible"),
3205
+ parent = carousel._carouselEl;
3206
+
3207
+ rows = carousel._rows;
3208
+ domItemEl = carousel.get("carouselItemEl");
3209
+
3210
+ for (child = parent.firstChild; child; child = child.nextSibling) {
3211
+ if (child.nodeType == 1) {
3212
+ node = child.nodeName;
3213
+ if (node.toUpperCase() == domItemEl) {
3214
+ if (child.id) {
3215
+ elId = child.id;
3216
+ } else {
3217
+ elId = Dom.generateId();
3218
+ child.setAttribute("id", elId);
3219
+ }
3220
+ carousel.addItem(child,index);
3221
+ index++;
3222
+ }
3223
+ }
3224
+ }
3225
+ },
3226
+
3227
+ /**
3228
+ * Find the Carousel navigation within a container. The navigation
3229
+ * elements need to match the carousel navigation class names.
3230
+ *
3231
+ * @method parseCarouselNavigation
3232
+ * @param parent {HTMLElement} The parent element to look under
3233
+ * @return {Boolean} True if at least one is found, false otherwise
3234
+ * @protected
3235
+ */
3236
+ _parseCarouselNavigation: function (parent) {
3237
+ var carousel = this,
3238
+ cfg,
3239
+ cssClass = carousel.CLASSES,
3240
+ el,
3241
+ i,
3242
+ j,
3243
+ nav,
3244
+ rv = false;
3245
+
3246
+ nav = Dom.getElementsByClassName(cssClass.PREV_PAGE, "*", parent);
3247
+ if (nav.length > 0) {
3248
+ for (i in nav) {
3249
+ if (nav.hasOwnProperty(i)) {
3250
+ el = nav[i];
3251
+ if (el.nodeName == "INPUT" ||
3252
+ el.nodeName == "BUTTON" ||
3253
+ el.nodeName == "A") {// Anchor support in Nav (for SEO)
3254
+ carousel._navBtns.prev.push(el);
3255
+ } else {
3256
+ j = el.getElementsByTagName("INPUT");
3257
+ if (JS.isArray(j) && j.length > 0) {
3258
+ carousel._navBtns.prev.push(j[0]);
3259
+ } else {
3260
+ j = el.getElementsByTagName("BUTTON");
3261
+ if (JS.isArray(j) && j.length > 0) {
3262
+ carousel._navBtns.prev.push(j[0]);
3263
+ }
3264
+ }
3265
+ }
3266
+ }
3267
+ }
3268
+ cfg = { prev: nav };
3269
+ }
3270
+
3271
+ nav = Dom.getElementsByClassName(cssClass.NEXT_PAGE, "*", parent);
3272
+ if (nav.length > 0) {
3273
+ for (i in nav) {
3274
+ if (nav.hasOwnProperty(i)) {
3275
+ el = nav[i];
3276
+ if (el.nodeName == "INPUT" ||
3277
+ el.nodeName == "BUTTON" ||
3278
+ el.nodeName == "A") {// Anchor support in Nav (for SEO)
3279
+ carousel._navBtns.next.push(el);
3280
+ } else {
3281
+ j = el.getElementsByTagName("INPUT");
3282
+ if (JS.isArray(j) && j.length > 0) {
3283
+ carousel._navBtns.next.push(j[0]);
3284
+ } else {
3285
+ j = el.getElementsByTagName("BUTTON");
3286
+ if (JS.isArray(j) && j.length > 0) {
3287
+ carousel._navBtns.next.push(j[0]);
3288
+ }
3289
+ }
3290
+ }
3291
+ }
3292
+ }
3293
+ if (cfg) {
3294
+ cfg.next = nav;
3295
+ } else {
3296
+ cfg = { next: nav };
3297
+ }
3298
+ }
3299
+
3300
+ if (cfg) {
3301
+ carousel.set("navigation", cfg);
3302
+ rv = true;
3303
+ }
3304
+
3305
+ return rv;
3306
+ },
3307
+
3308
+ /**
3309
+ * Refresh the widget UI if it is not already rendered, on first item
3310
+ * addition.
3311
+ *
3312
+ * @method _refreshUi
3313
+ * @protected
3314
+ */
3315
+ _refreshUi: function () {
3316
+ var carousel = this, i, isVertical = carousel.get("isVertical"), firstVisible = carousel.get("firstVisible"), item, n, rsz, sz;
3317
+
3318
+ if (carousel._itemsTable.numItems < 1) {
3319
+ return;
3320
+ }
3321
+
3322
+ sz = getCarouselItemSize.call(carousel,
3323
+ isVertical ? "height" : "width");
3324
+ // This fixes the widget to auto-adjust height/width for absolute
3325
+ // positioned children.
3326
+ item = carousel._itemsTable.items[firstVisible].id;
3327
+
3328
+ sz = isVertical ? getStyle(item, "width") :
3329
+ getStyle(item, "height");
3330
+
3331
+ Dom.setStyle(carousel._carouselEl,
3332
+ isVertical ? "width" : "height", sz + "px");
3333
+
3334
+ // Set the rendered state appropriately.
3335
+ carousel._hasRendered = true;
3336
+ carousel.fireEvent(renderEvent);
3337
+ },
3338
+
3339
+ /**
3340
+ * Set the Carousel offset to the passed offset.
3341
+ *
3342
+ * @method _setCarouselOffset
3343
+ * @protected
3344
+ */
3345
+ _setCarouselOffset: function (offset) {
3346
+ var carousel = this, which;
3347
+
3348
+ which = carousel.get("isVertical") ? "top" : "left";
3349
+ Dom.setStyle(carousel._carouselEl, which, offset + "px");
3350
+ },
3351
+
3352
+ /**
3353
+ * Setup/Create the Carousel navigation element (if needed).
3354
+ *
3355
+ * @method _setupCarouselNavigation
3356
+ * @protected
3357
+ */
3358
+ _setupCarouselNavigation: function () {
3359
+ var carousel = this,
3360
+ btn, cfg, cssClass, nav, navContainer, nextButton, prevButton;
3361
+
3362
+ cssClass = carousel.CLASSES;
3363
+
3364
+ // TODO: can the _navBtns be tested against instead?
3365
+ navContainer = Dom.getElementsByClassName(cssClass.NAVIGATION,
3366
+ "DIV", carousel.get("element"));
3367
+
3368
+ if (navContainer.length === 0) {
3369
+ navContainer = createElement("DIV",
3370
+ { className: cssClass.NAVIGATION });
3371
+ carousel.insertBefore(navContainer,
3372
+ Dom.getFirstChild(carousel.get("element")));
3373
+ } else {
3374
+ navContainer = navContainer[0];
3375
+ }
3376
+
3377
+ carousel._pages.el = createElement("UL");
3378
+ navContainer.appendChild(carousel._pages.el);
3379
+
3380
+ nav = carousel.get("navigation");
3381
+ if (JS.isString(nav.prev) || JS.isArray(nav.prev)) {
3382
+ if (JS.isString(nav.prev)) {
3383
+ nav.prev = [nav.prev];
3384
+ }
3385
+ for (btn in nav.prev) {
3386
+ if (nav.prev.hasOwnProperty(btn)) {
3387
+ carousel._navBtns.prev.push(Dom.get(nav.prev[btn]));
3388
+ }
3389
+ }
3390
+ } else {
3391
+ // TODO: separate method for creating a navigation button
3392
+ prevButton = createElement("SPAN",
3393
+ { className: cssClass.BUTTON + cssClass.FIRST_NAV });
3394
+ // XXX: for IE 6.x
3395
+ Dom.setStyle(prevButton, "visibility", "visible");
3396
+ btn = Dom.generateId();
3397
+ prevButton.innerHTML = "<button type=\"button\" " +
3398
+ "id=\"" + btn + "\" name=\"" +
3399
+ carousel.STRINGS.PREVIOUS_BUTTON_TEXT + "\">" +
3400
+ carousel.STRINGS.PREVIOUS_BUTTON_TEXT + "</button>";
3401
+ navContainer.appendChild(prevButton);
3402
+ btn = Dom.get(btn);
3403
+ carousel._navBtns.prev = [btn];
3404
+ cfg = { prev: [prevButton] };
3405
+ }
3406
+
3407
+ if (JS.isString(nav.next) || JS.isArray(nav.next)) {
3408
+ if (JS.isString(nav.next)) {
3409
+ nav.next = [nav.next];
3410
+ }
3411
+ for (btn in nav.next) {
3412
+ if (nav.next.hasOwnProperty(btn)) {
3413
+ carousel._navBtns.next.push(Dom.get(nav.next[btn]));
3414
+ }
3415
+ }
3416
+ } else {
3417
+ // TODO: separate method for creating a navigation button
3418
+ nextButton = createElement("SPAN",
3419
+ { className: cssClass.BUTTON + cssClass.NEXT_NAV });
3420
+ // XXX: for IE 6.x
3421
+ Dom.setStyle(nextButton, "visibility", "visible");
3422
+ btn = Dom.generateId();
3423
+ nextButton.innerHTML = "<button type=\"button\" " +
3424
+ "id=\"" + btn + "\" name=\"" +
3425
+ carousel.STRINGS.NEXT_BUTTON_TEXT + "\">" +
3426
+ carousel.STRINGS.NEXT_BUTTON_TEXT + "</button>";
3427
+ navContainer.appendChild(nextButton);
3428
+ btn = Dom.get(btn);
3429
+ carousel._navBtns.next = [btn];
3430
+ if (cfg) {
3431
+ cfg.next = [nextButton];
3432
+ } else {
3433
+ cfg = { next: [nextButton] };
3434
+ }
3435
+ }
3436
+
3437
+ if (cfg) {
3438
+ carousel.set("navigation", cfg);
3439
+ }
3440
+
3441
+ return navContainer;
3442
+ },
3443
+
3444
+ /**
3445
+ * Set the clip container size (based on the new numVisible value).
3446
+ *
3447
+ * @method _setClipContainerSize
3448
+ * @param clip {HTMLElement} The clip container element.
3449
+ * @param num {Number} optional The number of items per page.
3450
+ * @protected
3451
+ */
3452
+ _setClipContainerSize: function (clip, num) {
3453
+ var carousel = this,
3454
+ isVertical = carousel.get("isVertical"),
3455
+ rows = carousel._rows,
3456
+ cols = carousel._cols,
3457
+ reveal = carousel.get("revealAmount"),
3458
+ itemHeight = getCarouselItemSize.call(carousel, "height"),
3459
+ itemWidth = getCarouselItemSize.call(carousel, "width"),
3460
+ containerHeight,
3461
+ containerWidth;
3462
+
3463
+ clip = clip || carousel._clipEl;
3464
+
3465
+ if (rows) {
3466
+ containerHeight = itemHeight * rows;
3467
+ containerWidth = itemWidth * cols;
3468
+ } else {
3469
+ num = num || carousel.get("numVisible");
3470
+ if (isVertical) {
3471
+ containerHeight = itemHeight * num;
3472
+ } else {
3473
+ containerWidth = itemWidth * num;
3474
+ }
3475
+ }
3476
+
3477
+ // TODO: try to re-use the _hasRendered indicator
3478
+
3479
+ carousel._recomputeSize = (containerHeight === 0); // bleh!
3480
+ if (carousel._recomputeSize) {
3481
+ carousel._hasRendered = false;
3482
+ return; // no use going further, bail out!
3483
+ }
3484
+
3485
+ reveal = getRevealSize.call(carousel);
3486
+ if (isVertical) {
3487
+ containerHeight += (reveal * 2);
3488
+ } else {
3489
+ containerWidth += (reveal * 2);
3490
+ }
3491
+
3492
+ if (isVertical) {
3493
+ containerHeight += getDimensions(carousel._carouselEl,"height");
3494
+ Dom.setStyle(clip, "height", containerHeight + "px");
3495
+ // For multi-row Carousel
3496
+ if (cols) {
3497
+ containerWidth += getDimensions(carousel._carouselEl,
3498
+ "width");
3499
+ Dom.setStyle(clip, "width", containerWidth + (0) + "px");
3500
+ }
3501
+ } else {
3502
+ containerWidth += getDimensions(carousel._carouselEl, "width");
3503
+ Dom.setStyle(clip, "width", containerWidth + "px");
3504
+ // For multi-row Carousel
3505
+ if (rows) {
3506
+ containerHeight += getDimensions(carousel._carouselEl,
3507
+ "height");
3508
+ Dom.setStyle(clip, "height", containerHeight + "px");
3509
+ }
3510
+ }
3511
+
3512
+ carousel._setContainerSize(clip); // adjust the container size too
3513
+ },
3514
+
3515
+ /**
3516
+ * Set the container size.
3517
+ *
3518
+ * @method _setContainerSize
3519
+ * @param clip {HTMLElement} The clip container element.
3520
+ * @param attr {String} Either set the height or width.
3521
+ * @protected
3522
+ */
3523
+ _setContainerSize: function (clip, attr) {
3524
+ var carousel = this,
3525
+ config = carousel.CONFIG,
3526
+ cssClass = carousel.CLASSES,
3527
+ isVertical,
3528
+ rows,
3529
+ cols,
3530
+ size;
3531
+
3532
+ isVertical = carousel.get("isVertical");
3533
+ rows = carousel._rows;
3534
+ cols = carousel._cols;
3535
+ clip = clip || carousel._clipEl;
3536
+ attr = attr || (isVertical ? "height" : "width");
3537
+ size = parseFloat(Dom.getStyle(clip, attr), 10);
3538
+
3539
+ size = JS.isNumber(size) ? size : 0;
3540
+
3541
+ if (isVertical) {
3542
+ size += getDimensions(carousel._carouselEl, "height") +
3543
+ getStyle(carousel._navEl, "height");
3544
+ } else {
3545
+ size += getDimensions(carousel._carouselEl, "width");
3546
+ }
3547
+
3548
+ if (!isVertical) {
3549
+ if (size < config.HORZ_MIN_WIDTH) {
3550
+ size = config.HORZ_MIN_WIDTH;
3551
+ carousel.addClass(cssClass.MIN_WIDTH);
3552
+ }
3553
+ }
3554
+ carousel.setStyle(attr, size + "px");
3555
+
3556
+ // Additionally the width of the container should be set for
3557
+ // the vertical Carousel
3558
+ if (isVertical) {
3559
+ size = getCarouselItemSize.call(carousel, "width");
3560
+ if(cols) {
3561
+ size = size * cols;
3562
+ }
3563
+ Dom.setStyle(carousel._carouselEl, "width", size + "px");// Bug fix for vertical carousel (goes in conjunction with .yui-carousel-element {... 3200px removed from styles), and allows for multirows in IEs).
3564
+ if (size < config.VERT_MIN_WIDTH) {
3565
+ size = config.VERT_MIN_WIDTH;
3566
+ carousel.addClass(cssClass.MIN_WIDTH);// set a min width on vertical carousel, don't see why this shouldn't always be set...
3567
+ }
3568
+ carousel.setStyle("width", size + "px");
3569
+ } else {
3570
+ if(rows) {
3571
+ size = getCarouselItemSize.call(carousel, "height");
3572
+ size = size * rows;
3573
+ Dom.setStyle(carousel._carouselEl, "height", size + "px");
3574
+ }
3575
+ }
3576
+ },
3577
+
3578
+ /**
3579
+ * Set the value for the Carousel's first visible item.
3580
+ *
3581
+ * @method _setFirstVisible
3582
+ * @param val {Number} The new value for firstVisible
3583
+ * @return {Number} The new value that would be set
3584
+ * @protected
3585
+ */
3586
+ _setFirstVisible: function (val) {
3587
+ var carousel = this;
3588
+
3589
+ if (val >= 0 && val < carousel.get("numItems")) {
3590
+ carousel.scrollTo(val);
3591
+ } else {
3592
+ val = carousel.get("firstVisible");
3593
+ }
3594
+ return val;
3595
+ },
3596
+
3597
+ /**
3598
+ * Set the value for the Carousel's navigation.
3599
+ *
3600
+ * @method _setNavigation
3601
+ * @param cfg {Object} The navigation configuration
3602
+ * @return {Object} The new value that would be set
3603
+ * @protected
3604
+ */
3605
+ _setNavigation: function (cfg) {
3606
+ var carousel = this;
3607
+
3608
+ if (cfg.prev) {
3609
+ Event.on(cfg.prev, "click", scrollPageBackward, carousel);
3610
+ }
3611
+ if (cfg.next) {
3612
+ Event.on(cfg.next, "click", scrollPageForward, carousel);
3613
+ }
3614
+ },
3615
+
3616
+ /**
3617
+ * Clip the container size every time numVisible is set.
3618
+ *
3619
+ * @method _setNumVisible
3620
+ * @param val {Number} The new value for numVisible
3621
+ * @return {Number} The new value that would be set
3622
+ * @protected
3623
+ */
3624
+ _setNumVisible: function (val) { // TODO: _setNumVisible should just be reserved for setting numVisible.
3625
+ var carousel = this;
3626
+
3627
+ carousel._setClipContainerSize(carousel._clipEl, val);
3628
+ },
3629
+
3630
+ /**
3631
+ * Set the value for the number of visible items in the Carousel.
3632
+ *
3633
+ * @method _numVisibleSetter
3634
+ * @param val {Number} The new value for numVisible
3635
+ * @return {Number} The new value that would be set
3636
+ * @protected
3637
+ */
3638
+ _numVisibleSetter: function (val) {
3639
+ var carousel = this,
3640
+ numVisible = val;
3641
+
3642
+ if(JS.isArray(val)) {
3643
+ carousel._cols = val[0];
3644
+ carousel._rows = val[1];
3645
+ numVisible = val[0] * val[1];
3646
+ }
3647
+ return numVisible;
3648
+ },
3649
+
3650
+ /**
3651
+ * Set the value for selectedItem.
3652
+ *
3653
+ * @method _selectedItemSetter
3654
+ * @param val {Number} The new value for selectedItem
3655
+ * @return {Number} The new value that would be set
3656
+ * @protected
3657
+ */
3658
+ _selectedItemSetter: function (val) {
3659
+ var carousel = this;
3660
+ return (val < carousel.get("numItems")) ? val : 0;
3661
+ },
3662
+
3663
+ /**
3664
+ * Set the number of items in the Carousel.
3665
+ * Warning: Setting this to a lower number than the current removes
3666
+ * items from the end.
3667
+ *
3668
+ * @method _setNumItems
3669
+ * @param val {Number} The new value for numItems
3670
+ * @return {Number} The new value that would be set
3671
+ * @protected
3672
+ */
3673
+ _setNumItems: function (val) {
3674
+ var carousel = this,
3675
+ num = carousel._itemsTable.numItems;
3676
+
3677
+ if (JS.isArray(carousel._itemsTable.items)) {
3678
+ if (carousel._itemsTable.items.length != num) { // out of sync
3679
+ num = carousel._itemsTable.items.length;
3680
+ carousel._itemsTable.numItems = num;
3681
+ }
3682
+ }
3683
+
3684
+ if (val < num) {
3685
+ while (num > val) {
3686
+ carousel.removeItem(num - 1);
3687
+ num--;
3688
+ }
3689
+ }
3690
+
3691
+ return val;
3692
+ },
3693
+
3694
+ /**
3695
+ * Set the orientation of the Carousel.
3696
+ *
3697
+ * @method _setOrientation
3698
+ * @param val {Boolean} The new value for isVertical
3699
+ * @return {Boolean} The new value that would be set
3700
+ * @protected
3701
+ */
3702
+ _setOrientation: function (val) {
3703
+ var carousel = this,
3704
+ cssClass = carousel.CLASSES;
3705
+
3706
+ if (val) {
3707
+ carousel.replaceClass(cssClass.HORIZONTAL, cssClass.VERTICAL);
3708
+ } else {
3709
+ carousel.replaceClass(cssClass.VERTICAL, cssClass.HORIZONTAL);
3710
+ }
3711
+ this._itemAttrCache = {}; // force recomputed next time
3712
+
3713
+ return val;
3714
+ },
3715
+
3716
+ /**
3717
+ * Set the value for the reveal amount percentage in the Carousel.
3718
+ *
3719
+ * @method _setRevealAmount
3720
+ * @param val {Number} The new value for revealAmount
3721
+ * @return {Number} The new value that would be set
3722
+ * @protected
3723
+ */
3724
+ _setRevealAmount: function (val) {
3725
+ var carousel = this;
3726
+
3727
+ if (val >= 0 && val <= 100) {
3728
+ val = parseInt(val, 10);
3729
+ val = JS.isNumber(val) ? val : 0;
3730
+ carousel._setClipContainerSize();
3731
+ } else {
3732
+ val = carousel.get("revealAmount");
3733
+ }
3734
+ return val;
3735
+ },
3736
+
3737
+ /**
3738
+ * Set the value for the selected item.
3739
+ *
3740
+ * @method _setSelectedItem
3741
+ * @param val {Number} The new value for "selected" item
3742
+ * @protected
3743
+ */
3744
+ _setSelectedItem: function (val) {
3745
+ this._selectedItem = val;
3746
+ },
3747
+
3748
+ /**
3749
+ * Get the total number of pages.
3750
+ *
3751
+ * @method _getNumPages
3752
+ * @protected
3753
+ */
3754
+ _getNumPages: function () {
3755
+ return Math.ceil(
3756
+ parseInt(this.get("numItems"),10) / parseInt(this.get("numVisible"),10)
3757
+ );
3758
+ },
3759
+
3760
+ /**
3761
+ * Get the index of the last visible item
3762
+ *
3763
+ * @method _getLastVisible
3764
+ * @protected
3765
+ */
3766
+ _getLastVisible: function () {
3767
+ var carousel = this;
3768
+ return carousel.get("currentPage") + 1 == carousel.get("numPages") ?
3769
+ carousel.get("numItems") - 1:
3770
+ carousel.get("firstVisible") + carousel.get("numVisible") - 1;
3771
+ },
3772
+
3773
+ /**
3774
+ * Synchronize and redraw the UI after an item is added.
3775
+ *
3776
+ * @method _syncUiForItemAdd
3777
+ * @protected
3778
+ */
3779
+ _syncUiForItemAdd: function (obj) {
3780
+ var attr,
3781
+ carousel = this,
3782
+ carouselEl = carousel._carouselEl,
3783
+ el,
3784
+ item,
3785
+ itemsTable = carousel._itemsTable,
3786
+ oel,
3787
+ pos,
3788
+ sibling,
3789
+ styles;
3790
+
3791
+ pos = JS.isUndefined(obj.pos) ?
3792
+ obj.newPos || itemsTable.numItems - 1 : obj.pos;
3793
+
3794
+ if (!oel) {
3795
+ item = itemsTable.items[pos] || {};
3796
+ el = carousel._createCarouselItem({
3797
+ className : item.className,
3798
+ styles : item.styles,
3799
+ content : item.item,
3800
+ id : item.id,
3801
+ pos : pos
3802
+ });
3803
+ if (JS.isUndefined(obj.pos)) {
3804
+ if (!JS.isUndefined(itemsTable.loading[pos])) {
3805
+ oel = itemsTable.loading[pos];
3806
+ // if oel is null, it is a problem ...
3807
+ }
3808
+ if (oel) {
3809
+ // replace the node
3810
+ carouselEl.replaceChild(el, oel);
3811
+ // ... and remove the item from the data structure
3812
+ delete itemsTable.loading[pos];
3813
+ } else {
3814
+ carouselEl.appendChild(el);
3815
+ }
3816
+ } else {
3817
+ if (!JS.isUndefined(itemsTable.items[obj.pos + 1])) {
3818
+ sibling = Dom.get(itemsTable.items[obj.pos + 1].id);
3819
+ }
3820
+ if (sibling) {
3821
+ carouselEl.insertBefore(el, sibling);
3822
+ } else {
3823
+ }
3824
+ }
3825
+ } else {
3826
+ if (JS.isUndefined(obj.pos)) {
3827
+ if (!Dom.isAncestor(carousel._carouselEl, oel)) {
3828
+ carouselEl.appendChild(oel);
3829
+ }
3830
+ } else {
3831
+ if (!Dom.isAncestor(carouselEl, oel)) {
3832
+ if (!JS.isUndefined(itemsTable.items[obj.pos + 1])) {
3833
+ carouselEl.insertBefore(oel,
3834
+ Dom.get(itemsTable.items[obj.pos + 1].id));
3835
+ }
3836
+ }
3837
+ }
3838
+ }
3839
+
3840
+ if (!carousel._hasRendered) {
3841
+ carousel._refreshUi();
3842
+ }
3843
+
3844
+ if (carousel.get("selectedItem") < 0) {
3845
+ carousel.set("selectedItem", carousel.get("firstVisible"));
3846
+ }
3847
+
3848
+ carousel._syncUiItems();
3849
+ },
3850
+
3851
+ /**
3852
+ * Synchronize and redraw the UI after an item is replaced.
3853
+ *
3854
+ * @method _syncUiForItemReplace
3855
+ * @protected
3856
+ */
3857
+ _syncUiForItemReplace: function (o) {
3858
+ var carousel = this,
3859
+ carouselEl = carousel._carouselEl,
3860
+ itemsTable = carousel._itemsTable,
3861
+ pos = o.pos,
3862
+ item = o.newItem,
3863
+ oel = o.oldItem,
3864
+ el;
3865
+
3866
+ el = carousel._createCarouselItem({
3867
+ className : item.className,
3868
+ styles : item.styles,
3869
+ content : item.item,
3870
+ id : item.id,
3871
+ pos : pos
3872
+ });
3873
+
3874
+ if(el && oel) {
3875
+ Event.purgeElement(oel, true);
3876
+ carouselEl.replaceChild(el, Dom.get(oel.id));
3877
+ if (!JS.isUndefined(itemsTable.loading[pos])) {
3878
+ itemsTable.numItems++;
3879
+ delete itemsTable.loading[pos];
3880
+ }
3881
+ }
3882
+ // TODO: should we add the item if oel is undefined?
3883
+
3884
+ if (!carousel._hasRendered) {
3885
+ carousel._refreshUi();
3886
+ }
3887
+
3888
+ carousel._syncUiItems();
3889
+ },
3890
+
3891
+ /**
3892
+ * Synchronize and redraw the UI after an item is removed.
3893
+ *
3894
+ * @method _syncUiForItemAdd
3895
+ * @protected
3896
+ */
3897
+ _syncUiForItemRemove: function (obj) {
3898
+ var carousel = this,
3899
+ carouselEl = carousel._carouselEl,
3900
+ el, item, num, pos;
3901
+
3902
+ num = carousel.get("numItems");
3903
+ item = obj.item;
3904
+ pos = obj.pos;
3905
+
3906
+ if (item && (el = Dom.get(item.id))) {
3907
+ if (el && Dom.isAncestor(carouselEl, el)) {
3908
+ Event.purgeElement(el, true);
3909
+ carouselEl.removeChild(el);
3910
+ }
3911
+
3912
+ if (carousel.get("selectedItem") == pos) {
3913
+ pos = pos >= num ? num - 1 : pos;
3914
+ }
3915
+ } else {
3916
+ }
3917
+
3918
+ carousel._syncUiItems();
3919
+ },
3920
+
3921
+ /**
3922
+ * Synchronize and redraw the UI for lazy loading.
3923
+ *
3924
+ * @method _syncUiForLazyLoading
3925
+ * @protected
3926
+ */
3927
+ _syncUiForLazyLoading: function (obj) {
3928
+ var carousel = this,
3929
+ carouselEl = carousel._carouselEl,
3930
+ itemsTable = carousel._itemsTable,
3931
+ len = itemsTable.items.length,
3932
+ sibling = itemsTable.items[obj.last + 1],
3933
+ el,
3934
+ j;
3935
+
3936
+ // attempt to find the next closest sibling
3937
+ if(!sibling && obj.last < len){
3938
+ j = obj.first;
3939
+ do {
3940
+ sibling = itemsTable.items[j];
3941
+ j++;
3942
+ } while (j<len && !sibling);
3943
+ }
3944
+
3945
+ for (var i = obj.first; i <= obj.last; i++) {
3946
+ if(JS.isUndefined(itemsTable.loading[i]) && JS.isUndefined(itemsTable.items[i])){
3947
+ el = carousel._createCarouselItem({
3948
+ className : carousel.CLASSES.ITEM_LOADING,
3949
+ content : carousel.STRINGS.ITEM_LOADING_CONTENT,
3950
+ id : Dom.generateId(),
3951
+ pos : i
3952
+ });
3953
+ if (el) {
3954
+ if (sibling) {
3955
+ sibling = Dom.get(sibling.id);
3956
+ if (sibling) {
3957
+ carouselEl.insertBefore(el, sibling);
3958
+ } else {
3959
+ }
3960
+ } else {
3961
+ carouselEl.appendChild(el);
3962
+ }
3963
+ }
3964
+ itemsTable.loading[i] = el;
3965
+ }
3966
+ }
3967
+
3968
+ carousel._syncUiItems();
3969
+ },
3970
+
3971
+ /**
3972
+ * Redraw the UI for item positioning.
3973
+ *
3974
+ * @method _syncUiItems
3975
+ * @protected
3976
+ */
3977
+ _syncUiItems: function () {
3978
+ var attr,
3979
+ carousel = this,
3980
+ numItems = carousel.get("numItems"),
3981
+ i,
3982
+ itemsTable = carousel._itemsTable,
3983
+ items = itemsTable.items,
3984
+ loading = itemsTable.loading,
3985
+ item,
3986
+ styles;
3987
+
3988
+ for (i = 0; i < numItems; i++) {
3989
+ item = items[i] || loading[i];
3990
+
3991
+ if (item && item.id) {
3992
+ styles = getCarouselItemPosition.call(carousel, i);
3993
+ item.styles = item.styles || {};
3994
+ for (attr in styles) {
3995
+ if (styles.hasOwnProperty(attr)) {
3996
+ item.styles[attr] = styles[attr];
3997
+ }
3998
+ }
3999
+ setStyles(Dom.get(item.id), styles);
4000
+ }
4001
+ }
4002
+ },
4003
+
4004
+ /**
4005
+ * Set the correct class for the navigation buttons.
4006
+ *
4007
+ * @method _updateNavButtons
4008
+ * @param el {Object} The target button
4009
+ * @param setFocus {Boolean} True to set focus ring, false otherwise.
4010
+ * @protected
4011
+ */
4012
+ _updateNavButtons: function (el, setFocus) {
4013
+ var children,
4014
+ cssClass = this.CLASSES,
4015
+ grandParent,
4016
+ parent = el.parentNode;
4017
+
4018
+ if (!parent) {
4019
+ return;
4020
+ }
4021
+ grandParent = parent.parentNode;
4022
+
4023
+ if (el.nodeName.toUpperCase() == "BUTTON" &&
4024
+ Dom.hasClass(parent, cssClass.BUTTON)) {
4025
+ if (setFocus) {
4026
+ if (grandParent) {
4027
+ children = Dom.getChildren(grandParent);
4028
+ if (children) {
4029
+ Dom.removeClass(children, cssClass.FOCUSSED_BUTTON);
4030
+ }
4031
+ }
4032
+ Dom.addClass(parent, cssClass.FOCUSSED_BUTTON);
4033
+ } else {
4034
+ Dom.removeClass(parent, cssClass.FOCUSSED_BUTTON);
4035
+ }
4036
+ }
4037
+ },
4038
+
4039
+ /**
4040
+ * Update the UI for the pager buttons based on the current page and
4041
+ * the number of pages.
4042
+ *
4043
+ * @method _updatePagerButtons
4044
+ * @protected
4045
+ */
4046
+ _updatePagerButtons: function () {
4047
+ var carousel = this,
4048
+ css = carousel.CLASSES,
4049
+ cur = carousel._pages.cur, // current page
4050
+ el,
4051
+ html,
4052
+ i,
4053
+ item,
4054
+ n = carousel.get("numVisible"),
4055
+ num = carousel._pages.num, // total pages
4056
+ pager = carousel._pages.el; // the pager container element
4057
+
4058
+ if (num === 0 || !pager) {
4059
+ return; // don't do anything if number of pages is 0
4060
+ }
4061
+
4062
+ // Hide the pager before redrawing it
4063
+ Dom.setStyle(pager, "visibility", "hidden");
4064
+
4065
+ // Remove all nodes from the pager
4066
+ while (pager.firstChild) {
4067
+ pager.removeChild(pager.firstChild);
4068
+ }
4069
+
4070
+ for (i = 0; i < num; i++) {
4071
+
4072
+ el = document.createElement("LI");
4073
+
4074
+ if (i === 0) {
4075
+ Dom.addClass(el, css.FIRST_PAGE);
4076
+ }
4077
+ if (i == cur) {
4078
+ Dom.addClass(el, css.SELECTED_NAV);
4079
+ }
4080
+
4081
+ html = "<a class=" + css.PAGER_ITEM + " href=\"#" + (i+1) + "\" tabindex=\"0\"><em>" +
4082
+ carousel.STRINGS.PAGER_PREFIX_TEXT + " " + (i+1) +
4083
+ "</em></a>";
4084
+ el.innerHTML = html;
4085
+
4086
+ pager.appendChild(el);
4087
+ }
4088
+
4089
+ // Show the pager now
4090
+ Dom.setStyle(pager, "visibility", "visible");
4091
+ },
4092
+
4093
+ /**
4094
+ * Update the UI for the pager menu based on the current page and
4095
+ * the number of pages. If the number of pages is greater than
4096
+ * MAX_PAGER_BUTTONS, then the selection of pages is provided by a drop
4097
+ * down menu instead of a set of buttons.
4098
+ *
4099
+ * @method _updatePagerMenu
4100
+ * @protected
4101
+ */
4102
+ _updatePagerMenu: function () {
4103
+ var carousel = this,
4104
+ css = carousel.CLASSES,
4105
+ cur = carousel._pages.cur, // current page
4106
+ el,
4107
+ i,
4108
+ item,
4109
+ n = carousel.get("numVisible"),
4110
+ num = carousel._pages.num, // total pages
4111
+ pager = carousel._pages.el, // the pager container element
4112
+ sel;
4113
+
4114
+ if (num === 0) {
4115
+ return;// don't do anything if number of pages is 0
4116
+ }
4117
+
4118
+ sel = document.createElement("SELECT");
4119
+
4120
+
4121
+ if (!sel) {
4122
+ return;
4123
+ }
4124
+
4125
+ // Hide the pager before redrawing it
4126
+ Dom.setStyle(pager, "visibility", "hidden");
4127
+
4128
+ // Remove all nodes from the pager
4129
+ while (pager.firstChild) {
4130
+ pager.removeChild(pager.firstChild);
4131
+ }
4132
+
4133
+ for (i = 0; i < num; i++) {
4134
+
4135
+ el = document.createElement("OPTION");
4136
+ el.value = i+1;
4137
+ el.innerHTML = carousel.STRINGS.PAGER_PREFIX_TEXT+" "+(i+1);
4138
+
4139
+ if (i == cur) {
4140
+ el.setAttribute("selected", "selected");
4141
+ }
4142
+
4143
+ sel.appendChild(el);
4144
+ }
4145
+
4146
+ el = document.createElement("FORM");
4147
+ if (!el) {
4148
+ } else {
4149
+ el.appendChild(sel);
4150
+ pager.appendChild(el);
4151
+ }
4152
+
4153
+ // Show the pager now
4154
+ Event.addListener(sel, "change", carousel._pagerChangeHandler, this, true);
4155
+ Dom.setStyle(pager, "visibility", "visible");
4156
+ },
4157
+
4158
+ /**
4159
+ * Set the correct tab index for the Carousel items.
4160
+ *
4161
+ * @method _updateTabIndex
4162
+ * @param el {Object} The element to be focussed
4163
+ * @protected
4164
+ */
4165
+ _updateTabIndex: function (el) {
4166
+ var carousel = this;
4167
+
4168
+ if (el) {
4169
+ if (carousel._focusableItemEl) {
4170
+ carousel._focusableItemEl.tabIndex = -1;
4171
+ }
4172
+ carousel._focusableItemEl = el;
4173
+ el.tabIndex = 0;
4174
+ }
4175
+ },
4176
+
4177
+ /**
4178
+ * Validate animation parameters.
4179
+ *
4180
+ * @method _validateAnimation
4181
+ * @param cfg {Object} The animation configuration
4182
+ * @return {Boolean} The status of the validation
4183
+ * @protected
4184
+ */
4185
+ _validateAnimation: function (cfg) {
4186
+ var rv = true;
4187
+
4188
+ if (JS.isObject(cfg)) {
4189
+ if (cfg.speed) {
4190
+ rv = rv && JS.isNumber(cfg.speed);
4191
+ }
4192
+ if (cfg.effect) {
4193
+ rv = rv && JS.isFunction(cfg.effect);
4194
+ } else if (!JS.isUndefined(YAHOO.util.Easing)) {
4195
+ cfg.effect = YAHOO.util.Easing.easeOut;
4196
+ }
4197
+ } else {
4198
+ rv = false;
4199
+ }
4200
+
4201
+ return rv;
4202
+ },
4203
+
4204
+ /**
4205
+ * Validate the firstVisible value.
4206
+ *
4207
+ * @method _validateFirstVisible
4208
+ * @param val {Number} The first visible value
4209
+ * @return {Boolean} The status of the validation
4210
+ * @protected
4211
+ */
4212
+ _validateFirstVisible: function (val) {
4213
+ var carousel = this, numItems = carousel.get("numItems");
4214
+
4215
+ if (JS.isNumber(val)) {
4216
+ if (numItems === 0 && val == numItems) {
4217
+ return true;
4218
+ } else {
4219
+ return (val >= 0 && val < numItems);
4220
+ }
4221
+ }
4222
+
4223
+ return false;
4224
+ },
4225
+
4226
+ /**
4227
+ * Validate and navigation parameters.
4228
+ *
4229
+ * @method _validateNavigation
4230
+ * @param cfg {Object} The navigation configuration
4231
+ * @return {Boolean} The status of the validation
4232
+ * @protected
4233
+ */
4234
+ _validateNavigation : function (cfg) {
4235
+ var i;
4236
+
4237
+ if (!JS.isObject(cfg)) {
4238
+ return false;
4239
+ }
4240
+
4241
+ if (cfg.prev) {
4242
+ if (!JS.isArray(cfg.prev)) {
4243
+ return false;
4244
+ }
4245
+ for (i in cfg.prev) {
4246
+ if (cfg.prev.hasOwnProperty(i)) {
4247
+ if (!JS.isString(cfg.prev[i].nodeName)) {
4248
+ return false;
4249
+ }
4250
+ }
4251
+ }
4252
+ }
4253
+
4254
+ if (cfg.next) {
4255
+ if (!JS.isArray(cfg.next)) {
4256
+ return false;
4257
+ }
4258
+ for (i in cfg.next) {
4259
+ if (cfg.next.hasOwnProperty(i)) {
4260
+ if (!JS.isString(cfg.next[i].nodeName)) {
4261
+ return false;
4262
+ }
4263
+ }
4264
+ }
4265
+ }
4266
+
4267
+ return true;
4268
+ },
4269
+
4270
+ /**
4271
+ * Validate the numItems value.
4272
+ *
4273
+ * @method _validateNumItems
4274
+ * @param val {Number} The numItems value
4275
+ * @return {Boolean} The status of the validation
4276
+ * @protected
4277
+ */
4278
+ _validateNumItems: function (val) {
4279
+ return JS.isNumber(val) && (val >= 0);
4280
+ },
4281
+
4282
+ /**
4283
+ * Validate the numVisible value.
4284
+ *
4285
+ * @method _validateNumVisible
4286
+ * @param val {Number} The numVisible value
4287
+ * @return {Boolean} The status of the validation
4288
+ * @protected
4289
+ */
4290
+ _validateNumVisible: function (val) {
4291
+ var rv = false;
4292
+
4293
+ if (JS.isNumber(val)) {
4294
+ rv = val > 0 && val <= this.get("numItems");
4295
+ } else if (JS.isArray(val)) {
4296
+ if (JS.isNumber(val[0]) && JS.isNumber(val[1])) {
4297
+ rv = val[0] * val[1] > 0 && val.length == 2;
4298
+ }
4299
+ }
4300
+
4301
+ return rv;
4302
+ },
4303
+
4304
+ /**
4305
+ * Validate the revealAmount value.
4306
+ *
4307
+ * @method _validateRevealAmount
4308
+ * @param val {Number} The revealAmount value
4309
+ * @return {Boolean} The status of the validation
4310
+ * @protected
4311
+ */
4312
+ _validateRevealAmount: function (val) {
4313
+ var rv = false;
4314
+
4315
+ if (JS.isNumber(val)) {
4316
+ rv = val >= 0 && val < 100;
4317
+ }
4318
+
4319
+ return rv;
4320
+ },
4321
+
4322
+ /**
4323
+ * Validate the scrollIncrement value.
4324
+ *
4325
+ * @method _validateScrollIncrement
4326
+ * @param val {Number} The scrollIncrement value
4327
+ * @return {Boolean} The status of the validation
4328
+ * @protected
4329
+ */
4330
+ _validateScrollIncrement: function (val) {
4331
+ var rv = false;
4332
+
4333
+ if (JS.isNumber(val)) {
4334
+ rv = (val > 0 && val < this.get("numItems"));
4335
+ }
4336
+
4337
+ return rv;
4338
+ }
4339
+
4340
+ });
4341
+
4342
+ })();
4343
+ /*
4344
+ ;; Local variables: **
4345
+ ;; mode: js2 **
4346
+ ;; indent-tabs-mode: nil **
4347
+ ;; End: **
4348
+ */
4349
+ YAHOO.register("carousel", YAHOO.widget.Carousel, {version: "2.8.1", build: "19"});