yui-rails-asset 2.8.1

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