yodel_admin 0.0.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 (321) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +1 -0
  4. data/lib/layouts/admin_list_record.html +94 -0
  5. data/lib/layouts/admin_login.html +131 -0
  6. data/lib/layouts/admin_page/admin_list_page.html +55 -0
  7. data/lib/layouts/admin_page/admin_settings_page.html +34 -0
  8. data/lib/layouts/admin_page/admin_tree_page.html +51 -0
  9. data/lib/layouts/admin_page.html +56 -0
  10. data/lib/layouts/admin_record_form.html +74 -0
  11. data/lib/migrations/01_admin_pages.rb +99 -0
  12. data/lib/migrations/02_admin_default_pages.rb +98 -0
  13. data/lib/models/admin_editor_page.rb +27 -0
  14. data/lib/models/admin_list_page.rb +121 -0
  15. data/lib/models/admin_root_page.rb +9 -0
  16. data/lib/models/admin_settings_page.rb +20 -0
  17. data/lib/models/admin_sync_page.rb +82 -0
  18. data/lib/models/admin_tree_page.rb +141 -0
  19. data/lib/public/admin/chosen/chosen-sprite.png +0 -0
  20. data/lib/public/admin/chosen/chosen.css +340 -0
  21. data/lib/public/admin/chosen/chosen.jquery.min.js +10 -0
  22. data/lib/public/admin/css/admin.css +1086 -0
  23. data/lib/public/admin/css/reset.css +48 -0
  24. data/lib/public/admin/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  25. data/lib/public/admin/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  26. data/lib/public/admin/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  27. data/lib/public/admin/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  28. data/lib/public/admin/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  29. data/lib/public/admin/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  30. data/lib/public/admin/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  31. data/lib/public/admin/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  32. data/lib/public/admin/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  33. data/lib/public/admin/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  34. data/lib/public/admin/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  35. data/lib/public/admin/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  36. data/lib/public/admin/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  37. data/lib/public/admin/css/smoothness/jquery-ui-1.8.16.custom.css +380 -0
  38. data/lib/public/admin/images/add.png +0 -0
  39. data/lib/public/admin/images/clock.png +0 -0
  40. data/lib/public/admin/images/close.png +0 -0
  41. data/lib/public/admin/images/cross.png +0 -0
  42. data/lib/public/admin/images/default_icon.png +0 -0
  43. data/lib/public/admin/images/delete.png +0 -0
  44. data/lib/public/admin/images/deploy_spinner.gif +0 -0
  45. data/lib/public/admin/images/drag.png +0 -0
  46. data/lib/public/admin/images/group_icon.png +0 -0
  47. data/lib/public/admin/images/left_arrow.png +0 -0
  48. data/lib/public/admin/images/load_spinner.gif +0 -0
  49. data/lib/public/admin/images/load_spinner_selected.gif +0 -0
  50. data/lib/public/admin/images/missing_image.png +0 -0
  51. data/lib/public/admin/images/new.png +0 -0
  52. data/lib/public/admin/images/open.png +0 -0
  53. data/lib/public/admin/images/right_arrow.png +0 -0
  54. data/lib/public/admin/images/save_spinner.gif +0 -0
  55. data/lib/public/admin/images/search.png +0 -0
  56. data/lib/public/admin/images/tick.png +0 -0
  57. data/lib/public/admin/images/user_icon.png +0 -0
  58. data/lib/public/admin/images/yodel.png +0 -0
  59. data/lib/public/admin/js/admin.js +1030 -0
  60. data/lib/public/admin/js/jquery-ui-1.8.16.custom.min.js +227 -0
  61. data/lib/public/admin/js/jquery.min.js +18 -0
  62. data/lib/public/admin/js/jquery.tablesorter.min.js +4 -0
  63. data/lib/public/admin/js/json2.js +480 -0
  64. data/lib/public/admin/js/yodel_jquery.js +241 -0
  65. data/lib/public/admin/tiny_mce/jquery.tinymce.js +338 -0
  66. data/lib/public/admin/tiny_mce/langs/en.js +223 -0
  67. data/lib/public/admin/tiny_mce/license.txt +504 -0
  68. data/lib/public/admin/tiny_mce/plugins/advhr/css/advhr.css +5 -0
  69. data/lib/public/admin/tiny_mce/plugins/advhr/editor_plugin.js +1 -0
  70. data/lib/public/admin/tiny_mce/plugins/advhr/editor_plugin_src.js +57 -0
  71. data/lib/public/admin/tiny_mce/plugins/advhr/js/rule.js +43 -0
  72. data/lib/public/admin/tiny_mce/plugins/advhr/langs/en_dlg.js +7 -0
  73. data/lib/public/admin/tiny_mce/plugins/advhr/rule.htm +58 -0
  74. data/lib/public/admin/tiny_mce/plugins/advimage/css/advimage.css +13 -0
  75. data/lib/public/admin/tiny_mce/plugins/advimage/editor_plugin.js +1 -0
  76. data/lib/public/admin/tiny_mce/plugins/advimage/editor_plugin_src.js +50 -0
  77. data/lib/public/admin/tiny_mce/plugins/advimage/image.htm +235 -0
  78. data/lib/public/admin/tiny_mce/plugins/advimage/img/sample.gif +0 -0
  79. data/lib/public/admin/tiny_mce/plugins/advimage/js/image.js +458 -0
  80. data/lib/public/admin/tiny_mce/plugins/advimage/langs/en_dlg.js +45 -0
  81. data/lib/public/admin/tiny_mce/plugins/advlink/css/advlink.css +8 -0
  82. data/lib/public/admin/tiny_mce/plugins/advlink/editor_plugin.js +1 -0
  83. data/lib/public/admin/tiny_mce/plugins/advlink/editor_plugin_src.js +61 -0
  84. data/lib/public/admin/tiny_mce/plugins/advlink/js/advlink.js +532 -0
  85. data/lib/public/admin/tiny_mce/plugins/advlink/langs/en_dlg.js +54 -0
  86. data/lib/public/admin/tiny_mce/plugins/advlink/link.htm +338 -0
  87. data/lib/public/admin/tiny_mce/plugins/advlist/editor_plugin.js +1 -0
  88. data/lib/public/admin/tiny_mce/plugins/advlist/editor_plugin_src.js +176 -0
  89. data/lib/public/admin/tiny_mce/plugins/autolink/editor_plugin.js +1 -0
  90. data/lib/public/admin/tiny_mce/plugins/autolink/editor_plugin_src.js +172 -0
  91. data/lib/public/admin/tiny_mce/plugins/autoresize/editor_plugin.js +1 -0
  92. data/lib/public/admin/tiny_mce/plugins/autoresize/editor_plugin_src.js +137 -0
  93. data/lib/public/admin/tiny_mce/plugins/autosave/editor_plugin.js +1 -0
  94. data/lib/public/admin/tiny_mce/plugins/autosave/editor_plugin_src.js +431 -0
  95. data/lib/public/admin/tiny_mce/plugins/autosave/langs/en.js +4 -0
  96. data/lib/public/admin/tiny_mce/plugins/bbcode/editor_plugin.js +1 -0
  97. data/lib/public/admin/tiny_mce/plugins/bbcode/editor_plugin_src.js +120 -0
  98. data/lib/public/admin/tiny_mce/plugins/contextmenu/editor_plugin.js +1 -0
  99. data/lib/public/admin/tiny_mce/plugins/contextmenu/editor_plugin_src.js +160 -0
  100. data/lib/public/admin/tiny_mce/plugins/directionality/editor_plugin.js +1 -0
  101. data/lib/public/admin/tiny_mce/plugins/directionality/editor_plugin_src.js +82 -0
  102. data/lib/public/admin/tiny_mce/plugins/emotions/editor_plugin.js +1 -0
  103. data/lib/public/admin/tiny_mce/plugins/emotions/editor_plugin_src.js +43 -0
  104. data/lib/public/admin/tiny_mce/plugins/emotions/emotions.htm +41 -0
  105. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-cool.gif +0 -0
  106. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-cry.gif +0 -0
  107. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-embarassed.gif +0 -0
  108. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-foot-in-mouth.gif +0 -0
  109. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-frown.gif +0 -0
  110. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-innocent.gif +0 -0
  111. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-kiss.gif +0 -0
  112. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-laughing.gif +0 -0
  113. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-money-mouth.gif +0 -0
  114. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-sealed.gif +0 -0
  115. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-smile.gif +0 -0
  116. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-surprised.gif +0 -0
  117. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-tongue-out.gif +0 -0
  118. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-undecided.gif +0 -0
  119. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-wink.gif +0 -0
  120. data/lib/public/admin/tiny_mce/plugins/emotions/img/smiley-yell.gif +0 -0
  121. data/lib/public/admin/tiny_mce/plugins/emotions/js/emotions.js +22 -0
  122. data/lib/public/admin/tiny_mce/plugins/emotions/langs/en_dlg.js +20 -0
  123. data/lib/public/admin/tiny_mce/plugins/example/dialog.htm +22 -0
  124. data/lib/public/admin/tiny_mce/plugins/example/editor_plugin.js +1 -0
  125. data/lib/public/admin/tiny_mce/plugins/example/editor_plugin_src.js +84 -0
  126. data/lib/public/admin/tiny_mce/plugins/example/img/example.gif +0 -0
  127. data/lib/public/admin/tiny_mce/plugins/example/js/dialog.js +19 -0
  128. data/lib/public/admin/tiny_mce/plugins/example/langs/en.js +3 -0
  129. data/lib/public/admin/tiny_mce/plugins/example/langs/en_dlg.js +3 -0
  130. data/lib/public/admin/tiny_mce/plugins/example_dependency/editor_plugin.js +1 -0
  131. data/lib/public/admin/tiny_mce/plugins/example_dependency/editor_plugin_src.js +50 -0
  132. data/lib/public/admin/tiny_mce/plugins/fullpage/css/fullpage.css +143 -0
  133. data/lib/public/admin/tiny_mce/plugins/fullpage/editor_plugin.js +1 -0
  134. data/lib/public/admin/tiny_mce/plugins/fullpage/editor_plugin_src.js +399 -0
  135. data/lib/public/admin/tiny_mce/plugins/fullpage/fullpage.htm +259 -0
  136. data/lib/public/admin/tiny_mce/plugins/fullpage/js/fullpage.js +232 -0
  137. data/lib/public/admin/tiny_mce/plugins/fullpage/langs/en_dlg.js +85 -0
  138. data/lib/public/admin/tiny_mce/plugins/fullscreen/editor_plugin.js +1 -0
  139. data/lib/public/admin/tiny_mce/plugins/fullscreen/editor_plugin_src.js +159 -0
  140. data/lib/public/admin/tiny_mce/plugins/fullscreen/fullscreen.htm +109 -0
  141. data/lib/public/admin/tiny_mce/plugins/iespell/editor_plugin.js +1 -0
  142. data/lib/public/admin/tiny_mce/plugins/iespell/editor_plugin_src.js +54 -0
  143. data/lib/public/admin/tiny_mce/plugins/inlinepopups/editor_plugin.js +1 -0
  144. data/lib/public/admin/tiny_mce/plugins/inlinepopups/editor_plugin_src.js +699 -0
  145. data/lib/public/admin/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/alert.gif +0 -0
  146. data/lib/public/admin/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/button.gif +0 -0
  147. data/lib/public/admin/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/buttons.gif +0 -0
  148. data/lib/public/admin/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/confirm.gif +0 -0
  149. data/lib/public/admin/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/corners.gif +0 -0
  150. data/lib/public/admin/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/horizontal.gif +0 -0
  151. data/lib/public/admin/tiny_mce/plugins/inlinepopups/skins/clearlooks2/img/vertical.gif +0 -0
  152. data/lib/public/admin/tiny_mce/plugins/inlinepopups/skins/clearlooks2/window.css +90 -0
  153. data/lib/public/admin/tiny_mce/plugins/inlinepopups/template.htm +387 -0
  154. data/lib/public/admin/tiny_mce/plugins/insertdatetime/editor_plugin.js +1 -0
  155. data/lib/public/admin/tiny_mce/plugins/insertdatetime/editor_plugin_src.js +83 -0
  156. data/lib/public/admin/tiny_mce/plugins/layer/editor_plugin.js +1 -0
  157. data/lib/public/admin/tiny_mce/plugins/layer/editor_plugin_src.js +214 -0
  158. data/lib/public/admin/tiny_mce/plugins/legacyoutput/editor_plugin.js +1 -0
  159. data/lib/public/admin/tiny_mce/plugins/legacyoutput/editor_plugin_src.js +139 -0
  160. data/lib/public/admin/tiny_mce/plugins/lists/editor_plugin.js +1 -0
  161. data/lib/public/admin/tiny_mce/plugins/lists/editor_plugin_src.js +769 -0
  162. data/lib/public/admin/tiny_mce/plugins/media/css/media.css +17 -0
  163. data/lib/public/admin/tiny_mce/plugins/media/editor_plugin.js +1 -0
  164. data/lib/public/admin/tiny_mce/plugins/media/editor_plugin_src.js +822 -0
  165. data/lib/public/admin/tiny_mce/plugins/media/js/embed.js +73 -0
  166. data/lib/public/admin/tiny_mce/plugins/media/js/media.js +389 -0
  167. data/lib/public/admin/tiny_mce/plugins/media/langs/en_dlg.js +112 -0
  168. data/lib/public/admin/tiny_mce/plugins/media/media.htm +897 -0
  169. data/lib/public/admin/tiny_mce/plugins/media/moxieplayer.swf +0 -0
  170. data/lib/public/admin/tiny_mce/plugins/nonbreaking/editor_plugin.js +1 -0
  171. data/lib/public/admin/tiny_mce/plugins/nonbreaking/editor_plugin_src.js +53 -0
  172. data/lib/public/admin/tiny_mce/plugins/noneditable/editor_plugin.js +1 -0
  173. data/lib/public/admin/tiny_mce/plugins/noneditable/editor_plugin_src.js +95 -0
  174. data/lib/public/admin/tiny_mce/plugins/pagebreak/editor_plugin.js +1 -0
  175. data/lib/public/admin/tiny_mce/plugins/pagebreak/editor_plugin_src.js +74 -0
  176. data/lib/public/admin/tiny_mce/plugins/paste/editor_plugin.js +1 -0
  177. data/lib/public/admin/tiny_mce/plugins/paste/editor_plugin_src.js +942 -0
  178. data/lib/public/admin/tiny_mce/plugins/paste/js/pastetext.js +36 -0
  179. data/lib/public/admin/tiny_mce/plugins/paste/js/pasteword.js +51 -0
  180. data/lib/public/admin/tiny_mce/plugins/paste/langs/en_dlg.js +5 -0
  181. data/lib/public/admin/tiny_mce/plugins/paste/pastetext.htm +27 -0
  182. data/lib/public/admin/tiny_mce/plugins/paste/pasteword.htm +21 -0
  183. data/lib/public/admin/tiny_mce/plugins/preview/editor_plugin.js +1 -0
  184. data/lib/public/admin/tiny_mce/plugins/preview/editor_plugin_src.js +53 -0
  185. data/lib/public/admin/tiny_mce/plugins/preview/example.html +28 -0
  186. data/lib/public/admin/tiny_mce/plugins/preview/jscripts/embed.js +73 -0
  187. data/lib/public/admin/tiny_mce/plugins/preview/preview.html +17 -0
  188. data/lib/public/admin/tiny_mce/plugins/print/editor_plugin.js +1 -0
  189. data/lib/public/admin/tiny_mce/plugins/print/editor_plugin_src.js +34 -0
  190. data/lib/public/admin/tiny_mce/plugins/save/editor_plugin.js +1 -0
  191. data/lib/public/admin/tiny_mce/plugins/save/editor_plugin_src.js +101 -0
  192. data/lib/public/admin/tiny_mce/plugins/searchreplace/css/searchreplace.css +6 -0
  193. data/lib/public/admin/tiny_mce/plugins/searchreplace/editor_plugin.js +1 -0
  194. data/lib/public/admin/tiny_mce/plugins/searchreplace/editor_plugin_src.js +61 -0
  195. data/lib/public/admin/tiny_mce/plugins/searchreplace/js/searchreplace.js +142 -0
  196. data/lib/public/admin/tiny_mce/plugins/searchreplace/langs/en_dlg.js +16 -0
  197. data/lib/public/admin/tiny_mce/plugins/searchreplace/searchreplace.htm +100 -0
  198. data/lib/public/admin/tiny_mce/plugins/spellchecker/css/content.css +1 -0
  199. data/lib/public/admin/tiny_mce/plugins/spellchecker/editor_plugin.js +1 -0
  200. data/lib/public/admin/tiny_mce/plugins/spellchecker/editor_plugin_src.js +434 -0
  201. data/lib/public/admin/tiny_mce/plugins/spellchecker/img/wline.gif +0 -0
  202. data/lib/public/admin/tiny_mce/plugins/style/css/props.css +13 -0
  203. data/lib/public/admin/tiny_mce/plugins/style/editor_plugin.js +1 -0
  204. data/lib/public/admin/tiny_mce/plugins/style/editor_plugin_src.js +55 -0
  205. data/lib/public/admin/tiny_mce/plugins/style/js/props.js +635 -0
  206. data/lib/public/admin/tiny_mce/plugins/style/langs/en_dlg.js +70 -0
  207. data/lib/public/admin/tiny_mce/plugins/style/props.htm +840 -0
  208. data/lib/public/admin/tiny_mce/plugins/tabfocus/editor_plugin.js +1 -0
  209. data/lib/public/admin/tiny_mce/plugins/tabfocus/editor_plugin_src.js +122 -0
  210. data/lib/public/admin/tiny_mce/plugins/table/cell.htm +180 -0
  211. data/lib/public/admin/tiny_mce/plugins/table/css/cell.css +17 -0
  212. data/lib/public/admin/tiny_mce/plugins/table/css/row.css +25 -0
  213. data/lib/public/admin/tiny_mce/plugins/table/css/table.css +13 -0
  214. data/lib/public/admin/tiny_mce/plugins/table/editor_plugin.js +1 -0
  215. data/lib/public/admin/tiny_mce/plugins/table/editor_plugin_src.js +1363 -0
  216. data/lib/public/admin/tiny_mce/plugins/table/js/cell.js +319 -0
  217. data/lib/public/admin/tiny_mce/plugins/table/js/merge_cells.js +27 -0
  218. data/lib/public/admin/tiny_mce/plugins/table/js/row.js +237 -0
  219. data/lib/public/admin/tiny_mce/plugins/table/js/table.js +450 -0
  220. data/lib/public/admin/tiny_mce/plugins/table/langs/en_dlg.js +75 -0
  221. data/lib/public/admin/tiny_mce/plugins/table/merge_cells.htm +32 -0
  222. data/lib/public/admin/tiny_mce/plugins/table/row.htm +158 -0
  223. data/lib/public/admin/tiny_mce/plugins/table/table.htm +188 -0
  224. data/lib/public/admin/tiny_mce/plugins/template/blank.htm +12 -0
  225. data/lib/public/admin/tiny_mce/plugins/template/css/template.css +23 -0
  226. data/lib/public/admin/tiny_mce/plugins/template/editor_plugin.js +1 -0
  227. data/lib/public/admin/tiny_mce/plugins/template/editor_plugin_src.js +159 -0
  228. data/lib/public/admin/tiny_mce/plugins/template/js/template.js +106 -0
  229. data/lib/public/admin/tiny_mce/plugins/template/langs/en_dlg.js +15 -0
  230. data/lib/public/admin/tiny_mce/plugins/template/template.htm +31 -0
  231. data/lib/public/admin/tiny_mce/plugins/visualchars/editor_plugin.js +1 -0
  232. data/lib/public/admin/tiny_mce/plugins/visualchars/editor_plugin_src.js +83 -0
  233. data/lib/public/admin/tiny_mce/plugins/wordcount/editor_plugin.js +1 -0
  234. data/lib/public/admin/tiny_mce/plugins/wordcount/editor_plugin_src.js +114 -0
  235. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/abbr.htm +142 -0
  236. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/acronym.htm +142 -0
  237. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/attributes.htm +149 -0
  238. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/cite.htm +142 -0
  239. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/css/attributes.css +11 -0
  240. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/css/popup.css +9 -0
  241. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/del.htm +162 -0
  242. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/editor_plugin.js +1 -0
  243. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/editor_plugin_src.js +132 -0
  244. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/ins.htm +162 -0
  245. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/js/abbr.js +28 -0
  246. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/js/acronym.js +28 -0
  247. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/js/attributes.js +111 -0
  248. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/js/cite.js +28 -0
  249. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/js/del.js +53 -0
  250. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/js/element_common.js +229 -0
  251. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/js/ins.js +53 -0
  252. data/lib/public/admin/tiny_mce/plugins/xhtmlxtras/langs/en_dlg.js +32 -0
  253. data/lib/public/admin/tiny_mce/themes/advanced/about.htm +52 -0
  254. data/lib/public/admin/tiny_mce/themes/advanced/anchor.htm +26 -0
  255. data/lib/public/admin/tiny_mce/themes/advanced/charmap.htm +51 -0
  256. data/lib/public/admin/tiny_mce/themes/advanced/color_picker.htm +74 -0
  257. data/lib/public/admin/tiny_mce/themes/advanced/editor_template.js +1 -0
  258. data/lib/public/admin/tiny_mce/themes/advanced/editor_template_src.js +1358 -0
  259. data/lib/public/admin/tiny_mce/themes/advanced/image.htm +80 -0
  260. data/lib/public/admin/tiny_mce/themes/advanced/img/colorpicker.jpg +0 -0
  261. data/lib/public/admin/tiny_mce/themes/advanced/img/flash.gif +0 -0
  262. data/lib/public/admin/tiny_mce/themes/advanced/img/icons.gif +0 -0
  263. data/lib/public/admin/tiny_mce/themes/advanced/img/iframe.gif +0 -0
  264. data/lib/public/admin/tiny_mce/themes/advanced/img/pagebreak.gif +0 -0
  265. data/lib/public/admin/tiny_mce/themes/advanced/img/quicktime.gif +0 -0
  266. data/lib/public/admin/tiny_mce/themes/advanced/img/realmedia.gif +0 -0
  267. data/lib/public/admin/tiny_mce/themes/advanced/img/shockwave.gif +0 -0
  268. data/lib/public/admin/tiny_mce/themes/advanced/img/trans.gif +0 -0
  269. data/lib/public/admin/tiny_mce/themes/advanced/img/video.gif +0 -0
  270. data/lib/public/admin/tiny_mce/themes/advanced/img/windowsmedia.gif +0 -0
  271. data/lib/public/admin/tiny_mce/themes/advanced/js/about.js +73 -0
  272. data/lib/public/admin/tiny_mce/themes/advanced/js/anchor.js +42 -0
  273. data/lib/public/admin/tiny_mce/themes/advanced/js/charmap.js +355 -0
  274. data/lib/public/admin/tiny_mce/themes/advanced/js/color_picker.js +329 -0
  275. data/lib/public/admin/tiny_mce/themes/advanced/js/image.js +247 -0
  276. data/lib/public/admin/tiny_mce/themes/advanced/js/link.js +153 -0
  277. data/lib/public/admin/tiny_mce/themes/advanced/js/source_editor.js +56 -0
  278. data/lib/public/admin/tiny_mce/themes/advanced/langs/en.js +68 -0
  279. data/lib/public/admin/tiny_mce/themes/advanced/langs/en_dlg.js +54 -0
  280. data/lib/public/admin/tiny_mce/themes/advanced/link.htm +57 -0
  281. data/lib/public/admin/tiny_mce/themes/advanced/shortcuts.htm +47 -0
  282. data/lib/public/admin/tiny_mce/themes/advanced/skins/default/content.css +48 -0
  283. data/lib/public/admin/tiny_mce/themes/advanced/skins/default/dialog.css +117 -0
  284. data/lib/public/admin/tiny_mce/themes/advanced/skins/default/img/buttons.png +0 -0
  285. data/lib/public/admin/tiny_mce/themes/advanced/skins/default/img/items.gif +0 -0
  286. data/lib/public/admin/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif +0 -0
  287. data/lib/public/admin/tiny_mce/themes/advanced/skins/default/img/menu_check.gif +0 -0
  288. data/lib/public/admin/tiny_mce/themes/advanced/skins/default/img/progress.gif +0 -0
  289. data/lib/public/admin/tiny_mce/themes/advanced/skins/default/img/tabs.gif +0 -0
  290. data/lib/public/admin/tiny_mce/themes/advanced/skins/default/ui.css +214 -0
  291. data/lib/public/admin/tiny_mce/themes/advanced/skins/highcontrast/content.css +23 -0
  292. data/lib/public/admin/tiny_mce/themes/advanced/skins/highcontrast/dialog.css +105 -0
  293. data/lib/public/admin/tiny_mce/themes/advanced/skins/highcontrast/ui.css +102 -0
  294. data/lib/public/admin/tiny_mce/themes/advanced/skins/o2k7/content.css +47 -0
  295. data/lib/public/admin/tiny_mce/themes/advanced/skins/o2k7/dialog.css +117 -0
  296. data/lib/public/admin/tiny_mce/themes/advanced/skins/o2k7/img/button_bg.png +0 -0
  297. data/lib/public/admin/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_black.png +0 -0
  298. data/lib/public/admin/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_silver.png +0 -0
  299. data/lib/public/admin/tiny_mce/themes/advanced/skins/o2k7/ui.css +217 -0
  300. data/lib/public/admin/tiny_mce/themes/advanced/skins/o2k7/ui_black.css +8 -0
  301. data/lib/public/admin/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css +5 -0
  302. data/lib/public/admin/tiny_mce/themes/advanced/source_editor.htm +25 -0
  303. data/lib/public/admin/tiny_mce/themes/simple/editor_template.js +1 -0
  304. data/lib/public/admin/tiny_mce/themes/simple/editor_template_src.js +84 -0
  305. data/lib/public/admin/tiny_mce/themes/simple/img/icons.gif +0 -0
  306. data/lib/public/admin/tiny_mce/themes/simple/langs/en.js +11 -0
  307. data/lib/public/admin/tiny_mce/themes/simple/skins/default/content.css +25 -0
  308. data/lib/public/admin/tiny_mce/themes/simple/skins/default/ui.css +32 -0
  309. data/lib/public/admin/tiny_mce/themes/simple/skins/o2k7/content.css +17 -0
  310. data/lib/public/admin/tiny_mce/themes/simple/skins/o2k7/img/button_bg.png +0 -0
  311. data/lib/public/admin/tiny_mce/themes/simple/skins/o2k7/ui.css +35 -0
  312. data/lib/public/admin/tiny_mce/tiny_mce.js +1 -0
  313. data/lib/public/admin/tiny_mce/tiny_mce_popup.js +5 -0
  314. data/lib/public/admin/tiny_mce/tiny_mce_src.js +15519 -0
  315. data/lib/public/admin/tiny_mce/utils/editable_selects.js +70 -0
  316. data/lib/public/admin/tiny_mce/utils/form_utils.js +210 -0
  317. data/lib/public/admin/tiny_mce/utils/mctabs.js +162 -0
  318. data/lib/public/admin/tiny_mce/utils/validate.js +252 -0
  319. data/lib/yodel_admin.rb +3 -0
  320. data/yodel_admin.gemspec +22 -0
  321. metadata +365 -0
@@ -0,0 +1,1030 @@
1
+ var MENU_WIDTH = 371;
2
+
3
+ // Array Remove - By John Resig (MIT Licensed)
4
+ Array.prototype.remove = function(from, to) {
5
+ var rest = this.slice((to || from) + 1 || this.length);
6
+ this.length = from < 0 ? this.length + from : from;
7
+ return this.push.apply(this, rest);
8
+ };
9
+
10
+ function initialiseWidgets() {
11
+ hideModelPanel();
12
+ initialiseHTMLFields();
13
+ initialiseMultipleSelectFields();
14
+ addClearLinks();
15
+ }
16
+
17
+ function initialiseHTMLFields() {
18
+ if($('.list').length) {
19
+ var width = '320px';
20
+ var row1 = 'bold,italic,underline,strikethrough,sub,sup,charmap,|,justifyleft,justifycenter,justifyright,justifyfull';
21
+ var row2 = 'formatselect,fontsizeselect,|,bullist,numlist,outdent,indent,blockquote';
22
+ var row3 = 'link,unlink,|,code';
23
+ } else {
24
+ var width = '100%';
25
+ var row1 = 'bold,italic,underline,strikethrough,sub,sup,charmap,|,justifyleft,justifycenter,justifyright,justifyfull,|,formatselect,fontsizeselect,|,bullist,numlist,outdent,indent,blockquote,|,link,unlink,|,code';
26
+ var row2 = '';
27
+ var row3 = '';
28
+ }
29
+
30
+ $('textarea.html').each(function(index, field) {
31
+ $(field).tinymce({
32
+ script_url : '/admin/tiny_mce/tiny_mce.js',
33
+ theme : "advanced",
34
+ plugins : "safari,inlinepopups,paste",
35
+ width: width,
36
+ height: '200',
37
+ theme_advanced_blockformats: 'p,h1,h2,h3',
38
+
39
+ theme_advanced_buttons1 : row1,
40
+ theme_advanced_buttons2 : row2,
41
+ theme_advanced_buttons3 : row3,
42
+ theme_advanced_toolbar_location : "top",
43
+ theme_advanced_toolbar_align : "left",
44
+ theme_advanced_statusbar_location : "none",
45
+ theme_advanced_resizing : false
46
+ });
47
+ });
48
+ }
49
+
50
+ function initialiseMultipleSelectFields() {
51
+ $('select[multiple=multiple]').chosen();
52
+ }
53
+
54
+ function addClearLinks() {
55
+ $('#record_form .field-type-attachment p, #record_form .field-type-image p').each(function(index, p) {
56
+ var clear = $('<a class="clear">clear</a>');
57
+ $(p).append(clear);
58
+ if($(p).find('span').html() == 'none')
59
+ clear.hide();
60
+ });
61
+ }
62
+
63
+ $('#admin_save button').click(function(event) {
64
+ $('#admin_save_spinner').fadeIn().delay(1000).fadeOut();
65
+ $('#admin_save_success').delay(1500).fadeIn().delay(2000).fadeOut();
66
+ });
67
+
68
+
69
+
70
+ var menus = {};
71
+
72
+ function showMenu(parentName, recordID, initialLoad) {
73
+ if(menus[recordID]) {
74
+ pushNavigationPanel(parentName, menus[recordID]);
75
+ } else {
76
+ jQuery.getJSON(jsonURL + '?id=' + recordID, function(data) {
77
+ menus[recordID] = data;
78
+ pushNavigationPanel(parentName, data, initialLoad);
79
+ highlightSelectedRow(recordID);
80
+ });
81
+ }
82
+ }
83
+
84
+
85
+
86
+
87
+ var NEW_ROW = '<h1 class="new"><div class="folder_state spacer"></div><div class="icon"><div class="spinner"></div><img src="/admin/images/new.png"></div>New</h1></li>';
88
+
89
+ function constructRecordListItem(tree) {
90
+ // add the icon, name, slide and delete icons
91
+ var list = '<li class="record" data-record-id="' + tree.id + '" data-type="' + tree.type + '">';
92
+
93
+ // the h1 contains the content elements for each record
94
+ if(tree.menu_root)
95
+ list += '<h1 class="new_panel">';
96
+ else
97
+ list += '<h1>';
98
+
99
+ // add space for any children underneath this record
100
+ var canHaveChildren = (types[tree.type].validChildren.length > 0 && !tree.menu_root);
101
+ var hasChildren = (tree.children && tree.children.length > 0);
102
+ if(!tree.root) {
103
+ list += '<div class="folder_state';
104
+ if(hasChildren)
105
+ list += ' open';
106
+ list += '"></div>';
107
+ }
108
+
109
+ // add the slider, delete and drag handle icons if necessary
110
+ list += '<div class="icon"><div class="spinner"></div><img src="';
111
+ if(tree.icon)
112
+ list += tree.icon;
113
+ else
114
+ list += '/admin/images/default_icon.png';
115
+ list += '"></div><p>' + tree.name + '</p>';
116
+ if(tree.menu_root)
117
+ list += '<div class="slide"></div>';
118
+ if(!tree.root)
119
+ list += '<div class="delete"></div><div class="drag"></div>';
120
+ if(canHaveChildren) {
121
+ list += '<div class="add_child';
122
+ if(hasChildren || tree.root)
123
+ list += ' hidden';
124
+ list += '"></div>';
125
+ }
126
+ list += '</h1>';
127
+
128
+ // generate a tree for child elements of this record
129
+ var child_lists = [];
130
+ for(var i = 0, c = tree.children.length; i < c; i++)
131
+ child_lists.push(constructRecordListItem(tree.children[i]));
132
+
133
+ if(canHaveChildren)
134
+ child_lists.push('<li>' + NEW_ROW);
135
+
136
+ if(!tree.root)
137
+ list += '<ul class="child_elements" style="display: none">';
138
+ else
139
+ list += '<ul class="child_elements">';
140
+
141
+ return list + child_lists.join('') + '</ul></li>';
142
+ }
143
+
144
+ function constructRecordList(tree) {
145
+ return '<ul>' + constructRecordListItem(tree) + '</ul>';
146
+ }
147
+
148
+
149
+ var navigationPanels = [];
150
+
151
+ function dragError(parent, oldIndex, row) {
152
+ alert('Sorry, an error occurred updating the position of this record. Please reload the page and try again.');
153
+
154
+ // move the row back to its old position; record indexes are 1 based
155
+ if(oldIndex == 1) {
156
+ row.insertBefore('.record[data-record-id=' + parent.children[1].id + ']');
157
+ } else {
158
+ row.insertAfter('.record[data-record-id=' + parent.children[oldIndex - 2].id + ']');
159
+ }
160
+ }
161
+
162
+ function pushNavigationPanel(rootName, tree, isPageRoot) {
163
+ // create the panel html
164
+ html = '<nav class="previous_folder">';
165
+ if(rootName) {
166
+ html += '<a href="#" class="prev_nav_panel'
167
+ if(isPageRoot)
168
+ html += ' root';
169
+ html += '">' + rootName + '</a>';
170
+ }
171
+ html += '</nav><nav class="records">' + constructRecordList(tree) + '</nav></div>';
172
+
173
+ // push the panel to the elements list
174
+ var panel = $('<div class="navigation_panel">');
175
+ panel.html(html);
176
+ panel.data('tree', tree);
177
+ navigationPanels.push(panel);
178
+
179
+ // prepare for animation and insert the panel
180
+ if(navigationPanels.length != 1)
181
+ panel.css('left', MENU_WIDTH + 'px');
182
+ $('#navigation_panels').append(panel);
183
+ panel.find('ul.child_elements').sortable({
184
+ containment: 'parent',
185
+ items: '> li.record',
186
+ axis: 'y',
187
+ handle: 'div.drag',
188
+ revert: 200,
189
+ cursor: 'ns-resize',
190
+ start: function(event, ui) {
191
+ ui.item.addClass('dragging');
192
+ },
193
+ stop: function(event, ui) {
194
+ ui.item.removeClass('dragging');
195
+
196
+ // save the new record index
197
+ var tree = navigationPanels[navigationPanels.length - 1].data('tree');
198
+ var id = ui.item.attr('data-record-id');
199
+ var record = null;
200
+ var parent = null;
201
+
202
+ // find the record by id
203
+ if(id == tree.id)
204
+ record = tree;
205
+ else
206
+ record = findRecord(tree, id);
207
+
208
+ // try and find the parent record
209
+ if(record && record.parent_id)
210
+ parent = findRecord(tree, record.parent_id);
211
+ if(!parent) {
212
+ alert("Sorry, an error occurred updating the position of this record (the parent record could not be found). Please refresh the page and try again.");
213
+ return;
214
+ }
215
+
216
+ // if this is the only child of the parent, ignore the index change
217
+ if(parent.children.length == 1)
218
+ return;
219
+
220
+ // otherwise detect the new index of this record
221
+ var oldIndex = record.index;
222
+ if(ui.item.prev().length != 0) {
223
+ var sibling = findRecord(tree, ui.item.prev().attr('data-record-id'));
224
+ var newIndex = sibling.index;
225
+ if(record.index > sibling.index)
226
+ newIndex += 1;
227
+ } else {
228
+ var newIndex = 1;
229
+ }
230
+ if(oldIndex == newIndex)
231
+ return;
232
+
233
+ // save the updated index
234
+ $.ajax(jsonURL, {
235
+ data: {id: record.id, _method: 'put', action: 'set_index', index: newIndex},
236
+ dataType: 'json',
237
+ type: 'post',
238
+ success: function(data, textStatus, jqXHR) {
239
+ if(data.success == false) {
240
+ dragError(parent, oldIndex, ui.item);
241
+ return;
242
+ }
243
+
244
+ // update backing object
245
+ record.index = newIndex;
246
+
247
+ // update the index of other affected records
248
+ if(newIndex > oldIndex) {
249
+ for(var i = oldIndex; i < newIndex; i++)
250
+ parent.children[i].index -= 1;
251
+ } else {
252
+ for(var i = (newIndex - 1); i < (oldIndex - 2); i++)
253
+ parent.children[i].index += 1;
254
+ }
255
+
256
+ // change the position of the record in the parent's list of children
257
+ parent.children.splice(oldIndex - 1, 1);
258
+ parent.children.splice(newIndex - 1, 0, record);
259
+
260
+ }, error: function(jqXHR, textStatus, errorThrown) {
261
+ dragError(parent, oldIndex, ui.item);
262
+ }
263
+ });
264
+ }
265
+ });
266
+
267
+ // animate the panel in to view
268
+ if(navigationPanels.length != 1) {
269
+ navigationPanels[navigationPanels.length - 2].animate({left: '-' + MENU_WIDTH + 'px'});
270
+ panel.animate({left: '0px'});
271
+ }
272
+ }
273
+
274
+ function popNavigationPanel() {
275
+ if(navigationPanels.length == 1)
276
+ return;
277
+
278
+ // swap between the previous and current panels, and remove the current panel
279
+ navigationPanels[navigationPanels.length - 2].animate({left: '0px'});
280
+ navigationPanels[navigationPanels.length - 1].animate({left: MENU_WIDTH + 'px'}, {complete: function() {
281
+ $(this).remove();
282
+ }});
283
+ navigationPanels = navigationPanels.slice(0, -1);
284
+
285
+ // sliding back a navigation panel means the currently displayed record
286
+ // can no longer be displayed; clear the record form and any highlights
287
+ $('#record').empty();
288
+ $('.record h1.selected').removeClass('selected');
289
+ }
290
+
291
+
292
+ function showNavigationPanel(recordID, element) {
293
+ // get the name of the root element in the current list
294
+ var rootName = $(element).parents('nav.records').find('> ul > li > h1 > p').html();
295
+
296
+ // show the new navigation panel
297
+ showMenu(rootName, recordID);
298
+ }
299
+
300
+ function showPreviousNavigationPanel(event) {
301
+ popNavigationPanel();
302
+ event.preventDefault();
303
+ }
304
+
305
+
306
+ // folder open/close
307
+ function showOrHideChildren(event) {
308
+ event.preventDefault();
309
+ event.stopPropagation();
310
+ if($(event.target).hasClass('open'))
311
+ showChildren(event);
312
+ else
313
+ hideChildren(event);
314
+ }
315
+
316
+ function showChildren(event) {
317
+ var button = $(event.target);
318
+
319
+ button.parents('h1').siblings('ul').animate({
320
+ height: 'show',
321
+ opacity: 'show'
322
+ }, 400);
323
+
324
+ button.removeClass('open');
325
+ button.addClass('close');
326
+ }
327
+
328
+ function hideChildren(event) {
329
+ var button = $(event.target);
330
+
331
+ button.parents('h1').siblings('ul').animate({
332
+ height: 'hide',
333
+ opacity: 'hide'
334
+ }, 400);
335
+
336
+ button.removeClass('close');
337
+ button.addClass('open');
338
+ }
339
+
340
+
341
+ // update an existing record or add a record to the tree
342
+ function updateRecord(record) {
343
+ // either find the parent record by searching from the root of the
344
+ // current tree, or the updated record is the root of the current tree
345
+ var tree = navigationPanels[navigationPanels.length - 1].data('tree');
346
+ var treeRecord = null;
347
+ var parent = null;
348
+
349
+ if(record.id == tree.id)
350
+ treeRecord = tree;
351
+ else
352
+ if(record.parent_id == tree.id)
353
+ parent = tree;
354
+ else
355
+ parent = findRecord(tree, record.parent_id);
356
+
357
+ if(!treeRecord && !parent) {
358
+ alert("Sorry, an error occurred while creating this record (no parent or record could be found). Please refresh the page and try again.");
359
+ return;
360
+ }
361
+
362
+ // if we found a parent, determine if this is a new or existing record
363
+ var update = false;
364
+ if(parent) {
365
+ if(!parent.children)
366
+ parent.children = [];
367
+
368
+ // try and find an existing record
369
+ for(var i = 0, c = parent.children.length; i < c; i++) {
370
+ if(parent.children[i].id == record.id) {
371
+ treeRecord = parent.children[i];
372
+ update = true;
373
+ break;
374
+ }
375
+ }
376
+
377
+ // if none was found, create a blank record
378
+ if(!update) {
379
+ treeRecord = {children:[]};
380
+ parent.children.push(treeRecord);
381
+ }
382
+ } else {
383
+ // if there's no parent, treeRecord must be an existing root record
384
+ update = true;
385
+ }
386
+
387
+ // copy the new values across
388
+ treeRecord.id = record.id;
389
+ treeRecord.icon = record.icon;
390
+ treeRecord.index = record.index;
391
+ treeRecord.root = treeRecord.root || false;
392
+ treeRecord.menu_root = record.menu_root;
393
+ treeRecord.name = record.name;
394
+ treeRecord.parent_id = record.parent_id;
395
+ treeRecord.type = record.type;
396
+
397
+ if(update) {
398
+ // change the existing record's name
399
+ $('.record[data-record-id=' + record.id + '] > h1 > p').html(record.name);
400
+
401
+ } else {
402
+ // if this is the first new child of the parent, hide the new (+)
403
+ // button, show the "New" row, show the list, and set the disclosure
404
+ // button to - (indicating the folder is open)
405
+ var parentRow = $('.record[data-record-id=' + parent.id + ']');
406
+ var parentChildList = parentRow.find('> .child_elements');
407
+ if(parent && !parent.root && !parent.menu_root) {
408
+ if(parent.children.length == 1) {
409
+ parentChildList.show();
410
+ parentRow.find('> h1 > .add_child').addClass('hidden');
411
+ parentRow.find('> h1 > .folder_state').addClass('close');
412
+ parentRow.find('> h1 > .folder_state').removeClass('open');
413
+ }
414
+ }
415
+
416
+ // insert the new row
417
+ var row = constructRecordListItem(treeRecord);
418
+ parentChildList.find('> li:last-child').before(row);
419
+ highlightSelectedRow(treeRecord.id);
420
+
421
+ // if the row is a menu root, slide to the new menu
422
+ if(treeRecord.menu_root)
423
+ showNavigationPanel(treeRecord.id, parentRow);
424
+ }
425
+ }
426
+
427
+ function findRecord(parent, id) {
428
+ if(parent.id == id)
429
+ return parent;
430
+
431
+ if(parent.children && parent.children.length > 0) {
432
+ for(var i = 0, c = parent.children.length; i < c; i++) {
433
+ if(parent.children[i].id == id)
434
+ return parent.children[i];
435
+ var record = findRecord(parent.children[i], id);
436
+ if(record != false)
437
+ return record;
438
+ }
439
+ }
440
+ return false;
441
+ }
442
+
443
+ // delete a record from the tree
444
+ function deleteRecordInTree(parent, id) {
445
+ if(parent.children && parent.children.length > 0) {
446
+ for(var i = 0, c = parent.children.length; i < c; i++) {
447
+ var record = parent.children[i];
448
+ if(record.id == id) {
449
+ parent.children.remove(i, i);
450
+ return parent;
451
+ } else {
452
+ var result = deleteRecordInTree(record, id);
453
+ if(result)
454
+ return result;
455
+ }
456
+ }
457
+ }
458
+ return false;
459
+ }
460
+
461
+
462
+
463
+
464
+ // delete buttons
465
+ function deleteButtonPressed(event) {
466
+ event.preventDefault();
467
+ event.stopPropagation();
468
+ var recordRow = $(event.target).parents('li').first();
469
+ var recordTypeName = types[recordRow.attr('data-type')].humanName;
470
+ var recordID = recordRow.attr('data-record-id');
471
+
472
+ if(confirm('Are you sure you want to delete this ' + recordTypeName + '?')) {
473
+ showSpinner(recordRow);
474
+ $.ajax(jsonURL, {
475
+ data: {id: recordID, _method: 'delete'},
476
+ dataType: 'json',
477
+ type: 'post',
478
+ success: function(data, textStatus, jqXHR) {
479
+ // delete the backing object
480
+ var tree = navigationPanels[navigationPanels.length - 1].data('tree');
481
+ var parent = deleteRecordInTree(tree, recordID);
482
+
483
+ // remove the row representing the object
484
+ recordRow.remove();
485
+
486
+ // clear the record panel if this record was being displayed
487
+ if($('#record_id').val() == recordID)
488
+ $('#record').empty();
489
+
490
+ // clear the record panel if this record was the parent of a
491
+ // new record currently being created
492
+ if($('#parent').val() == recordID)
493
+ $('#record').empty();
494
+
495
+ // collapse the record if this was the last child record
496
+ if(parent && parent.children.length == 0 && !parent.root) {
497
+ var parentRow = $('.record[data-record-id=' + parent.id + ']');
498
+ var parentChildList = parentRow.find('> .child_elements');
499
+ var folderState = parentRow.find('> h1 > .folder_state');
500
+ parentChildList.hide();
501
+ parentRow.find('h1 > .add_child').removeClass('hidden');
502
+ folderState.removeClass('close');
503
+ folderState.removeClass('open');
504
+
505
+ // if a new record was being created under the parent, and this
506
+ // deleted record was the last child, change the highlighted
507
+ // row from the 'new' row to the parent row itself
508
+ if(parentChildList.find('li .new').hasClass('selected')) {
509
+ parentChildList.find('li .new').removeClass('selected');
510
+ parentRow.find('> h1').addClass('selected');
511
+ }
512
+ }
513
+
514
+ // remove the record from the menu list if it was a menu root
515
+ if(menus[recordID])
516
+ delete menus[recordID];
517
+ }, error: function(jqXHR, textStatus, errorThrown) {
518
+ // FIXME: better error message
519
+ hideSpinner(recordRow);
520
+ alert('Sorry, an error occurred deleting this record. Please reload the page and try again.');
521
+ }
522
+ });
523
+ }
524
+ }
525
+
526
+
527
+ // attachment/photo clearing
528
+ function clearAttachmentOrPhoto(event) {
529
+ event.preventDefault();
530
+ var link = $(event.target);
531
+ var container = link.closest('.field-type-attachment, .field-type-image');
532
+ link.hide();
533
+ container.find('p span').html('none');
534
+ container.find('input[type=checkbox]').attr('checked', true);
535
+ container.find('input[type=file]').val('');
536
+ link.closest('.field-type-image').find('img').hide();
537
+ }
538
+
539
+ function hideClear(event) {
540
+ var file_input = $(event.target);
541
+ var container = file_input.closest('.field-type-attachment, .field-type-image');
542
+ container.find('input[type=checkbox]').removeAttr('checked');
543
+ container.find('.clear').show();
544
+ }
545
+
546
+
547
+ // new record type panel
548
+ var modelPanelShowing = false;
549
+ function showModelPanel(event) {
550
+ event.preventDefault();
551
+ event.stopPropagation();
552
+ var recordRow = $(event.target).parents('li.record');
553
+
554
+ // hide all new model buttons, then display only those valid for the selected parent
555
+ // if the model only has a single allowed child type, immediately show a new record form
556
+ var childTypes = types[recordRow.attr('data-type')].validChildren;
557
+ var parentID = recordRow.attr('data-record-id');
558
+
559
+ if(childTypes.length == 1) {
560
+ var modelID = types[childTypes[0]].id;
561
+ loadNewRecord(modelID, parentID);
562
+ return;
563
+ } else {
564
+ $('#new_model_panel ul a').hide();
565
+ for(var i = 0, c = childTypes.length; i < c; i++) {
566
+ $('a.model[data-type="' + childTypes[i] + '"]').show();
567
+ }
568
+ }
569
+
570
+ $('#new_model_panel').attr('data-parent-id', parentID);
571
+ $('#new_model_panel').fadeIn();
572
+ $('#admin_content').fadeOut();
573
+ modelPanelShowing = true;
574
+ }
575
+
576
+ function hideModelPanel(event) {
577
+ if(!modelPanelShowing) return;
578
+ if(event) event.preventDefault();
579
+ if(modelPanelShowing) {
580
+ $('#new_model_panel').fadeOut();
581
+ $('#admin_content').fadeIn();
582
+ $('#new_model_panel .spinner').hide();
583
+ $('#new_model_panel .icon').show();
584
+ }
585
+ modelPanelShowing = false;
586
+ }
587
+
588
+
589
+
590
+
591
+ // options and section toggle button
592
+ function toggleSectionVisibility(event) {
593
+ event.preventDefault();
594
+ $(event.target).closest('section').find('> div').slideToggle('slow');
595
+ $(event.target).html($(event.target).html() == 'show' ? 'hide' : 'show');
596
+ event.preventDefault();
597
+ }
598
+
599
+
600
+ // delete an embedded doc
601
+ function deleteEmbeddedDoc(event) {
602
+ event.preventDefault();
603
+ var target = $(event.target);
604
+ var documents = target.parents('div.embedded_documents');
605
+ var type = documents.attr('data-type');
606
+
607
+ if(confirm('Are you sure you want to delete this ' + type + '?')) {
608
+ target.parents('div.embedded_document').animate({
609
+ height: 'hide',
610
+ opacity: 'hide'
611
+ }, {
612
+ complete: function() {
613
+ // show the 'No TYPE' text if we are removing the last embedded doc in a collection
614
+ if(documents.find('div.embedded_document').size() == 1)
615
+ documents.find('.no_embedded_documents').animate({height: 'show', opacity: 'show'});
616
+ $(this).remove();
617
+ }
618
+ });
619
+ }
620
+ }
621
+
622
+ // add a new embedded doc
623
+ function addEmbeddedDoc(event) {
624
+ event.preventDefault();
625
+ var target = $(event.target);
626
+ var documents = target.parents('div.embedded_documents');
627
+
628
+ // construct a new document form an insert in to the collection
629
+ var doc = $('<div class="embedded_document" style="display: none"><a href="#" class="delete_embedded_document"></a><table><tr><td id="label_col"></td><td id="input_col"></td></tr><tr><td><label>Photo</label></td><td><div class="attachment photo"><div class="photo_preview"><img src="sample_photo.jpg"></div><p class="current_value"><span class="title">File:</span>train.jpeg <a href="#" class="clear">Clear</a></p><p><span class="title">Select:</span><input type="file"></p><input type="hidden" name="delete_X" class="delete" value="false"></div></td></tr><tr><td><label>Name</label></td><td><input type="text"></td></tr></table></div>');
630
+ $(event.target).before(doc);
631
+
632
+ // hide the 'No TYPE' text if we are adding a new embedded doc in to an empty collection
633
+ // animate the insertion of the new doc after hiding the 'No TYPE' text or immediately
634
+ if(documents.find('div.embedded_document').size() == 1) {
635
+ documents.find('.no_embedded_documents').animate({
636
+ height: 'hide',
637
+ opacity: 'hide'
638
+ }, {
639
+ duration: 150,
640
+ complete: function() {
641
+ doc.animate({height: 'show', opacity: 'show'});
642
+ }
643
+ });
644
+ } else {
645
+ doc.animate({height: 'show', opacity: 'show'});
646
+ }
647
+ }
648
+
649
+
650
+
651
+ $('div.delete').live('click', deleteButtonPressed);
652
+ $('div.folder_state').live('click', showOrHideChildren);
653
+
654
+ $('a.clear').live('click', clearAttachmentOrPhoto);
655
+ $('input[type=file]').live('change', hideClear);
656
+
657
+ $('a.prev_nav_panel').live('click', showPreviousNavigationPanel);
658
+ $('a.section_toggle').live('click', toggleSectionVisibility);
659
+ $('a.delete_embedded_document').live('click', deleteEmbeddedDoc);
660
+ $('a.add_embedded_document').live('click', addEmbeddedDoc);
661
+
662
+ $('h1.new').live('click', showModelPanel);
663
+ $('div.add_child').live('click', showModelPanel);
664
+ $('#cancel_new_record').live('click', hideModelPanel);
665
+
666
+ $('.opens-editor').click(function(event) {
667
+ $.ajax($(event.target).attr('href'));
668
+ event.preventDefault();
669
+ });
670
+
671
+
672
+
673
+
674
+
675
+ // show and hide spinners to indicate network activity. More than
676
+ // one spinner at a time may be shown (e.g deleting two records
677
+ // while loading another)
678
+ function showSpinner(row) {
679
+ if(typeof row == 'string')
680
+ row = $('.record[data-record-id=' + row + '] > h1 > .icon .spinner').show();
681
+ else
682
+ row = $(row).find('.icon .spinner').show();
683
+ }
684
+
685
+ function hideSpinner(row) {
686
+ if(typeof row == 'string')
687
+ row = $('.record[data-record-id=' + row + '] > h1 > .icon .spinner').hide();
688
+ else
689
+ row = $(row).find('.icon .spinner').hide();
690
+ }
691
+
692
+ // un-highlight all other rows, and highlight a new selected record
693
+ function highlightSelectedRow(row) {
694
+ $('.record h1.selected').removeClass('selected');
695
+ hideSpinner(row);
696
+ if(typeof row == 'string')
697
+ row = $('.record[data-record-id=' + row + '] > h1');
698
+ else
699
+ row = $(row);
700
+ row.addClass('selected');
701
+ }
702
+
703
+ // load an existing record's form
704
+ function loadRecord(id) {
705
+ $('#record').load(htmlURL + '?action=show&id=' + id, function(text, status, req) {
706
+ highlightSelectedRow(id);
707
+ hideModelPanel();
708
+ initialiseWidgets();
709
+ });
710
+ }
711
+
712
+ // show a menu root record
713
+ $('.record > h1.new_panel').live('click', function(event) {
714
+ var recordID = $(this).parent().attr('data-record-id');
715
+ showSpinner(this);
716
+ loadRecord(recordID);
717
+ showNavigationPanel(recordID, this);
718
+ event.stopImmediatePropagation();
719
+ });
720
+
721
+ // show a normal record
722
+ $('.record > h1').live('click', function(event) {
723
+ showSpinner(this);
724
+ loadRecord($(this).parent().attr('data-record-id'));
725
+ });
726
+
727
+ // load a blank (new) record
728
+ function loadNewRecord(modelID, parentID, modelWasSelected) {
729
+ // for parents with existing children, show a spinner on and highlight
730
+ // the 'new' row, otherwise highlight the parent row itself
731
+ var tree = navigationPanels[navigationPanels.length - 1].data('tree');
732
+ var parent = findRecord(tree, parentID);
733
+
734
+ if(modelWasSelected == undefined) {
735
+ if(parent.children.length == 0)
736
+ showSpinner(parentID);
737
+ else
738
+ showSpinner($('.record[data-record-id=' + parentID + '] > .child_elements > li > h1.new'));
739
+ }
740
+
741
+ // load the blank default record
742
+ $('#record').load(htmlURL + '?action=new&model=' + modelID + '&parent=' + parentID, function(text, status, req) {
743
+ initialiseWidgets();
744
+ if(parent.children.length == 0)
745
+ highlightSelectedRow(parentID);
746
+ else
747
+ highlightSelectedRow($('.record[data-record-id=' + parentID + '] > .child_elements > li > h1.new'));
748
+ });
749
+ }
750
+
751
+ $('a.model').click(function(event) {
752
+ var parentID = $('#new_model_panel').attr('data-parent-id');
753
+ var modelID = $(this).attr('data-model-id');
754
+ event.preventDefault();
755
+
756
+ $(this).find('.spinner').show();
757
+ $(this).find('.icon').hide();
758
+ loadNewRecord(modelID, parentID, true);
759
+ });
760
+
761
+ $('#add_domain').click(function(event) {
762
+ var domain = $('#new_domain').val();
763
+ if(domain != '') {
764
+ $('#domains_list').append("<li><input type='hidden' name='domains[]' value='" + domain + "'>" + domain + " - <a href='#' class='remove_domain'>remove</a></li>");
765
+ $('#new_domain').val('')
766
+ }
767
+ event.preventDefault();
768
+ });
769
+
770
+ $('.remove_domain').live('click', function(event) {
771
+ $(event.target).closest('li').remove();
772
+ });
773
+
774
+
775
+
776
+
777
+
778
+ // syncing
779
+ var SYNC_URL = '/admin/sync.json';
780
+ var syncing = false;
781
+
782
+ function showSyncStatus(status) {
783
+ jQuery('#site_menu > p').queue(function () {
784
+ jQuery('#site_menu > p span').html(status);
785
+ jQuery(this).fadeIn();
786
+ jQuery(this).dequeue();
787
+ });
788
+ }
789
+
790
+ function hideSyncStatus() {
791
+ syncing = false;
792
+ jQuery('#site_menu > p').queue(function () {
793
+ jQuery(this).fadeOut();
794
+ jQuery(this).dequeue();
795
+ });
796
+ }
797
+
798
+ function push(creating) {
799
+ showSyncStatus('Pushing changes');
800
+ var errorText = "Sorry, an error occurred while pushing changes to the remote server";
801
+
802
+ jQuery.ajax(SYNC_URL, {type: 'POST', success: function(data) {
803
+ if(!data.success) {
804
+ if(data.reason)
805
+ alert(errorText + ": " + data.reason);
806
+ else if(data.conflicts)
807
+ alert("The following files are in conflict and need to be resolved before pushing: " + data.conflicts.join(','));
808
+ else
809
+ alert(errorText + ".");
810
+ } else if(creating) {
811
+ window.open('http://' + data.remoteDomain + '/', 'livesite');
812
+ window.location.reload()
813
+ }
814
+ }, error: function(jqXHR, textStatus, errorThrown) {
815
+ alert(errorText + ".");
816
+ }, complete: function(jqXHR, textStatus) {
817
+ hideSyncStatus();
818
+ }});
819
+ }
820
+
821
+ $('.sync.push').live('click', function(event) {
822
+ if(syncing)
823
+ return;
824
+ else
825
+ syncing = true;
826
+ push();
827
+ });
828
+
829
+ $('.sync.create').live('click', function(event) {
830
+ if(syncing)
831
+ return;
832
+ else
833
+ syncing = true;
834
+ showSyncStatus('Creating site');
835
+
836
+ jQuery.ajax(SYNC_URL, {data: {remote: $(this).attr('data-sync-remote')}, type: 'POST', success: function(data) {
837
+ if(data.success) {
838
+ push(true);
839
+ } else {
840
+ alert("Sorry, an error occurred while creating this site on the remote server: " + data.reason);
841
+ hideSyncStatus();
842
+ }
843
+ }, error: function(jqXHR, textStatus, errorThrown) {
844
+ alert("Sorry, an error occurred while creating this site on the remote server.");
845
+ hideSyncStatus();
846
+ }});
847
+ });
848
+
849
+ $('.sync.pull').live('click', function(event) {
850
+ if(syncing)
851
+ return;
852
+ else
853
+ syncing = true;
854
+ showSyncStatus('Pulling changes');
855
+ var errorText = "Sorry, an error occurred while pulling changes from the remote server";
856
+
857
+ jQuery.ajax(SYNC_URL, {type: 'GET', success: function(data) {
858
+ if(!data.success) {
859
+ if(data.reason)
860
+ alert(errorText + ": " + data.reason);
861
+ else if(data.requires_push)
862
+ alert(errorText + ": No remote server is associated with this site");
863
+ else if(data.conflicts)
864
+ alert("The following files are in conflict and need to be resolved before pulling: " + data.conflicts.join(','));
865
+ else
866
+ alert(errorText + ".");
867
+ }
868
+ }, error: function(jqXHR, textStatus, errorThrown) {
869
+ alert(errorText + ".");
870
+ }, complete: function(jqXHR, textStatus) {
871
+ hideSyncStatus();
872
+ }});
873
+ });
874
+
875
+
876
+
877
+
878
+
879
+ // admin list page
880
+ function adminListPageValueExtractor(node) {
881
+ return $(node).attr('data-value');
882
+ }
883
+
884
+ function fixHeaders(table) {
885
+ var headers = table.find('th');
886
+ var cols = table.find('col');
887
+
888
+ headers.each(function(index, header) {
889
+ var header = $(header);
890
+ var offset = header.offset();
891
+ if(index == (headers.length - 1))
892
+ header.width(header.width() + 2);
893
+ else
894
+ header.width(header.width());
895
+ $(cols[index]).width(header.outerWidth());
896
+ header.css('left', offset.left + 'px');
897
+ header.css('top', (offset.top - 37) + 'px');
898
+ header.css('position', 'fixed');
899
+ });
900
+ }
901
+
902
+ function searchList() {
903
+ var terms = $('#search').val().split(' ');
904
+ $('#list_items table tbody tr').each(function(index, row) {
905
+ var match = false;
906
+ var text = [];
907
+
908
+ // extract the text of the cell of each row, separated by spaces
909
+ $(row).find('td').each(function(index, cell) {
910
+ text.push($(cell).text());
911
+ });
912
+ text = text.join(' ');
913
+
914
+ // determine if any of the terms are matched by the row text
915
+ for(var i = 0; i < terms.length; i++) {
916
+ if(text.indexOf(terms[i]) != -1) {
917
+ match = true;
918
+ break;
919
+ }
920
+ }
921
+
922
+ if(match)
923
+ $(row).css('display', 'table-row');
924
+ else
925
+ $(row).css('display', 'none');
926
+ });
927
+ }
928
+
929
+ $('#search').keyup(function() {
930
+ searchList();
931
+ });
932
+
933
+ $('#search').blur(function() {
934
+ searchList();
935
+ });
936
+
937
+ function highlightSelectedListRow(row) {
938
+ $('#list_items tbody tr').removeClass('selected');
939
+ if(row)
940
+ row.addClass('selected');
941
+ }
942
+
943
+ $('#list_items tbody tr').live('click', function() {
944
+ var row = $(this);
945
+ var recordID = row.attr('data-record-id');
946
+ $('#activity_spinner').fadeIn();
947
+
948
+ $('#record').load(htmlURL + '?id=' + recordID, function(text, status, req) {
949
+ $('#activity_spinner').fadeOut();
950
+ if(status == 'error') {
951
+ alert("Sorry, an error occurred loading this record. Please refresh the page and try again.");
952
+ } else {
953
+ highlightSelectedListRow(row);
954
+ initialiseWidgets();
955
+ $('#record').scrollTop(0);
956
+ }
957
+ });
958
+ });
959
+
960
+ function updateListRecord(json) {
961
+ var values = json.record;
962
+ var row = $('#list_items table tr[data-record-id=' + values['_id'] + ']').first();
963
+ $('#record_name').html(json.name);
964
+
965
+ if(row.length == 0) {
966
+ // insert a new row for the new record
967
+ row = $(json['_row_html']);
968
+ $('#list_items table tbody').append(row);
969
+ } else {
970
+ // update the row values
971
+ row.replaceWith(json['_row_html']);
972
+ row = $('#list_items table tr[data-record-id=' + values['_id'] + ']').first();
973
+ }
974
+
975
+ // tablesorter defers running update with setTimeout; work around
976
+ // this so redrawings occur after the cache has been updated
977
+ $('#list_items table').trigger('update');
978
+ setTimeout(function () {
979
+ var currentSort = $('#list_items table').first()[0].config.sortList;
980
+ $('#list_items table').trigger("sorton", [currentSort]);
981
+ highlightSelectedListRow(row);
982
+ }, 10);
983
+ }
984
+
985
+ $('.list #record .delete').live('click', function(event) {
986
+ event.preventDefault();
987
+ event.stopPropagation();
988
+ var recordID = $(event.target).attr('data-record-id');
989
+ var recordTypeName = $(event.target).attr('data-record-type');
990
+
991
+ if(confirm('Are you sure you want to delete this ' + recordTypeName + '?')) {
992
+ $('#delete_spinner').fadeIn();
993
+ $.ajax(jsonURL, {
994
+ data: {id: recordID, _method: 'delete'},
995
+ dataType: 'json',
996
+ type: 'post',
997
+
998
+ success: function(data, textStatus, jqXHR) {
999
+ $('#record').html('');
1000
+ $('#list_items table tr[data-record-id=' + recordID + ']').remove();
1001
+ $('#list_items table').trigger('update');
1002
+
1003
+ }, error: function(jqXHR, textStatus, errorThrown) {
1004
+ // FIXME: better error message
1005
+ alert('Sorry, an error occurred deleting this record. Please reload the page and try again.');
1006
+
1007
+ }, complete: function() {
1008
+ $('#delete_spinner').fadeOut();
1009
+ }
1010
+ });
1011
+ }
1012
+ });
1013
+
1014
+ $('#new_record').live('click', function(event) {
1015
+ event.preventDefault();
1016
+ event.stopPropagation();
1017
+ $('#activity_spinner').fadeIn();
1018
+
1019
+ $('#record').load(htmlURL + '?new=true', function(text, status, req) {
1020
+ $('#activity_spinner').fadeOut();
1021
+ if(status == 'error') {
1022
+ alert("Sorry, an error occurred loading a new record form. Please refresh the page and try again.");
1023
+ } else {
1024
+ highlightSelectedListRow();
1025
+ initialiseWidgets();
1026
+ $('#record').scrollTop(0);
1027
+ }
1028
+ });
1029
+ })
1030
+