alchemy_cms 2.1.12 → 2.2.rc1

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 (405) hide show
  1. data/.travis.yml +1 -1
  2. data/Gemfile +20 -16
  3. data/README.md +11 -7
  4. data/alchemy_cms.gemspec +31 -29
  5. data/app/assets/javascripts/alchemy/alchemy.base.js +234 -233
  6. data/app/assets/javascripts/alchemy/alchemy.buttons.js +26 -26
  7. data/app/assets/javascripts/alchemy/alchemy.datepicker.js +32 -32
  8. data/app/assets/javascripts/alchemy/alchemy.dirty.js +78 -78
  9. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js +103 -103
  10. data/app/assets/javascripts/alchemy/alchemy.element_editor_selector.js +84 -84
  11. data/app/assets/javascripts/alchemy/alchemy.elements_window.js +88 -88
  12. data/app/assets/javascripts/alchemy/alchemy.file_progress.js +92 -0
  13. data/app/assets/javascripts/alchemy/alchemy.growler.js +23 -23
  14. data/app/assets/javascripts/alchemy/alchemy.html5.js +23 -0
  15. data/app/assets/javascripts/alchemy/alchemy.image_cropper.js +53 -52
  16. data/app/assets/javascripts/alchemy/alchemy.jquery_loader.js +33 -30
  17. data/app/assets/javascripts/alchemy/alchemy.js +2 -0
  18. data/app/assets/javascripts/alchemy/alchemy.js_extensions.js +14 -14
  19. data/app/assets/javascripts/alchemy/alchemy.link_overlay.js.coffee +181 -0
  20. data/app/assets/javascripts/alchemy/alchemy.menubar.js +48 -48
  21. data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +39 -39
  22. data/app/assets/javascripts/alchemy/alchemy.preview.js +81 -83
  23. data/app/assets/javascripts/alchemy/alchemy.preview_window.js +86 -86
  24. data/app/assets/javascripts/alchemy/alchemy.routes.js.erb +23 -23
  25. data/app/assets/javascripts/alchemy/alchemy.swf_upload.js +208 -353
  26. data/app/assets/javascripts/alchemy/alchemy.uploader.js +279 -0
  27. data/app/assets/javascripts/alchemy/alchemy.windows.js +268 -268
  28. data/app/assets/javascripts/tiny_mce/plugins/alchemy_link/editor_plugin.js +42 -42
  29. data/app/assets/stylesheets/alchemy/_defaults.scss +89 -89
  30. data/app/assets/stylesheets/alchemy/base.css.scss +790 -804
  31. data/app/assets/stylesheets/alchemy/buttons.css.scss +263 -264
  32. data/app/assets/stylesheets/alchemy/dashboard.css.scss +66 -66
  33. data/app/assets/stylesheets/alchemy/elements.css.scss +575 -564
  34. data/app/assets/stylesheets/alchemy/flash.css.scss +45 -45
  35. data/app/assets/stylesheets/alchemy/frame.css.scss +262 -262
  36. data/app/assets/stylesheets/alchemy/icons.css.scss +86 -86
  37. data/app/assets/stylesheets/alchemy/jquery-ui.alchemy.css.scss +706 -707
  38. data/app/assets/stylesheets/alchemy/jquery.Jcrop.css.scss +46 -27
  39. data/app/assets/stylesheets/alchemy/jquery.sb.css.scss +107 -107
  40. data/app/assets/stylesheets/alchemy/login.css.scss +40 -38
  41. data/app/assets/stylesheets/alchemy/menubar.css.scss +84 -82
  42. data/app/assets/stylesheets/alchemy/modules.css.scss +9 -9
  43. data/app/assets/stylesheets/alchemy/pagination.css.scss +49 -49
  44. data/app/assets/stylesheets/alchemy/print.css +7 -7
  45. data/app/assets/stylesheets/alchemy/sitemap.css.scss +185 -154
  46. data/app/assets/stylesheets/alchemy/standard_set.css +205 -206
  47. data/app/assets/stylesheets/alchemy/tables.css.scss +94 -60
  48. data/app/assets/stylesheets/alchemy/tinymce_content.css.scss +34 -34
  49. data/app/assets/stylesheets/alchemy/tinymce_dialog.css.scss +177 -177
  50. data/app/assets/stylesheets/alchemy/upload.css.scss +68 -45
  51. data/app/assets/stylesheets/tiny_mce/plugins/inlinepopups/skins/alchemy/window.css.scss +222 -221
  52. data/app/controllers/alchemy/admin/attachments_controller.rb +100 -100
  53. data/app/controllers/alchemy/admin/base_controller.rb +116 -116
  54. data/app/controllers/alchemy/admin/clipboard_controller.rb +44 -44
  55. data/app/controllers/alchemy/admin/contents_controller.rb +55 -55
  56. data/app/controllers/alchemy/admin/dashboard_controller.rb +12 -11
  57. data/app/controllers/alchemy/admin/elements_controller.rb +109 -109
  58. data/app/controllers/alchemy/admin/essence_audios_controller.rb +8 -8
  59. data/app/controllers/alchemy/admin/essence_files_controller.rb +20 -20
  60. data/app/controllers/alchemy/admin/essence_flashes_controller.rb +8 -8
  61. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +81 -81
  62. data/app/controllers/alchemy/admin/essence_videos_controller.rb +8 -8
  63. data/app/controllers/alchemy/admin/languages_controller.rb +16 -4
  64. data/app/controllers/alchemy/admin/layoutpages_controller.rb +9 -9
  65. data/app/controllers/alchemy/admin/pages_controller.rb +249 -248
  66. data/app/controllers/alchemy/admin/pictures_controller.rb +105 -105
  67. data/app/controllers/alchemy/admin/resources_controller.rb +111 -166
  68. data/app/controllers/alchemy/admin/trash_controller.rb +18 -18
  69. data/app/controllers/alchemy/admin/users_controller.rb +69 -69
  70. data/app/controllers/alchemy/attachments_controller.rb +27 -27
  71. data/app/controllers/alchemy/base_controller.rb +159 -155
  72. data/app/controllers/alchemy/elements_controller.rb +16 -16
  73. data/app/controllers/alchemy/messages_controller.rb +59 -59
  74. data/app/controllers/alchemy/pages_controller.rb +194 -198
  75. data/app/controllers/alchemy/pictures_controller.rb +57 -57
  76. data/app/controllers/alchemy/user_sessions_controller.rb +70 -70
  77. data/app/helpers/alchemy/admin/attachments_helper.rb +7 -7
  78. data/app/helpers/alchemy/admin/base_helper.rb +425 -425
  79. data/app/helpers/alchemy/admin/contents_helper.rb +72 -72
  80. data/app/helpers/alchemy/admin/elements_helper.rb +108 -107
  81. data/app/helpers/alchemy/admin/essences_helper.rb +108 -108
  82. data/app/helpers/alchemy/admin/pages_helper.rb +42 -42
  83. data/app/helpers/alchemy/admin/pictures_helper.rb +26 -26
  84. data/app/helpers/alchemy/base_helper.rb +90 -90
  85. data/app/helpers/alchemy/elements_helper.rb +167 -168
  86. data/app/helpers/alchemy/essences_helper.rb +133 -133
  87. data/app/helpers/alchemy/pages_helper.rb +515 -526
  88. data/app/helpers/alchemy/pictures_helper.rb +19 -0
  89. data/app/mailers/alchemy/messages.rb +13 -13
  90. data/app/mailers/alchemy/notifications.rb +19 -19
  91. data/app/models/alchemy.rb +3 -3
  92. data/app/models/alchemy/attachment.rb +52 -78
  93. data/app/models/alchemy/cell.rb +48 -48
  94. data/app/models/alchemy/content.rb +196 -196
  95. data/app/models/alchemy/element.rb +500 -490
  96. data/app/models/alchemy/essence_audio.rb +7 -7
  97. data/app/models/alchemy/essence_date.rb +10 -10
  98. data/app/models/alchemy/essence_file.rb +7 -7
  99. data/app/models/alchemy/essence_flash.rb +6 -6
  100. data/app/models/alchemy/essence_html.rb +9 -9
  101. data/app/models/alchemy/essence_picture.rb +17 -17
  102. data/app/models/alchemy/essence_richtext.rb +53 -53
  103. data/app/models/alchemy/essence_text.rb +21 -21
  104. data/app/models/alchemy/essence_video.rb +7 -7
  105. data/app/models/alchemy/folded_page.rb +3 -3
  106. data/app/models/alchemy/language.rb +91 -91
  107. data/app/models/alchemy/language/code.rb +14 -14
  108. data/app/models/alchemy/message.rb +48 -45
  109. data/app/models/alchemy/page.rb +555 -558
  110. data/app/models/alchemy/picture.rb +100 -99
  111. data/app/models/alchemy/user.rb +76 -74
  112. data/app/models/alchemy/user_session.rb +8 -8
  113. data/app/sweepers/alchemy/content_sweeper.rb +15 -15
  114. data/app/sweepers/alchemy/pages_sweeper.rb +50 -50
  115. data/app/sweepers/alchemy/pictures_sweeper.rb +14 -14
  116. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +23 -23
  117. data/app/views/alchemy/admin/attachments/_attachment.html.erb +56 -56
  118. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +15 -15
  119. data/app/views/alchemy/admin/attachments/_files_list.html.erb +16 -16
  120. data/app/views/alchemy/admin/attachments/create.js.erb +2 -2
  121. data/app/views/alchemy/admin/attachments/destroy.js.erb +3 -3
  122. data/app/views/alchemy/admin/attachments/edit.html.erb +10 -10
  123. data/app/views/alchemy/admin/attachments/index.html.erb +14 -14
  124. data/app/views/alchemy/admin/attachments/new.html.erb +9 -9
  125. data/app/views/alchemy/admin/clipboard/index.html.erb +21 -21
  126. data/app/views/alchemy/admin/clipboard/insert.js.erb +5 -5
  127. data/app/views/alchemy/admin/contents/_missing.html.erb +1 -1
  128. data/app/views/alchemy/admin/contents/create.js.erb +33 -33
  129. data/app/views/alchemy/admin/contents/destroy.js.erb +5 -5
  130. data/app/views/alchemy/admin/contents/new.html.erb +13 -13
  131. data/app/views/alchemy/admin/contents/order.js.erb +2 -2
  132. data/app/views/alchemy/admin/dashboard/index.html.erb +96 -92
  133. data/app/views/alchemy/admin/elements/_add_content.html.erb +12 -12
  134. data/app/views/alchemy/admin/elements/_element.html.erb +3 -3
  135. data/app/views/alchemy/admin/elements/_new_element_form.html.erb +28 -28
  136. data/app/views/alchemy/admin/elements/_picture_editor.html.erb +21 -21
  137. data/app/views/alchemy/admin/elements/create.js.erb +32 -32
  138. data/app/views/alchemy/admin/elements/index.html.erb +2 -2
  139. data/app/views/alchemy/admin/elements/new.html.erb +31 -31
  140. data/app/views/alchemy/admin/elements/order.js.erb +3 -3
  141. data/app/views/alchemy/admin/elements/trash.js.erb +13 -13
  142. data/app/views/alchemy/admin/elements/update.js.erb +6 -6
  143. data/app/views/alchemy/admin/essence_files/assign.js.erb +6 -6
  144. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +32 -32
  145. data/app/views/alchemy/admin/essence_pictures/destroy.js.erb +1 -1
  146. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +1 -1
  147. data/app/views/alchemy/admin/essence_pictures/update.js.erb +11 -11
  148. data/app/views/alchemy/admin/languages/_form.html.erb +51 -45
  149. data/app/views/alchemy/admin/languages/_language.html.erb +45 -45
  150. data/app/views/alchemy/admin/languages/_table.html.erb +25 -25
  151. data/app/views/alchemy/admin/layoutpages/index.html.erb +35 -35
  152. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +42 -42
  153. data/app/views/alchemy/admin/pages/_external_link.html.erb +1 -1
  154. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +27 -27
  155. data/app/views/alchemy/admin/pages/_page.html.erb +112 -112
  156. data/app/views/alchemy/admin/pages/_sitemap.html.erb +1 -1
  157. data/app/views/alchemy/admin/pages/configure.html.erb +71 -69
  158. data/app/views/alchemy/admin/pages/configure_external.html.erb +38 -38
  159. data/app/views/alchemy/admin/pages/destroy.js.erb +10 -10
  160. data/app/views/alchemy/admin/pages/edit.html.erb +165 -165
  161. data/app/views/alchemy/admin/pages/fold.js.erb +2 -2
  162. data/app/views/alchemy/admin/pages/index.html.erb +66 -66
  163. data/app/views/alchemy/admin/pages/locked.html.erb +1 -1
  164. data/app/views/alchemy/admin/pages/new.html.erb +40 -40
  165. data/app/views/alchemy/admin/pages/sort.js.erb +4 -4
  166. data/app/views/alchemy/admin/pages/unlock.js.erb +6 -6
  167. data/app/views/alchemy/admin/pages/update.js.erb +19 -19
  168. data/app/views/alchemy/admin/partials/_flash.html.erb +2 -2
  169. data/app/views/alchemy/admin/partials/_flash_notices.html.erb +1 -1
  170. data/app/views/alchemy/admin/partials/_flash_upload.html.erb +38 -0
  171. data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +15 -15
  172. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +8 -8
  173. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +35 -35
  174. data/app/views/alchemy/admin/partials/_search_form.html.erb +14 -14
  175. data/app/views/alchemy/admin/partials/_sub_navigation_tab.html.erb +6 -6
  176. data/app/views/alchemy/admin/partials/_upload_form.html.erb +56 -118
  177. data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +11 -11
  178. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +71 -71
  179. data/app/views/alchemy/admin/pictures/_picture.html.erb +32 -32
  180. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +26 -26
  181. data/app/views/alchemy/admin/pictures/_pictures_list.html.erb +6 -6
  182. data/app/views/alchemy/admin/pictures/create.js.erb +7 -7
  183. data/app/views/alchemy/admin/pictures/index.html.erb +67 -67
  184. data/app/views/alchemy/admin/pictures/show_in_window.html.erb +5 -4
  185. data/app/views/alchemy/admin/resources/_form.html.erb +25 -19
  186. data/app/views/alchemy/admin/resources/_resource.html.erb +37 -36
  187. data/app/views/alchemy/admin/resources/_table.html.erb +17 -17
  188. data/app/views/alchemy/admin/resources/destroy.js.erb +1 -1
  189. data/app/views/alchemy/admin/resources/index.html.erb +14 -14
  190. data/app/views/alchemy/admin/trash/index.html.erb +20 -20
  191. data/app/views/alchemy/admin/users/_table.html.erb +52 -52
  192. data/app/views/alchemy/admin/users/_user.html.erb +35 -36
  193. data/app/views/alchemy/admin/users/index.html.erb +26 -27
  194. data/app/views/alchemy/base/error_notice.html.erb +2 -2
  195. data/app/views/alchemy/base/update.js.erb +1 -1
  196. data/app/views/alchemy/elements/_contactform_view.html.erb +76 -76
  197. data/app/views/alchemy/elements/_download_view.html.erb +1 -1
  198. data/app/views/alchemy/elements/_editor_not_found.html.erb +3 -3
  199. data/app/views/alchemy/elements/_searchresult_view.html.erb +2 -2
  200. data/app/views/alchemy/elements/_sitemap_editor.html.erb +1 -1
  201. data/app/views/alchemy/essences/_essence_audio_view.html.erb +13 -13
  202. data/app/views/alchemy/essences/_essence_date_editor.html.erb +10 -10
  203. data/app/views/alchemy/essences/_essence_file_editor.html.erb +62 -62
  204. data/app/views/alchemy/essences/_essence_file_view.html.erb +8 -8
  205. data/app/views/alchemy/essences/_essence_flash_view.html.erb +19 -19
  206. data/app/views/alchemy/essences/_essence_html_editor.html.erb +6 -6
  207. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +73 -73
  208. data/app/views/alchemy/essences/_essence_picture_view.html.erb +34 -34
  209. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +7 -7
  210. data/app/views/alchemy/essences/_essence_text_editor.html.erb +8 -8
  211. data/app/views/alchemy/navigation/_image_link.html.erb +12 -12
  212. data/app/views/alchemy/navigation/_link.html.erb +13 -13
  213. data/app/views/alchemy/navigation/_renderer.html.erb +17 -17
  214. data/app/views/alchemy/page_layouts/_layout_footer.html.erb +1 -1
  215. data/app/views/alchemy/page_layouts/_layout_header.html.erb +1 -1
  216. data/app/views/alchemy/pages/show.rss.builder +14 -14
  217. data/app/views/alchemy/search/_result.html.erb +7 -7
  218. data/app/views/alchemy/user_sessions/leave.html.erb +9 -9
  219. data/app/views/alchemy/user_sessions/login.html.erb +39 -39
  220. data/app/views/alchemy/user_sessions/logout.html.erb +1 -1
  221. data/app/views/layouts/alchemy/admin.html.erb +81 -81
  222. data/app/views/layouts/alchemy/login.html.erb +36 -36
  223. data/app/views/layouts/alchemy/pages.html.erb +48 -27
  224. data/bin/alchemy +136 -134
  225. data/config/alchemy/config.yml +13 -9
  226. data/config/locales/alchemy.de.yml +24 -30
  227. data/config/locales/alchemy.en.yml +11 -28
  228. data/config/routes.rb +146 -146
  229. data/db/migrate/20100607193638_create_essence_pictures.rb +3 -3
  230. data/db/migrate/20101109150312_alter_pages_visible_column_default.rb +1 -1
  231. data/db/migrate/20101109151812_create_languages.rb +3 -3
  232. data/db/migrate/20110115123343_remove_css_class_default_from_essence_pictures.rb +3 -3
  233. data/db/migrate/20110224105120_change_pages_visible_default.rb +3 -3
  234. data/db/migrate/20110228182659_remove_default_page_layout_from_pages.rb +2 -2
  235. data/db/migrate/20110414163140_remove_display_name_from_elements.rb +3 -3
  236. data/db/migrate/20110511100516_rename_essence_texts_title_to_link_title.rb +2 -2
  237. data/db/migrate/20110529130500_add_cell_id_to_elements.rb +3 -3
  238. data/db/migrate/20110530102804_change_pages_page_layout_column.rb +3 -3
  239. data/db/migrate/20110711142057_change_open_link_in_new_window_to_link_target.rb +1 -1
  240. data/db/migrate/20111116125112_namespace_alchemy_models.rb +21 -21
  241. data/lib/alchemy/auth_engine.rb +5 -5
  242. data/lib/alchemy/capistrano.rb +64 -64
  243. data/lib/alchemy/config.rb +47 -44
  244. data/lib/alchemy/engine.rb +41 -41
  245. data/lib/alchemy/essence.rb +50 -51
  246. data/lib/alchemy/i18n.rb +48 -48
  247. data/lib/alchemy/modules.rb +30 -30
  248. data/lib/alchemy/mount_point.rb +6 -6
  249. data/lib/alchemy/page_layout.rb +94 -93
  250. data/lib/alchemy/resource.rb +82 -0
  251. data/lib/alchemy/resources_helper.rb +56 -0
  252. data/lib/alchemy/scoped_pagination_url_helper.rb +8 -8
  253. data/lib/alchemy/seeder.rb +88 -88
  254. data/lib/alchemy/tinymce.rb +49 -49
  255. data/lib/alchemy/upgrader.rb +103 -103
  256. data/lib/alchemy/version.rb +1 -1
  257. data/lib/alchemy_cms.rb +26 -27
  258. data/lib/extensions/action_view.rb +1 -1
  259. data/lib/extensions/array.rb +3 -3
  260. data/lib/extensions/hash.rb +3 -3
  261. data/lib/middleware/flash_session_cookie.rb +1 -1
  262. data/lib/rails/generators/alchemy/deploy_script/deploy_script_generator.rb +24 -24
  263. data/lib/rails/generators/alchemy/elements/elements_generator.rb +7 -7
  264. data/lib/rails/generators/alchemy/elements/templates/view.html.erb +17 -17
  265. data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +6 -6
  266. data/lib/rails/generators/alchemy/plugin/templates/authorization_rules.rb +8 -8
  267. data/lib/rails/generators/alchemy/scaffold/files/pages.html.erb +7 -7
  268. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +36 -36
  269. data/lib/rails/templates/alchemy.rb +1 -1
  270. data/lib/tasks/ferret.rake +2 -2
  271. data/lib/tasks/fleximage.rake +32 -32
  272. data/lib/tasks/install.rake +12 -12
  273. data/lib/tasks/upgrade.rake +4 -4
  274. data/spec/controllers/admin/clipboard_controller_spec.rb +43 -43
  275. data/spec/controllers/admin/contents_controller_spec.rb +22 -22
  276. data/spec/controllers/admin/elements_controller_spec.rb +13 -13
  277. data/spec/controllers/admin/languages_controller_spec.rb +31 -0
  278. data/spec/controllers/admin/pages_controller_spec.rb +10 -41
  279. data/spec/controllers/admin/resources_controller_spec.rb +19 -0
  280. data/spec/controllers/admin/trash_controller_spec.rb +11 -11
  281. data/spec/controllers/base_controller_spec.rb +46 -46
  282. data/spec/controllers/pages_controller_spec.rb +102 -92
  283. data/spec/dummy/app/controllers/admin/events_controller.rb +3 -0
  284. data/spec/dummy/app/controllers/errors_controller.rb +5 -0
  285. data/spec/dummy/app/models/event.rb +3 -0
  286. data/spec/dummy/config.ru +1 -1
  287. data/spec/dummy/config/application.rb +3 -0
  288. data/spec/dummy/config/authorization_rules.rb +7 -0
  289. data/spec/dummy/config/environments/development.rb +8 -1
  290. data/spec/dummy/config/environments/production.rb +1 -1
  291. data/spec/dummy/config/environments/test.rb +5 -2
  292. data/spec/dummy/config/routes.rb +9 -1
  293. data/spec/dummy/db/schema.rb +47 -35
  294. data/spec/dummy/public/404.html +19 -7
  295. data/spec/dummy/public/404.html.bak +26 -0
  296. data/spec/dummy/public/422.html +19 -7
  297. data/spec/dummy/public/500.html +19 -7
  298. data/spec/dummy/script/rails +2 -2
  299. data/spec/factories.rb +76 -76
  300. data/spec/helpers/admin/base_helper_spec.rb +21 -21
  301. data/spec/helpers/admin/contents_helper_spec.rb +14 -14
  302. data/spec/helpers/admin/elements_helper_spec.rb +40 -40
  303. data/spec/helpers/admin/essences_helper_spec.rb +7 -7
  304. data/spec/helpers/elements_helper_spec.rb +154 -154
  305. data/spec/helpers/essences_helper_spec.rb +10 -10
  306. data/spec/helpers/pages_helper_spec.rb +369 -372
  307. data/spec/helpers/pictures_helper_spec.rb +14 -0
  308. data/spec/helpers/url_helpers_spec.rb +29 -34
  309. data/spec/integration/admin/pages_controller_spec.rb +50 -50
  310. data/spec/integration/admin/resources_integration_spec.rb +100 -0
  311. data/spec/integration/navigation_spec.rb +1 -1
  312. data/spec/integration/pages_controller_spec.rb +205 -207
  313. data/spec/integration/security_spec.rb +47 -47
  314. data/spec/javascripts/alchemy/link_overlay_spec.js.coffee +42 -0
  315. data/spec/javascripts/alchemy_integration_spec.coffee +12 -0
  316. data/spec/javascripts/fixtures/select.html +3 -0
  317. data/spec/javascripts/helpers/.gitkeep +0 -0
  318. data/spec/javascripts/helpers/jasmine-jquery-1.3.1.js +289 -0
  319. data/spec/javascripts/helpers/mock-ajax.js +207 -0
  320. data/spec/javascripts/helpers/test_responses/test_responses.js +1 -0
  321. data/spec/javascripts/spec.css +3 -0
  322. data/spec/javascripts/spec.js +2 -0
  323. data/spec/libraries/resource_spec.rb +122 -0
  324. data/spec/libraries/resources_helper_spec.rb +105 -0
  325. data/spec/models/content_spec.rb +67 -67
  326. data/spec/models/element_spec.rb +133 -133
  327. data/spec/models/essence_picture_spec.rb +5 -5
  328. data/spec/models/essence_richtext_spec.rb +4 -4
  329. data/spec/models/language_spec.rb +89 -89
  330. data/spec/models/page_spec.rb +436 -506
  331. data/spec/models/picture_spec.rb +34 -34
  332. data/spec/models/user_spec.rb +2 -2
  333. data/spec/page_layout_spec.rb +24 -20
  334. data/spec/routing_spec.rb +253 -253
  335. data/spec/spec_helper.rb +51 -50
  336. data/spec/support/alchemy/controller_hacks.rb +25 -25
  337. data/spec/support/alchemy/specs_helpers.rb +25 -25
  338. data/spec/support/integration_spec_helper.rb +24 -0
  339. data/vendor/assets/javascripts/jquery_plugins/jquery.html5uploader.js +271 -0
  340. data/vendor/assets/javascripts/jquery_plugins/jquery.in-place-edit.js +86 -85
  341. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +380 -377
  342. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.tabspaging.js +285 -279
  343. data/vendor/assets/javascripts/swfupload/SWFObject License.txt +3 -3
  344. data/vendor/assets/javascripts/swfupload/swfupload.cookies.js +47 -47
  345. data/vendor/assets/javascripts/swfupload/swfupload.js +612 -612
  346. data/vendor/assets/javascripts/swfupload/swfupload.queue.js +93 -93
  347. data/vendor/assets/javascripts/swfupload/swfupload.speed.js +337 -337
  348. data/vendor/assets/javascripts/swfupload/swfupload.swfobject.js +706 -102
  349. data/vendor/assets/javascripts/tiny_mce/license.txt +6 -6
  350. data/vendor/assets/javascripts/tiny_mce/plugins/fullscreen/fullscreen.htm +97 -97
  351. data/vendor/assets/javascripts/tiny_mce/plugins/inlinepopups/template.htm +386 -376
  352. data/vendor/assets/javascripts/tiny_mce/plugins/paste/js/pastetext.js +30 -30
  353. data/vendor/assets/javascripts/tiny_mce/plugins/paste/js/pasteword.js +45 -45
  354. data/vendor/assets/javascripts/tiny_mce/plugins/paste/pastetext.htm +20 -17
  355. data/vendor/assets/javascripts/tiny_mce/plugins/paste/pasteword.htm +12 -12
  356. data/vendor/assets/javascripts/tiny_mce/plugins/table/cell.htm +183 -173
  357. data/vendor/assets/javascripts/tiny_mce/plugins/table/css/cell.css +4 -4
  358. data/vendor/assets/javascripts/tiny_mce/plugins/table/css/row.css +7 -7
  359. data/vendor/assets/javascripts/tiny_mce/plugins/table/css/table.css +3 -3
  360. data/vendor/assets/javascripts/tiny_mce/plugins/table/js/cell.js +282 -280
  361. data/vendor/assets/javascripts/tiny_mce/plugins/table/js/merge_cells.js +15 -15
  362. data/vendor/assets/javascripts/tiny_mce/plugins/table/js/row.js +204 -204
  363. data/vendor/assets/javascripts/tiny_mce/plugins/table/js/table.js +435 -435
  364. data/vendor/assets/javascripts/tiny_mce/plugins/table/merge_cells.htm +24 -22
  365. data/vendor/assets/javascripts/tiny_mce/plugins/table/row.htm +144 -136
  366. data/vendor/assets/javascripts/tiny_mce/plugins/table/table.htm +184 -168
  367. data/vendor/assets/javascripts/tiny_mce/themes/advanced/about.htm +62 -46
  368. data/vendor/assets/javascripts/tiny_mce/themes/advanced/anchor.htm +17 -16
  369. data/vendor/assets/javascripts/tiny_mce/themes/advanced/charmap.htm +56 -47
  370. data/vendor/assets/javascripts/tiny_mce/themes/advanced/color_picker.htm +67 -54
  371. data/vendor/assets/javascripts/tiny_mce/themes/advanced/editor_template.js +852 -1
  372. data/vendor/assets/javascripts/tiny_mce/themes/advanced/image.htm +79 -69
  373. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/about.js +48 -48
  374. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/anchor.js +28 -28
  375. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/charmap.js +317 -317
  376. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/color_picker.js +248 -246
  377. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/image.js +246 -246
  378. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/link.js +146 -146
  379. data/vendor/assets/javascripts/tiny_mce/themes/advanced/js/source_editor.js +31 -31
  380. data/vendor/assets/javascripts/tiny_mce/themes/advanced/langs/de.js +1 -1
  381. data/vendor/assets/javascripts/tiny_mce/themes/advanced/langs/de_dlg.js +1 -1
  382. data/vendor/assets/javascripts/tiny_mce/themes/advanced/langs/en.js +1 -1
  383. data/vendor/assets/javascripts/tiny_mce/themes/advanced/langs/en_dlg.js +1 -1
  384. data/vendor/assets/javascripts/tiny_mce/themes/advanced/link.htm +53 -46
  385. data/vendor/assets/javascripts/tiny_mce/themes/advanced/shortcuts.htm +57 -45
  386. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/default/content.css +182 -47
  387. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/default/dialog.css +399 -92
  388. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/default/ui.css +891 -187
  389. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/content.css +102 -24
  390. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/dialog.css +377 -78
  391. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/ui.css +452 -77
  392. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/content.css +167 -45
  393. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/dialog.css +399 -92
  394. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui.css +890 -190
  395. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_black.css +33 -7
  396. data/vendor/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css +15 -4
  397. data/vendor/assets/javascripts/tiny_mce/themes/advanced/source_editor.htm +18 -15
  398. data/vendor/assets/javascripts/tiny_mce/utils/editable_selects.js +46 -46
  399. data/vendor/assets/javascripts/tiny_mce/utils/form_utils.js +124 -124
  400. data/vendor/assets/javascripts/tiny_mce/utils/mctabs.js +112 -112
  401. data/vendor/assets/javascripts/tiny_mce/utils/validate.js +213 -213
  402. metadata +102 -115
  403. data/app/assets/javascripts/alchemy/alchemy.link_overlay.js +0 -216
  404. data/lib/tasks/routes.rake +0 -29
  405. data/spec/integration/admin/resources_spec.rb +0 -19
@@ -1,98 +1,98 @@
1
1
  /*
2
- Queue Plug-in
3
-
4
- Features:
5
- *Adds a cancelQueue() method for cancelling the entire queue.
6
- *All queued files are uploaded when startUpload() is called.
7
- *If false is returned from uploadComplete then the queue upload is stopped.
8
- If false is not returned (strict comparison) then the queue upload is continued.
9
- *Adds a QueueComplete event that is fired when all the queued files have finished uploading.
10
- Set the event handler with the queue_complete_handler setting.
11
-
12
- */
2
+ Queue Plug-in
3
+
4
+ Features:
5
+ *Adds a cancelQueue() method for cancelling the entire queue.
6
+ *All queued files are uploaded when startUpload() is called.
7
+ *If false is returned from uploadComplete then the queue upload is stopped.
8
+ If false is not returned (strict comparison) then the queue upload is continued.
9
+ *Adds a QueueComplete event that is fired when all the queued files have finished uploading.
10
+ Set the event handler with the queue_complete_handler setting.
11
+
12
+ */
13
13
 
14
14
  var SWFUpload;
15
15
  if (typeof(SWFUpload) === "function") {
16
- SWFUpload.queue = {};
17
-
18
- SWFUpload.prototype.initSettings = (function (oldInitSettings) {
19
- return function () {
20
- if (typeof(oldInitSettings) === "function") {
21
- oldInitSettings.call(this);
22
- }
23
-
24
- this.queueSettings = {};
25
-
26
- this.queueSettings.queue_cancelled_flag = false;
27
- this.queueSettings.queue_upload_count = 0;
28
-
29
- this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
30
- this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler;
31
- this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler;
32
- this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler;
33
-
34
- this.settings.queue_complete_handler = this.settings.queue_complete_handler || null;
35
- };
36
- })(SWFUpload.prototype.initSettings);
37
-
38
- SWFUpload.prototype.startUpload = function (fileID) {
39
- this.queueSettings.queue_cancelled_flag = false;
40
- this.callFlash("StartUpload", [fileID]);
41
- };
42
-
43
- SWFUpload.prototype.cancelQueue = function () {
44
- this.queueSettings.queue_cancelled_flag = true;
45
- this.stopUpload();
46
-
47
- var stats = this.getStats();
48
- while (stats.files_queued > 0) {
49
- this.cancelUpload();
50
- stats = this.getStats();
51
- }
52
- };
53
-
54
- SWFUpload.queue.uploadStartHandler = function (file) {
55
- var returnValue;
56
- if (typeof(this.queueSettings.user_upload_start_handler) === "function") {
57
- returnValue = this.queueSettings.user_upload_start_handler.call(this, file);
58
- }
59
-
60
- // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value.
61
- returnValue = (returnValue === false) ? false : true;
62
-
63
- this.queueSettings.queue_cancelled_flag = !returnValue;
64
-
65
- return returnValue;
66
- };
67
-
68
- SWFUpload.queue.uploadCompleteHandler = function (file) {
69
- var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler;
70
- var continueUpload;
71
-
72
- if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) {
73
- this.queueSettings.queue_upload_count++;
74
- }
75
-
76
- if (typeof(user_upload_complete_handler) === "function") {
77
- continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
78
- } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) {
79
- // If the file was stopped and re-queued don't restart the upload
80
- continueUpload = false;
81
- } else {
82
- continueUpload = true;
83
- }
84
-
85
- if (continueUpload) {
86
- var stats = this.getStats();
87
- if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) {
88
- this.startUpload();
89
- } else if (this.queueSettings.queue_cancelled_flag === false) {
90
- this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]);
91
- this.queueSettings.queue_upload_count = 0;
92
- } else {
93
- this.queueSettings.queue_cancelled_flag = false;
94
- this.queueSettings.queue_upload_count = 0;
95
- }
96
- }
97
- };
16
+ SWFUpload.queue = {};
17
+
18
+ SWFUpload.prototype.initSettings = (function (oldInitSettings) {
19
+ return function () {
20
+ if (typeof(oldInitSettings) === "function") {
21
+ oldInitSettings.call(this);
22
+ }
23
+
24
+ this.queueSettings = {};
25
+
26
+ this.queueSettings.queue_cancelled_flag = false;
27
+ this.queueSettings.queue_upload_count = 0;
28
+
29
+ this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
30
+ this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler;
31
+ this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler;
32
+ this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler;
33
+
34
+ this.settings.queue_complete_handler = this.settings.queue_complete_handler || null;
35
+ };
36
+ })(SWFUpload.prototype.initSettings);
37
+
38
+ SWFUpload.prototype.startUpload = function (fileID) {
39
+ this.queueSettings.queue_cancelled_flag = false;
40
+ this.callFlash("StartUpload", [fileID]);
41
+ };
42
+
43
+ SWFUpload.prototype.cancelQueue = function () {
44
+ this.queueSettings.queue_cancelled_flag = true;
45
+ this.stopUpload();
46
+
47
+ var stats = this.getStats();
48
+ while (stats.files_queued > 0) {
49
+ this.cancelUpload();
50
+ stats = this.getStats();
51
+ }
52
+ };
53
+
54
+ SWFUpload.queue.uploadStartHandler = function (file) {
55
+ var returnValue;
56
+ if (typeof(this.queueSettings.user_upload_start_handler) === "function") {
57
+ returnValue = this.queueSettings.user_upload_start_handler.call(this, file);
58
+ }
59
+
60
+ // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value.
61
+ returnValue = (returnValue === false) ? false : true;
62
+
63
+ this.queueSettings.queue_cancelled_flag = !returnValue;
64
+
65
+ return returnValue;
66
+ };
67
+
68
+ SWFUpload.queue.uploadCompleteHandler = function (file) {
69
+ var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler;
70
+ var continueUpload;
71
+
72
+ if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) {
73
+ this.queueSettings.queue_upload_count++;
74
+ }
75
+
76
+ if (typeof(user_upload_complete_handler) === "function") {
77
+ continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
78
+ } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) {
79
+ // If the file was stopped and re-queued don't restart the upload
80
+ continueUpload = false;
81
+ } else {
82
+ continueUpload = true;
83
+ }
84
+
85
+ if (continueUpload) {
86
+ var stats = this.getStats();
87
+ if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) {
88
+ this.startUpload();
89
+ } else if (this.queueSettings.queue_cancelled_flag === false) {
90
+ this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]);
91
+ this.queueSettings.queue_upload_count = 0;
92
+ } else {
93
+ this.queueSettings.queue_cancelled_flag = false;
94
+ this.queueSettings.queue_upload_count = 0;
95
+ }
96
+ }
97
+ };
98
98
  }
@@ -1,342 +1,342 @@
1
1
  /*
2
- Speed Plug-in
3
-
4
- Features:
5
- *Adds several properties to the 'file' object indicated upload speed, time left, upload time, etc.
6
- - currentSpeed -- String indicating the upload speed, bytes per second
7
- - averageSpeed -- Overall average upload speed, bytes per second
8
- - movingAverageSpeed -- Speed over averaged over the last several measurements, bytes per second
9
- - timeRemaining -- Estimated remaining upload time in seconds
10
- - timeElapsed -- Number of seconds passed for this upload
11
- - percentUploaded -- Percentage of the file uploaded (0 to 100)
12
- - sizeUploaded -- Formatted size uploaded so far, bytes
13
-
14
- *Adds setting 'moving_average_history_size' for defining the window size used to calculate the moving average speed.
15
-
16
- *Adds several Formatting functions for formatting that values provided on the file object.
17
- - SWFUpload.speed.formatBPS(bps) -- outputs string formatted in the best units (Gbps, Mbps, Kbps, bps)
18
- - SWFUpload.speed.formatTime(seconds) -- outputs string formatted in the best units (x Hr y M z S)
19
- - SWFUpload.speed.formatSize(bytes) -- outputs string formatted in the best units (w GB x MB y KB z B )
20
- - SWFUpload.speed.formatPercent(percent) -- outputs string formatted with a percent sign (x.xx %)
21
- - SWFUpload.speed.formatUnits(baseNumber, divisionArray, unitLabelArray, fractionalBoolean)
22
- - Formats a number using the division array to determine how to apply the labels in the Label Array
23
- - factionalBoolean indicates whether the number should be returned as a single fractional number with a unit (speed)
24
- or as several numbers labeled with units (time)
25
- */
2
+ Speed Plug-in
3
+
4
+ Features:
5
+ *Adds several properties to the 'file' object indicated upload speed, time left, upload time, etc.
6
+ - currentSpeed -- String indicating the upload speed, bytes per second
7
+ - averageSpeed -- Overall average upload speed, bytes per second
8
+ - movingAverageSpeed -- Speed over averaged over the last several measurements, bytes per second
9
+ - timeRemaining -- Estimated remaining upload time in seconds
10
+ - timeElapsed -- Number of seconds passed for this upload
11
+ - percentUploaded -- Percentage of the file uploaded (0 to 100)
12
+ - sizeUploaded -- Formatted size uploaded so far, bytes
13
+
14
+ *Adds setting 'moving_average_history_size' for defining the window size used to calculate the moving average speed.
15
+
16
+ *Adds several Formatting functions for formatting that values provided on the file object.
17
+ - SWFUpload.speed.formatBPS(bps) -- outputs string formatted in the best units (Gbps, Mbps, Kbps, bps)
18
+ - SWFUpload.speed.formatTime(seconds) -- outputs string formatted in the best units (x Hr y M z S)
19
+ - SWFUpload.speed.formatSize(bytes) -- outputs string formatted in the best units (w GB x MB y KB z B )
20
+ - SWFUpload.speed.formatPercent(percent) -- outputs string formatted with a percent sign (x.xx %)
21
+ - SWFUpload.speed.formatUnits(baseNumber, divisionArray, unitLabelArray, fractionalBoolean)
22
+ - Formats a number using the division array to determine how to apply the labels in the Label Array
23
+ - factionalBoolean indicates whether the number should be returned as a single fractional number with a unit (speed)
24
+ or as several numbers labeled with units (time)
25
+ */
26
26
 
27
27
  var SWFUpload;
28
28
  if (typeof(SWFUpload) === "function") {
29
- SWFUpload.speed = {};
30
-
31
- SWFUpload.prototype.initSettings = (function (oldInitSettings) {
32
- return function () {
33
- if (typeof(oldInitSettings) === "function") {
34
- oldInitSettings.call(this);
35
- }
36
-
37
- this.ensureDefault = function (settingName, defaultValue) {
38
- this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
39
- };
40
-
41
- // List used to keep the speed stats for the files we are tracking
42
- this.fileSpeedStats = {};
43
- this.speedSettings = {};
44
-
45
- this.ensureDefault("moving_average_history_size", "10");
46
-
47
- this.speedSettings.user_file_queued_handler = this.settings.file_queued_handler;
48
- this.speedSettings.user_file_queue_error_handler = this.settings.file_queue_error_handler;
49
- this.speedSettings.user_upload_start_handler = this.settings.upload_start_handler;
50
- this.speedSettings.user_upload_error_handler = this.settings.upload_error_handler;
51
- this.speedSettings.user_upload_progress_handler = this.settings.upload_progress_handler;
52
- this.speedSettings.user_upload_success_handler = this.settings.upload_success_handler;
53
- this.speedSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
54
-
55
- this.settings.file_queued_handler = SWFUpload.speed.fileQueuedHandler;
56
- this.settings.file_queue_error_handler = SWFUpload.speed.fileQueueErrorHandler;
57
- this.settings.upload_start_handler = SWFUpload.speed.uploadStartHandler;
58
- this.settings.upload_error_handler = SWFUpload.speed.uploadErrorHandler;
59
- this.settings.upload_progress_handler = SWFUpload.speed.uploadProgressHandler;
60
- this.settings.upload_success_handler = SWFUpload.speed.uploadSuccessHandler;
61
- this.settings.upload_complete_handler = SWFUpload.speed.uploadCompleteHandler;
62
-
63
- delete this.ensureDefault;
64
- };
65
- })(SWFUpload.prototype.initSettings);
66
-
67
-
68
- SWFUpload.speed.fileQueuedHandler = function (file) {
69
- if (typeof this.speedSettings.user_file_queued_handler === "function") {
70
- file = SWFUpload.speed.extendFile(file);
71
-
72
- return this.speedSettings.user_file_queued_handler.call(this, file);
73
- }
74
- };
75
-
76
- SWFUpload.speed.fileQueueErrorHandler = function (file, errorCode, message) {
77
- if (typeof this.speedSettings.user_file_queue_error_handler === "function") {
78
- file = SWFUpload.speed.extendFile(file);
79
-
80
- return this.speedSettings.user_file_queue_error_handler.call(this, file, errorCode, message);
81
- }
82
- };
83
-
84
- SWFUpload.speed.uploadStartHandler = function (file) {
85
- if (typeof this.speedSettings.user_upload_start_handler === "function") {
86
- file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
87
- return this.speedSettings.user_upload_start_handler.call(this, file);
88
- }
89
- };
90
-
91
- SWFUpload.speed.uploadErrorHandler = function (file, errorCode, message) {
92
- file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
93
- SWFUpload.speed.removeTracking(file, this.fileSpeedStats);
94
-
95
- if (typeof this.speedSettings.user_upload_error_handler === "function") {
96
- return this.speedSettings.user_upload_error_handler.call(this, file, errorCode, message);
97
- }
98
- };
99
- SWFUpload.speed.uploadProgressHandler = function (file, bytesComplete, bytesTotal) {
100
- this.updateTracking(file, bytesComplete);
101
- file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
102
-
103
- if (typeof this.speedSettings.user_upload_progress_handler === "function") {
104
- return this.speedSettings.user_upload_progress_handler.call(this, file, bytesComplete, bytesTotal);
105
- }
106
- };
107
-
108
- SWFUpload.speed.uploadSuccessHandler = function (file, serverData) {
109
- if (typeof this.speedSettings.user_upload_success_handler === "function") {
110
- file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
111
- return this.speedSettings.user_upload_success_handler.call(this, file, serverData);
112
- }
113
- };
114
- SWFUpload.speed.uploadCompleteHandler = function (file) {
115
- file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
116
- SWFUpload.speed.removeTracking(file, this.fileSpeedStats);
117
-
118
- if (typeof this.speedSettings.user_upload_complete_handler === "function") {
119
- return this.speedSettings.user_upload_complete_handler.call(this, file);
120
- }
121
- };
122
-
123
- // Private: extends the file object with the speed plugin values
124
- SWFUpload.speed.extendFile = function (file, trackingList) {
125
- var tracking;
126
-
127
- if (trackingList) {
128
- tracking = trackingList[file.id];
129
- }
130
-
131
- if (tracking) {
132
- file.currentSpeed = tracking.currentSpeed;
133
- file.averageSpeed = tracking.averageSpeed;
134
- file.movingAverageSpeed = tracking.movingAverageSpeed;
135
- file.timeRemaining = tracking.timeRemaining;
136
- file.timeElapsed = tracking.timeElapsed;
137
- file.percentUploaded = tracking.percentUploaded;
138
- file.sizeUploaded = tracking.bytesUploaded;
139
-
140
- } else {
141
- file.currentSpeed = 0;
142
- file.averageSpeed = 0;
143
- file.movingAverageSpeed = 0;
144
- file.timeRemaining = 0;
145
- file.timeElapsed = 0;
146
- file.percentUploaded = 0;
147
- file.sizeUploaded = 0;
148
- }
149
-
150
- return file;
151
- };
152
-
153
- // Private: Updates the speed tracking object, or creates it if necessary
154
- SWFUpload.prototype.updateTracking = function (file, bytesUploaded) {
155
- var tracking = this.fileSpeedStats[file.id];
156
- if (!tracking) {
157
- this.fileSpeedStats[file.id] = tracking = {};
158
- }
159
-
160
- // Sanity check inputs
161
- bytesUploaded = bytesUploaded || tracking.bytesUploaded || 0;
162
- if (bytesUploaded < 0) {
163
- bytesUploaded = 0;
164
- }
165
- if (bytesUploaded > file.size) {
166
- bytesUploaded = file.size;
167
- }
168
-
169
- var tickTime = (new Date()).getTime();
170
- if (!tracking.startTime) {
171
- tracking.startTime = (new Date()).getTime();
172
- tracking.lastTime = tracking.startTime;
173
- tracking.currentSpeed = 0;
174
- tracking.averageSpeed = 0;
175
- tracking.movingAverageSpeed = 0;
176
- tracking.movingAverageHistory = [];
177
- tracking.timeRemaining = 0;
178
- tracking.timeElapsed = 0;
179
- tracking.percentUploaded = bytesUploaded / file.size;
180
- tracking.bytesUploaded = bytesUploaded;
181
- } else if (tracking.startTime > tickTime) {
182
- this.debug("When backwards in time");
183
- } else {
184
- // Get time and deltas
185
- var now = (new Date()).getTime();
186
- var lastTime = tracking.lastTime;
187
- var deltaTime = now - lastTime;
188
- var deltaBytes = bytesUploaded - tracking.bytesUploaded;
189
-
190
- if (deltaBytes === 0 || deltaTime === 0) {
191
- return tracking;
192
- }
193
-
194
- // Update tracking object
195
- tracking.lastTime = now;
196
- tracking.bytesUploaded = bytesUploaded;
197
-
198
- // Calculate speeds
199
- tracking.currentSpeed = (deltaBytes * 8 ) / (deltaTime / 1000);
200
- tracking.averageSpeed = (tracking.bytesUploaded * 8) / ((now - tracking.startTime) / 1000);
201
-
202
- // Calculate moving average
203
- tracking.movingAverageHistory.push(tracking.currentSpeed);
204
- if (tracking.movingAverageHistory.length > this.settings.moving_average_history_size) {
205
- tracking.movingAverageHistory.shift();
206
- }
207
-
208
- tracking.movingAverageSpeed = SWFUpload.speed.calculateMovingAverage(tracking.movingAverageHistory);
209
-
210
- // Update times
211
- tracking.timeRemaining = (file.size - tracking.bytesUploaded) * 8 / tracking.movingAverageSpeed;
212
- tracking.timeElapsed = (now - tracking.startTime) / 1000;
213
-
214
- // Update percent
215
- tracking.percentUploaded = (tracking.bytesUploaded / file.size * 100);
216
- }
217
-
218
- return tracking;
219
- };
220
- SWFUpload.speed.removeTracking = function (file, trackingList) {
221
- try {
222
- trackingList[file.id] = null;
223
- delete trackingList[file.id];
224
- } catch (ex) {
225
- }
226
- };
227
-
228
- SWFUpload.speed.formatUnits = function (baseNumber, unitDivisors, unitLabels, singleFractional) {
229
- var i, unit, unitDivisor, unitLabel;
230
-
231
- if (baseNumber === 0) {
232
- return "0 " + unitLabels[unitLabels.length - 1];
233
- }
234
-
235
- if (singleFractional) {
236
- unit = baseNumber;
237
- unitLabel = unitLabels.length >= unitDivisors.length ? unitLabels[unitDivisors.length - 1] : "";
238
- for (i = 0; i < unitDivisors.length; i++) {
239
- if (baseNumber >= unitDivisors[i]) {
240
- unit = (baseNumber / unitDivisors[i]).toFixed(2);
241
- unitLabel = unitLabels.length >= i ? " " + unitLabels[i] : "";
242
- break;
243
- }
244
- }
245
-
246
- return unit + unitLabel;
247
- } else {
248
- var formattedStrings = [];
249
- var remainder = baseNumber;
250
-
251
- for (i = 0; i < unitDivisors.length; i++) {
252
- unitDivisor = unitDivisors[i];
253
- unitLabel = unitLabels.length > i ? " " + unitLabels[i] : "";
254
-
255
- unit = remainder / unitDivisor;
256
- if (i < unitDivisors.length -1) {
257
- unit = Math.floor(unit);
258
- } else {
259
- unit = unit.toFixed(2);
260
- }
261
- if (unit > 0) {
262
- remainder = remainder % unitDivisor;
263
-
264
- formattedStrings.push(unit + unitLabel);
265
- }
266
- }
267
-
268
- return formattedStrings.join(" ");
269
- }
270
- };
271
-
272
- SWFUpload.speed.formatBPS = function (baseNumber) {
273
- var bpsUnits = [1073741824, 1048576, 1024, 1], bpsUnitLabels = ["Gbps", "Mbps", "Kbps", "bps"];
274
- return SWFUpload.speed.formatUnits(baseNumber, bpsUnits, bpsUnitLabels, true);
275
-
276
- };
277
- SWFUpload.speed.formatTime = function (baseNumber) {
278
- var timeUnits = [86400, 3600, 60, 1], timeUnitLabels = ["d", "h", "m", "s"];
279
- return SWFUpload.speed.formatUnits(baseNumber, timeUnits, timeUnitLabels, false);
280
-
281
- };
282
- SWFUpload.speed.formatBytes = function (baseNumber) {
283
- var sizeUnits = [1073741824, 1048576, 1024, 1], sizeUnitLabels = ["GB", "MB", "KB", "bytes"];
284
- return SWFUpload.speed.formatUnits(baseNumber, sizeUnits, sizeUnitLabels, true);
285
-
286
- };
287
- SWFUpload.speed.formatPercent = function (baseNumber) {
288
- return baseNumber.toFixed(2) + " %";
289
- };
290
-
291
- SWFUpload.speed.calculateMovingAverage = function (history) {
292
- var vals = [], size, sum = 0.0, mean = 0.0, varianceTemp = 0.0, variance = 0.0, standardDev = 0.0;
293
- var i;
294
- var mSum = 0, mCount = 0;
295
-
296
- size = history.length;
297
-
298
- // Check for sufficient data
299
- if (size >= 8) {
300
- // Clone the array and Calculate sum of the values
301
- for (i = 0; i < size; i++) {
302
- vals[i] = history[i];
303
- sum += vals[i];
304
- }
305
-
306
- mean = sum / size;
307
-
308
- // Calculate variance for the set
309
- for (i = 0; i < size; i++) {
310
- varianceTemp += Math.pow((vals[i] - mean), 2);
311
- }
312
-
313
- variance = varianceTemp / size;
314
- standardDev = Math.sqrt(variance);
315
-
316
- //Standardize the Data
317
- for (i = 0; i < size; i++) {
318
- vals[i] = (vals[i] - mean) / standardDev;
319
- }
320
-
321
- // Calculate the average excluding outliers
322
- var deviationRange = 2.0;
323
- for (i = 0; i < size; i++) {
324
-
325
- if (vals[i] <= deviationRange && vals[i] >= -deviationRange) {
326
- mCount++;
327
- mSum += history[i];
328
- }
329
- }
330
-
331
- } else {
332
- // Calculate the average (not enough data points to remove outliers)
333
- mCount = size;
334
- for (i = 0; i < size; i++) {
335
- mSum += history[i];
336
- }
337
- }
338
-
339
- return mSum / mCount;
340
- };
341
-
29
+ SWFUpload.speed = {};
30
+
31
+ SWFUpload.prototype.initSettings = (function (oldInitSettings) {
32
+ return function () {
33
+ if (typeof(oldInitSettings) === "function") {
34
+ oldInitSettings.call(this);
35
+ }
36
+
37
+ this.ensureDefault = function (settingName, defaultValue) {
38
+ this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
39
+ };
40
+
41
+ // List used to keep the speed stats for the files we are tracking
42
+ this.fileSpeedStats = {};
43
+ this.speedSettings = {};
44
+
45
+ this.ensureDefault("moving_average_history_size", "10");
46
+
47
+ this.speedSettings.user_file_queued_handler = this.settings.file_queued_handler;
48
+ this.speedSettings.user_file_queue_error_handler = this.settings.file_queue_error_handler;
49
+ this.speedSettings.user_upload_start_handler = this.settings.upload_start_handler;
50
+ this.speedSettings.user_upload_error_handler = this.settings.upload_error_handler;
51
+ this.speedSettings.user_upload_progress_handler = this.settings.upload_progress_handler;
52
+ this.speedSettings.user_upload_success_handler = this.settings.upload_success_handler;
53
+ this.speedSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
54
+
55
+ this.settings.file_queued_handler = SWFUpload.speed.fileQueuedHandler;
56
+ this.settings.file_queue_error_handler = SWFUpload.speed.fileQueueErrorHandler;
57
+ this.settings.upload_start_handler = SWFUpload.speed.uploadStartHandler;
58
+ this.settings.upload_error_handler = SWFUpload.speed.uploadErrorHandler;
59
+ this.settings.upload_progress_handler = SWFUpload.speed.uploadProgressHandler;
60
+ this.settings.upload_success_handler = SWFUpload.speed.uploadSuccessHandler;
61
+ this.settings.upload_complete_handler = SWFUpload.speed.uploadCompleteHandler;
62
+
63
+ delete this.ensureDefault;
64
+ };
65
+ })(SWFUpload.prototype.initSettings);
66
+
67
+
68
+ SWFUpload.speed.fileQueuedHandler = function (file) {
69
+ if (typeof this.speedSettings.user_file_queued_handler === "function") {
70
+ file = SWFUpload.speed.extendFile(file);
71
+
72
+ return this.speedSettings.user_file_queued_handler.call(this, file);
73
+ }
74
+ };
75
+
76
+ SWFUpload.speed.fileQueueErrorHandler = function (file, errorCode, message) {
77
+ if (typeof this.speedSettings.user_file_queue_error_handler === "function") {
78
+ file = SWFUpload.speed.extendFile(file);
79
+
80
+ return this.speedSettings.user_file_queue_error_handler.call(this, file, errorCode, message);
81
+ }
82
+ };
83
+
84
+ SWFUpload.speed.uploadStartHandler = function (file) {
85
+ if (typeof this.speedSettings.user_upload_start_handler === "function") {
86
+ file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
87
+ return this.speedSettings.user_upload_start_handler.call(this, file);
88
+ }
89
+ };
90
+
91
+ SWFUpload.speed.uploadErrorHandler = function (file, errorCode, message) {
92
+ file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
93
+ SWFUpload.speed.removeTracking(file, this.fileSpeedStats);
94
+
95
+ if (typeof this.speedSettings.user_upload_error_handler === "function") {
96
+ return this.speedSettings.user_upload_error_handler.call(this, file, errorCode, message);
97
+ }
98
+ };
99
+ SWFUpload.speed.uploadProgressHandler = function (file, bytesComplete, bytesTotal) {
100
+ this.updateTracking(file, bytesComplete);
101
+ file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
102
+
103
+ if (typeof this.speedSettings.user_upload_progress_handler === "function") {
104
+ return this.speedSettings.user_upload_progress_handler.call(this, file, bytesComplete, bytesTotal);
105
+ }
106
+ };
107
+
108
+ SWFUpload.speed.uploadSuccessHandler = function (file, serverData) {
109
+ if (typeof this.speedSettings.user_upload_success_handler === "function") {
110
+ file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
111
+ return this.speedSettings.user_upload_success_handler.call(this, file, serverData);
112
+ }
113
+ };
114
+ SWFUpload.speed.uploadCompleteHandler = function (file) {
115
+ file = SWFUpload.speed.extendFile(file, this.fileSpeedStats);
116
+ SWFUpload.speed.removeTracking(file, this.fileSpeedStats);
117
+
118
+ if (typeof this.speedSettings.user_upload_complete_handler === "function") {
119
+ return this.speedSettings.user_upload_complete_handler.call(this, file);
120
+ }
121
+ };
122
+
123
+ // Private: extends the file object with the speed plugin values
124
+ SWFUpload.speed.extendFile = function (file, trackingList) {
125
+ var tracking;
126
+
127
+ if (trackingList) {
128
+ tracking = trackingList[file.id];
129
+ }
130
+
131
+ if (tracking) {
132
+ file.currentSpeed = tracking.currentSpeed;
133
+ file.averageSpeed = tracking.averageSpeed;
134
+ file.movingAverageSpeed = tracking.movingAverageSpeed;
135
+ file.timeRemaining = tracking.timeRemaining;
136
+ file.timeElapsed = tracking.timeElapsed;
137
+ file.percentUploaded = tracking.percentUploaded;
138
+ file.sizeUploaded = tracking.bytesUploaded;
139
+
140
+ } else {
141
+ file.currentSpeed = 0;
142
+ file.averageSpeed = 0;
143
+ file.movingAverageSpeed = 0;
144
+ file.timeRemaining = 0;
145
+ file.timeElapsed = 0;
146
+ file.percentUploaded = 0;
147
+ file.sizeUploaded = 0;
148
+ }
149
+
150
+ return file;
151
+ };
152
+
153
+ // Private: Updates the speed tracking object, or creates it if necessary
154
+ SWFUpload.prototype.updateTracking = function (file, bytesUploaded) {
155
+ var tracking = this.fileSpeedStats[file.id];
156
+ if (!tracking) {
157
+ this.fileSpeedStats[file.id] = tracking = {};
158
+ }
159
+
160
+ // Sanity check inputs
161
+ bytesUploaded = bytesUploaded || tracking.bytesUploaded || 0;
162
+ if (bytesUploaded < 0) {
163
+ bytesUploaded = 0;
164
+ }
165
+ if (bytesUploaded > file.size) {
166
+ bytesUploaded = file.size;
167
+ }
168
+
169
+ var tickTime = (new Date()).getTime();
170
+ if (!tracking.startTime) {
171
+ tracking.startTime = (new Date()).getTime();
172
+ tracking.lastTime = tracking.startTime;
173
+ tracking.currentSpeed = 0;
174
+ tracking.averageSpeed = 0;
175
+ tracking.movingAverageSpeed = 0;
176
+ tracking.movingAverageHistory = [];
177
+ tracking.timeRemaining = 0;
178
+ tracking.timeElapsed = 0;
179
+ tracking.percentUploaded = bytesUploaded / file.size;
180
+ tracking.bytesUploaded = bytesUploaded;
181
+ } else if (tracking.startTime > tickTime) {
182
+ this.debug("When backwards in time");
183
+ } else {
184
+ // Get time and deltas
185
+ var now = (new Date()).getTime();
186
+ var lastTime = tracking.lastTime;
187
+ var deltaTime = now - lastTime;
188
+ var deltaBytes = bytesUploaded - tracking.bytesUploaded;
189
+
190
+ if (deltaBytes === 0 || deltaTime === 0) {
191
+ return tracking;
192
+ }
193
+
194
+ // Update tracking object
195
+ tracking.lastTime = now;
196
+ tracking.bytesUploaded = bytesUploaded;
197
+
198
+ // Calculate speeds
199
+ tracking.currentSpeed = (deltaBytes * 8 ) / (deltaTime / 1000);
200
+ tracking.averageSpeed = (tracking.bytesUploaded * 8) / ((now - tracking.startTime) / 1000);
201
+
202
+ // Calculate moving average
203
+ tracking.movingAverageHistory.push(tracking.currentSpeed);
204
+ if (tracking.movingAverageHistory.length > this.settings.moving_average_history_size) {
205
+ tracking.movingAverageHistory.shift();
206
+ }
207
+
208
+ tracking.movingAverageSpeed = SWFUpload.speed.calculateMovingAverage(tracking.movingAverageHistory);
209
+
210
+ // Update times
211
+ tracking.timeRemaining = (file.size - tracking.bytesUploaded) * 8 / tracking.movingAverageSpeed;
212
+ tracking.timeElapsed = (now - tracking.startTime) / 1000;
213
+
214
+ // Update percent
215
+ tracking.percentUploaded = (tracking.bytesUploaded / file.size * 100);
216
+ }
217
+
218
+ return tracking;
219
+ };
220
+ SWFUpload.speed.removeTracking = function (file, trackingList) {
221
+ try {
222
+ trackingList[file.id] = null;
223
+ delete trackingList[file.id];
224
+ } catch (ex) {
225
+ }
226
+ };
227
+
228
+ SWFUpload.speed.formatUnits = function (baseNumber, unitDivisors, unitLabels, singleFractional) {
229
+ var i, unit, unitDivisor, unitLabel;
230
+
231
+ if (baseNumber === 0) {
232
+ return "0 " + unitLabels[unitLabels.length - 1];
233
+ }
234
+
235
+ if (singleFractional) {
236
+ unit = baseNumber;
237
+ unitLabel = unitLabels.length >= unitDivisors.length ? unitLabels[unitDivisors.length - 1] : "";
238
+ for (i = 0; i < unitDivisors.length; i++) {
239
+ if (baseNumber >= unitDivisors[i]) {
240
+ unit = (baseNumber / unitDivisors[i]).toFixed(2);
241
+ unitLabel = unitLabels.length >= i ? " " + unitLabels[i] : "";
242
+ break;
243
+ }
244
+ }
245
+
246
+ return unit + unitLabel;
247
+ } else {
248
+ var formattedStrings = [];
249
+ var remainder = baseNumber;
250
+
251
+ for (i = 0; i < unitDivisors.length; i++) {
252
+ unitDivisor = unitDivisors[i];
253
+ unitLabel = unitLabels.length > i ? " " + unitLabels[i] : "";
254
+
255
+ unit = remainder / unitDivisor;
256
+ if (i < unitDivisors.length - 1) {
257
+ unit = Math.floor(unit);
258
+ } else {
259
+ unit = unit.toFixed(2);
260
+ }
261
+ if (unit > 0) {
262
+ remainder = remainder % unitDivisor;
263
+
264
+ formattedStrings.push(unit + unitLabel);
265
+ }
266
+ }
267
+
268
+ return formattedStrings.join(" ");
269
+ }
270
+ };
271
+
272
+ SWFUpload.speed.formatBPS = function (baseNumber) {
273
+ var bpsUnits = [1073741824, 1048576, 1024, 1], bpsUnitLabels = ["Gbps", "Mbps", "Kbps", "bps"];
274
+ return SWFUpload.speed.formatUnits(baseNumber, bpsUnits, bpsUnitLabels, true);
275
+
276
+ };
277
+ SWFUpload.speed.formatTime = function (baseNumber) {
278
+ var timeUnits = [86400, 3600, 60, 1], timeUnitLabels = ["d", "h", "m", "s"];
279
+ return SWFUpload.speed.formatUnits(baseNumber, timeUnits, timeUnitLabels, false);
280
+
281
+ };
282
+ SWFUpload.speed.formatBytes = function (baseNumber) {
283
+ var sizeUnits = [1073741824, 1048576, 1024, 1], sizeUnitLabels = ["GB", "MB", "KB", "bytes"];
284
+ return SWFUpload.speed.formatUnits(baseNumber, sizeUnits, sizeUnitLabels, true);
285
+
286
+ };
287
+ SWFUpload.speed.formatPercent = function (baseNumber) {
288
+ return baseNumber.toFixed(2) + " %";
289
+ };
290
+
291
+ SWFUpload.speed.calculateMovingAverage = function (history) {
292
+ var vals = [], size, sum = 0.0, mean = 0.0, varianceTemp = 0.0, variance = 0.0, standardDev = 0.0;
293
+ var i;
294
+ var mSum = 0, mCount = 0;
295
+
296
+ size = history.length;
297
+
298
+ // Check for sufficient data
299
+ if (size >= 8) {
300
+ // Clone the array and Calculate sum of the values
301
+ for (i = 0; i < size; i++) {
302
+ vals[i] = history[i];
303
+ sum += vals[i];
304
+ }
305
+
306
+ mean = sum / size;
307
+
308
+ // Calculate variance for the set
309
+ for (i = 0; i < size; i++) {
310
+ varianceTemp += Math.pow((vals[i] - mean), 2);
311
+ }
312
+
313
+ variance = varianceTemp / size;
314
+ standardDev = Math.sqrt(variance);
315
+
316
+ //Standardize the Data
317
+ for (i = 0; i < size; i++) {
318
+ vals[i] = (vals[i] - mean) / standardDev;
319
+ }
320
+
321
+ // Calculate the average excluding outliers
322
+ var deviationRange = 2.0;
323
+ for (i = 0; i < size; i++) {
324
+
325
+ if (vals[i] <= deviationRange && vals[i] >= -deviationRange) {
326
+ mCount++;
327
+ mSum += history[i];
328
+ }
329
+ }
330
+
331
+ } else {
332
+ // Calculate the average (not enough data points to remove outliers)
333
+ mCount = size;
334
+ for (i = 0; i < size; i++) {
335
+ mSum += history[i];
336
+ }
337
+ }
338
+
339
+ return mSum / mCount;
340
+ };
341
+
342
342
  }