typo 4.1 → 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (251) hide show
  1. data/Rakefile +1 -1
  2. data/TODO-4.2 +14 -0
  3. data/TODO.MULTIUSERS +45 -0
  4. data/app/controllers/admin/base_controller.rb +18 -0
  5. data/app/controllers/admin/general_controller.rb +14 -0
  6. data/app/controllers/application.rb +2 -1
  7. data/app/controllers/articles_controller.rb +18 -21
  8. data/app/helpers/admin/base_helper.rb +4 -4
  9. data/app/helpers/admin/feedback_helper.rb +3 -3
  10. data/app/helpers/application_helper.rb +2 -6
  11. data/app/helpers/sidebar_helper.rb +2 -2
  12. data/app/models/blog.rb +9 -1
  13. data/app/models/category.rb +9 -9
  14. data/app/models/comment.rb +1 -1
  15. data/app/models/content_state/presumed_ham.rb +2 -2
  16. data/app/models/resource.rb +2 -0
  17. data/app/views/admin/categories/_categories.rhtml +10 -6
  18. data/app/views/admin/categories/edit.rhtml +3 -1
  19. data/app/views/admin/comments/_form.rhtml +3 -3
  20. data/app/views/admin/comments/list.rhtml +7 -5
  21. data/app/views/admin/comments/new.rhtml +3 -1
  22. data/app/views/admin/comments/show.rhtml +3 -1
  23. data/app/views/admin/content/_articles.rhtml +1 -1
  24. data/app/views/admin/content/_form.rhtml +4 -2
  25. data/app/views/admin/content/new.rhtml +1 -0
  26. data/app/views/admin/content/preview.rhtml +8 -8
  27. data/app/views/admin/feedback/_item.rhtml +3 -1
  28. data/app/views/admin/feedback/list.rhtml +4 -4
  29. data/app/views/admin/general/index.rhtml +14 -1
  30. data/app/views/admin/pages/_form.rhtml +1 -1
  31. data/app/views/admin/pages/destroy.rhtml +1 -1
  32. data/app/views/admin/pages/new.rhtml +1 -0
  33. data/app/views/admin/shared/_edit.rhtml +2 -2
  34. data/app/views/layouts/administration.rhtml +5 -2
  35. data/app/views/layouts/minimal.rhtml +134 -2
  36. data/config/boot.rb +1 -1
  37. data/config/environment.rb +11 -3
  38. data/config/environments/test.rb +0 -7
  39. data/config/routes.rb +3 -0
  40. data/db/migrate/004_add_sidebars.rb +21 -3
  41. data/db/migrate/056_create_notifications.rb +1 -1
  42. data/db/migrate/062_add_sitealizer_plugin.rb +18 -0
  43. data/db/schema.mysql-v3.sql +217 -0
  44. data/db/schema.mysql.sql +31 -5
  45. data/db/schema.postgresql.sql +31 -6
  46. data/db/schema.rb +17 -7
  47. data/db/schema.sqlite.sql +31 -6
  48. data/db/schema.sqlserver.sql +32 -6
  49. data/db/schema_version +1 -1
  50. data/lang/de_DE.rb +493 -0
  51. data/lang/fr_FR.rb +28 -4
  52. data/lang/ro_RO.rb +554 -0
  53. data/lib/tasks/release.rake +7 -7
  54. data/lib/typo_version.rb +1 -1
  55. data/public/images/sitealizer/bar.gif +0 -0
  56. data/public/images/sitealizer/uv.png +0 -0
  57. data/public/images/sitealizer/vh.png +0 -0
  58. data/public/javascripts/tiny_mce/blank.htm +9 -0
  59. data/public/javascripts/tiny_mce/langs/en.js +41 -0
  60. data/public/javascripts/tiny_mce/license.txt +504 -0
  61. data/public/javascripts/tiny_mce/themes/advanced/about.htm +52 -0
  62. data/public/javascripts/tiny_mce/themes/advanced/anchor.htm +33 -0
  63. data/public/javascripts/tiny_mce/themes/advanced/charmap.htm +53 -0
  64. data/public/javascripts/tiny_mce/themes/advanced/color_picker.htm +13 -0
  65. data/public/javascripts/tiny_mce/themes/advanced/css/editor_content.css +58 -0
  66. data/public/javascripts/tiny_mce/themes/advanced/css/editor_popup.css +331 -0
  67. data/public/javascripts/tiny_mce/themes/advanced/css/editor_ui.css +97 -0
  68. data/public/javascripts/tiny_mce/themes/advanced/docs/en/about.htm +31 -0
  69. data/public/javascripts/tiny_mce/themes/advanced/docs/en/common_buttons.htm +162 -0
  70. data/public/javascripts/tiny_mce/themes/advanced/docs/en/create_accessible_content.htm +45 -0
  71. data/public/javascripts/tiny_mce/themes/advanced/docs/en/images/insert_anchor_window.gif +0 -0
  72. data/public/javascripts/tiny_mce/themes/advanced/docs/en/images/insert_image_window.gif +0 -0
  73. data/public/javascripts/tiny_mce/themes/advanced/docs/en/images/insert_link_window.gif +0 -0
  74. data/public/javascripts/tiny_mce/themes/advanced/docs/en/images/insert_table_window.gif +0 -0
  75. data/public/javascripts/tiny_mce/themes/advanced/docs/en/index.htm +27 -0
  76. data/public/javascripts/tiny_mce/themes/advanced/docs/en/insert_anchor_button.htm +32 -0
  77. data/public/javascripts/tiny_mce/themes/advanced/docs/en/insert_image_button.htm +65 -0
  78. data/public/javascripts/tiny_mce/themes/advanced/docs/en/insert_link_button.htm +33 -0
  79. data/public/javascripts/tiny_mce/themes/advanced/docs/en/insert_table_button.htm +71 -0
  80. data/public/javascripts/tiny_mce/themes/advanced/docs/en/style.css +28 -0
  81. data/public/javascripts/tiny_mce/themes/advanced/editor_template.js +1 -0
  82. data/public/javascripts/tiny_mce/themes/advanced/editor_template_src.js +1534 -0
  83. data/public/javascripts/tiny_mce/themes/advanced/image.htm +100 -0
  84. data/public/javascripts/tiny_mce/themes/advanced/images/anchor.gif +0 -0
  85. data/public/javascripts/tiny_mce/themes/advanced/images/anchor_symbol.gif +0 -0
  86. data/public/javascripts/tiny_mce/themes/advanced/images/backcolor.gif +0 -0
  87. data/public/javascripts/tiny_mce/themes/advanced/images/bold.gif +0 -0
  88. data/public/javascripts/tiny_mce/themes/advanced/images/bold_de_se.gif +0 -0
  89. data/public/javascripts/tiny_mce/themes/advanced/images/bold_es.gif +0 -0
  90. data/public/javascripts/tiny_mce/themes/advanced/images/bold_fr.gif +0 -0
  91. data/public/javascripts/tiny_mce/themes/advanced/images/bold_ru.gif +0 -0
  92. data/public/javascripts/tiny_mce/themes/advanced/images/bold_tw.gif +0 -0
  93. data/public/javascripts/tiny_mce/themes/advanced/images/browse.gif +0 -0
  94. data/public/javascripts/tiny_mce/themes/advanced/images/bullist.gif +0 -0
  95. data/public/javascripts/tiny_mce/themes/advanced/images/button_menu.gif +0 -0
  96. data/public/javascripts/tiny_mce/themes/advanced/images/buttons.gif +0 -0
  97. data/public/javascripts/tiny_mce/themes/advanced/images/cancel_button_bg.gif +0 -0
  98. data/public/javascripts/tiny_mce/themes/advanced/images/charmap.gif +0 -0
  99. data/public/javascripts/tiny_mce/themes/advanced/images/cleanup.gif +0 -0
  100. data/public/javascripts/tiny_mce/themes/advanced/images/close.gif +0 -0
  101. data/public/javascripts/tiny_mce/themes/advanced/images/code.gif +0 -0
  102. data/public/javascripts/tiny_mce/themes/advanced/images/color.gif +0 -0
  103. data/public/javascripts/tiny_mce/themes/advanced/images/copy.gif +0 -0
  104. data/public/javascripts/tiny_mce/themes/advanced/images/custom_1.gif +0 -0
  105. data/public/javascripts/tiny_mce/themes/advanced/images/cut.gif +0 -0
  106. data/public/javascripts/tiny_mce/themes/advanced/images/forecolor.gif +0 -0
  107. data/public/javascripts/tiny_mce/themes/advanced/images/help.gif +0 -0
  108. data/public/javascripts/tiny_mce/themes/advanced/images/hr.gif +0 -0
  109. data/public/javascripts/tiny_mce/themes/advanced/images/image.gif +0 -0
  110. data/public/javascripts/tiny_mce/themes/advanced/images/indent.gif +0 -0
  111. data/public/javascripts/tiny_mce/themes/advanced/images/insert_button_bg.gif +0 -0
  112. data/public/javascripts/tiny_mce/themes/advanced/images/italic.gif +0 -0
  113. data/public/javascripts/tiny_mce/themes/advanced/images/italic_de_se.gif +0 -0
  114. data/public/javascripts/tiny_mce/themes/advanced/images/italic_es.gif +0 -0
  115. data/public/javascripts/tiny_mce/themes/advanced/images/italic_ru.gif +0 -0
  116. data/public/javascripts/tiny_mce/themes/advanced/images/italic_tw.gif +0 -0
  117. data/public/javascripts/tiny_mce/themes/advanced/images/justifycenter.gif +0 -0
  118. data/public/javascripts/tiny_mce/themes/advanced/images/justifyfull.gif +0 -0
  119. data/public/javascripts/tiny_mce/themes/advanced/images/justifyleft.gif +0 -0
  120. data/public/javascripts/tiny_mce/themes/advanced/images/justifyright.gif +0 -0
  121. data/public/javascripts/tiny_mce/themes/advanced/images/link.gif +0 -0
  122. data/public/javascripts/tiny_mce/themes/advanced/images/menu_check.gif +0 -0
  123. data/public/javascripts/tiny_mce/themes/advanced/images/newdocument.gif +0 -0
  124. data/public/javascripts/tiny_mce/themes/advanced/images/numlist.gif +0 -0
  125. data/public/javascripts/tiny_mce/themes/advanced/images/opacity.png +0 -0
  126. data/public/javascripts/tiny_mce/themes/advanced/images/outdent.gif +0 -0
  127. data/public/javascripts/tiny_mce/themes/advanced/images/paste.gif +0 -0
  128. data/public/javascripts/tiny_mce/themes/advanced/images/redo.gif +0 -0
  129. data/public/javascripts/tiny_mce/themes/advanced/images/removeformat.gif +0 -0
  130. data/public/javascripts/tiny_mce/themes/advanced/images/separator.gif +0 -0
  131. data/public/javascripts/tiny_mce/themes/advanced/images/spacer.gif +0 -0
  132. data/public/javascripts/tiny_mce/themes/advanced/images/statusbar_resize.gif +0 -0
  133. data/public/javascripts/tiny_mce/themes/advanced/images/strikethrough.gif +0 -0
  134. data/public/javascripts/tiny_mce/themes/advanced/images/sub.gif +0 -0
  135. data/public/javascripts/tiny_mce/themes/advanced/images/sup.gif +0 -0
  136. data/public/javascripts/tiny_mce/themes/advanced/images/underline.gif +0 -0
  137. data/public/javascripts/tiny_mce/themes/advanced/images/underline_es.gif +0 -0
  138. data/public/javascripts/tiny_mce/themes/advanced/images/underline_fr.gif +0 -0
  139. data/public/javascripts/tiny_mce/themes/advanced/images/underline_ru.gif +0 -0
  140. data/public/javascripts/tiny_mce/themes/advanced/images/underline_tw.gif +0 -0
  141. data/public/javascripts/tiny_mce/themes/advanced/images/undo.gif +0 -0
  142. data/public/javascripts/tiny_mce/themes/advanced/images/unlink.gif +0 -0
  143. data/public/javascripts/tiny_mce/themes/advanced/images/visualaid.gif +0 -0
  144. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tab_bg.gif +0 -0
  145. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tab_end.gif +0 -0
  146. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tab_sel_bg.gif +0 -0
  147. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tab_sel_end.gif +0 -0
  148. data/public/javascripts/tiny_mce/themes/advanced/images/xp/tabs_bg.gif +0 -0
  149. data/public/javascripts/tiny_mce/themes/advanced/jscripts/about.js +75 -0
  150. data/public/javascripts/tiny_mce/themes/advanced/jscripts/anchor.js +74 -0
  151. data/public/javascripts/tiny_mce/themes/advanced/jscripts/charmap.js +326 -0
  152. data/public/javascripts/tiny_mce/themes/advanced/jscripts/color_picker.js +108 -0
  153. data/public/javascripts/tiny_mce/themes/advanced/jscripts/image.js +81 -0
  154. data/public/javascripts/tiny_mce/themes/advanced/jscripts/link.js +70 -0
  155. data/public/javascripts/tiny_mce/themes/advanced/jscripts/source_editor.js +60 -0
  156. data/public/javascripts/tiny_mce/themes/advanced/langs/en.js +82 -0
  157. data/public/javascripts/tiny_mce/themes/advanced/link.htm +100 -0
  158. data/public/javascripts/tiny_mce/themes/advanced/source_editor.htm +32 -0
  159. data/public/javascripts/tiny_mce/tiny_mce.js +1 -0
  160. data/public/javascripts/tiny_mce/tiny_mce_popup.js +288 -0
  161. data/public/javascripts/tiny_mce/tiny_mce_src.js +7284 -0
  162. data/public/javascripts/tiny_mce/utils/editable_selects.js +61 -0
  163. data/public/javascripts/tiny_mce/utils/form_utils.js +210 -0
  164. data/public/javascripts/tiny_mce/utils/mclayer.js +210 -0
  165. data/public/javascripts/tiny_mce/utils/mctabs.js +74 -0
  166. data/public/javascripts/tiny_mce/utils/validate.js +219 -0
  167. data/public/stylesheets/administration.css +5 -1
  168. data/public/stylesheets/minimal.css +1 -0
  169. data/test/functional/admin/categories_controller_test.rb +2 -2
  170. data/test/functional/xml_controller_test.rb +72 -40
  171. data/test/test_helper.rb +1 -17
  172. data/test/unit/article_test.rb +1 -1
  173. data/test/unit/trigger_test.rb +1 -1
  174. data/themes/scribbish/views/articles/_comment.rhtml +13 -17
  175. data/themes/scribbish/views/articles/_comment_form.rhtml +7 -5
  176. data/themes/scribbish/views/articles/_comment_list.rhtml +7 -0
  177. data/themes/scribbish/views/articles/read.rhtml +1 -1
  178. data/vendor/plugins/aimpresence_sidebar/views/content.rhtml +1 -1
  179. data/vendor/plugins/archives_sidebar/views/content.rhtml +1 -1
  180. data/vendor/plugins/audioscrobbler_sidebar/MAINTAINERS +26 -0
  181. data/vendor/plugins/audioscrobbler_sidebar/MIT-LICENSE +21 -0
  182. data/vendor/plugins/audioscrobbler_sidebar/README +27 -0
  183. data/vendor/plugins/backpack_sidebar/MAINTAINERS +26 -0
  184. data/vendor/plugins/backpack_sidebar/MIT-LICENSE +21 -0
  185. data/vendor/plugins/backpack_sidebar/README +27 -0
  186. data/vendor/plugins/category_sidebar/views/content.rhtml +1 -1
  187. data/vendor/plugins/sitealizer/CHANGELOG +6 -0
  188. data/vendor/plugins/sitealizer/LICENSE +22 -0
  189. data/vendor/plugins/sitealizer/README +82 -0
  190. data/vendor/plugins/sitealizer/Rakefile +22 -0
  191. data/vendor/plugins/sitealizer/init.rb +24 -0
  192. data/vendor/plugins/sitealizer/install.rb +22 -0
  193. data/vendor/plugins/sitealizer/lib/app/assets/images/bar.gif +0 -0
  194. data/vendor/plugins/sitealizer/lib/app/assets/images/uv.png +0 -0
  195. data/vendor/plugins/sitealizer/lib/app/assets/images/vh.png +0 -0
  196. data/vendor/plugins/sitealizer/lib/app/controllers/sitealizer_controller.rb +118 -0
  197. data/vendor/plugins/sitealizer/lib/app/models/site_tracker.rb +145 -0
  198. data/vendor/plugins/sitealizer/lib/app/views/layouts/sitealizer.rhtml +66 -0
  199. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_browsers.rhtml +23 -0
  200. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_daily_stats.rhtml +67 -0
  201. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_hits_summary.rhtml +0 -0
  202. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_hosts.rhtml +21 -0
  203. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_keywords.rhtml +19 -0
  204. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_languages.rhtml +21 -0
  205. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_main_frame.rhtml +84 -0
  206. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_monthly_hits.rhtml +67 -0
  207. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_page_urls.rhtml +20 -0
  208. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_platforms.rhtml +21 -0
  209. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_referers.rhtml +22 -0
  210. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_robots.rhtml +19 -0
  211. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/_search_engines.rhtml +19 -0
  212. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/hourly_stats.rhtml +39 -0
  213. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/index.rhtml +8 -0
  214. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/login.rhtml +20 -0
  215. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/menu.rhtml +74 -0
  216. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/referrer_stats.rhtml +20 -0
  217. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/search_stats.rhtml +25 -0
  218. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/summary.rhtml +22 -0
  219. data/vendor/plugins/sitealizer/lib/app/views/sitealizer/visitor_info.rhtml +30 -0
  220. data/vendor/plugins/sitealizer/lib/config.yml +18 -0
  221. data/vendor/plugins/sitealizer/lib/sitealizer/parser.rb +347 -0
  222. data/vendor/plugins/sitealizer/lib/sitealizer.rb +78 -0
  223. data/vendor/plugins/sitealizer/lib/tasks/sitealizer.rake +36 -0
  224. data/vendor/plugins/sitealizer/test/fixtures/sitealizer.yml +89 -0
  225. data/vendor/plugins/sitealizer/test/sitealizer_controller_test.rb +208 -0
  226. data/vendor/plugins/sitealizer/test/sitealizer_parser_test.rb +169 -0
  227. data/vendor/plugins/sitealizer/test/test_helper.rb +7 -0
  228. data/vendor/plugins/tada_sidebar/MAINTAINERS +26 -0
  229. data/vendor/plugins/tada_sidebar/MIT-LICENSE +21 -0
  230. data/vendor/plugins/tada_sidebar/README +27 -0
  231. data/vendor/plugins/tag_sidebar/views/content.rhtml +1 -1
  232. data/vendor/plugins/tiny_mce/README +10 -0
  233. data/vendor/plugins/tiny_mce/Rakefile +22 -0
  234. data/vendor/plugins/tiny_mce/TODO +2 -0
  235. data/vendor/plugins/tiny_mce/changelog +1017 -0
  236. data/vendor/plugins/tiny_mce/init.rb +3 -0
  237. data/vendor/plugins/tiny_mce/install.rb +1 -0
  238. data/vendor/plugins/tiny_mce/lib/tiny_mce.rb +36 -0
  239. data/vendor/plugins/tiny_mce/lib/tiny_mce_helper.rb +48 -0
  240. data/vendor/plugins/tiny_mce/tasks/tiny_mce.rake +40 -0
  241. data/vendor/plugins/tiny_mce/test/helper_testcase.rb +38 -0
  242. data/vendor/plugins/tiny_mce/test/tiny_mce_helper_test.rb +67 -0
  243. data/vendor/plugins/tiny_mce/test/tiny_mce_test.rb +85 -0
  244. data/vendor/plugins/tiny_mce/tiny_mce_options.yml +121 -0
  245. data/vendor/plugins/xbox_sidebar/MAINTAINERS +26 -0
  246. data/vendor/plugins/xbox_sidebar/MIT-LICENSE +21 -0
  247. data/vendor/plugins/xbox_sidebar/README +27 -0
  248. data/vendor/plugins/xml_sidebar/lib/xml_sidebar.rb +1 -1
  249. data/vendor/plugins/xml_sidebar/views/content.rhtml +4 -4
  250. metadata +220 -4
  251. data/TODO-4.1 +0 -16
@@ -0,0 +1,219 @@
1
+ /**
2
+ * $Id: validate.js 65 2006-08-24 15:54:55Z spocke $
3
+ *
4
+ * Various form validation methods.
5
+ *
6
+ * @author Moxiecode
7
+ * @copyright Copyright � 2004-2006, Moxiecode Systems AB, All rights reserved.
8
+ */
9
+
10
+ /**
11
+ // String validation:
12
+
13
+ if (!Validator.isEmail('myemail'))
14
+ alert('Invalid email.');
15
+
16
+ // Form validation:
17
+
18
+ var f = document.forms['myform'];
19
+
20
+ if (!Validator.isEmail(f.myemail))
21
+ alert('Invalid email.');
22
+ */
23
+
24
+ var Validator = {
25
+ isEmail : function(s) {
26
+ return this.test(s, '^[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+@[-!#$%&\'*+\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&\'*+\\./0-9=?A-Z^_`a-z{|}~]+$');
27
+ },
28
+
29
+ isAbsUrl : function(s) {
30
+ return this.test(s, '^(news|telnet|nttp|file|http|ftp|https)://[-A-Za-z0-9\\.]+\\/?.*$');
31
+ },
32
+
33
+ isSize : function(s) {
34
+ return this.test(s, '^[0-9]+(px|%)?$');
35
+ },
36
+
37
+ isId : function(s) {
38
+ return this.test(s, '^[A-Za-z_]([A-Za-z0-9_])*$');
39
+ },
40
+
41
+ isEmpty : function(s) {
42
+ var nl, i;
43
+
44
+ if (s.nodeName == 'SELECT' && s.selectedIndex < 1)
45
+ return true;
46
+
47
+ if (s.type == 'checkbox' && !s.checked)
48
+ return true;
49
+
50
+ if (s.type == 'radio') {
51
+ for (i=0, nl = s.form.elements; i<nl.length; i++) {
52
+ if (nl[i].type == "radio" && nl[i].name == s.name && nl[i].checked)
53
+ return false;
54
+ }
55
+
56
+ return true;
57
+ }
58
+
59
+ return new RegExp('^\\s*$').test(s.nodeType == 1 ? s.value : s);
60
+ },
61
+
62
+ isNumber : function(s, d) {
63
+ return !isNaN(s.nodeType == 1 ? s.value : s) && (!d || !this.test(s, '^-?[0-9]*\\.[0-9]*$'));
64
+ },
65
+
66
+ test : function(s, p) {
67
+ s = s.nodeType == 1 ? s.value : s;
68
+
69
+ return s == '' || new RegExp(p).test(s);
70
+ }
71
+ };
72
+
73
+ var AutoValidator = {
74
+ settings : {
75
+ id_cls : 'id',
76
+ int_cls : 'int',
77
+ url_cls : 'url',
78
+ number_cls : 'number',
79
+ email_cls : 'email',
80
+ size_cls : 'size',
81
+ required_cls : 'required',
82
+ invalid_cls : 'invalid',
83
+ min_cls : 'min',
84
+ max_cls : 'max'
85
+ },
86
+
87
+ init : function(s) {
88
+ var n;
89
+
90
+ for (n in s)
91
+ this.settings[n] = s[n];
92
+ },
93
+
94
+ validate : function(f) {
95
+ var i, nl, s = this.settings, c = 0;
96
+
97
+ nl = this.tags(f, 'label');
98
+ for (i=0; i<nl.length; i++)
99
+ this.removeClass(nl[i], s.invalid_cls);
100
+
101
+ c += this.validateElms(f, 'input');
102
+ c += this.validateElms(f, 'select');
103
+ c += this.validateElms(f, 'textarea');
104
+
105
+ return c == 3;
106
+ },
107
+
108
+ invalidate : function(n) {
109
+ this.mark(n.form, n);
110
+ },
111
+
112
+ reset : function(e) {
113
+ var t = new Array('label', 'input', 'select', 'textarea');
114
+ var i, j, nl, s = this.settings;
115
+
116
+ if (e == null)
117
+ return;
118
+
119
+ for (i=0; i<t.length; i++) {
120
+ nl = this.tags(e.form ? e.form : e, t[i]);
121
+ for (j=0; j<nl.length; j++)
122
+ this.removeClass(nl[j], s.invalid_cls);
123
+ }
124
+ },
125
+
126
+ validateElms : function(f, e) {
127
+ var nl, i, n, s = this.settings, st = true, va = Validator, v;
128
+
129
+ nl = this.tags(f, e);
130
+ for (i=0; i<nl.length; i++) {
131
+ n = nl[i];
132
+
133
+ this.removeClass(n, s.invalid_cls);
134
+
135
+ if (this.hasClass(n, s.required_cls) && va.isEmpty(n))
136
+ st = this.mark(f, n);
137
+
138
+ if (this.hasClass(n, s.number_cls) && !va.isNumber(n))
139
+ st = this.mark(f, n);
140
+
141
+ if (this.hasClass(n, s.int_cls) && !va.isNumber(n, true))
142
+ st = this.mark(f, n);
143
+
144
+ if (this.hasClass(n, s.url_cls) && !va.isAbsUrl(n))
145
+ st = this.mark(f, n);
146
+
147
+ if (this.hasClass(n, s.email_cls) && !va.isEmail(n))
148
+ st = this.mark(f, n);
149
+
150
+ if (this.hasClass(n, s.size_cls) && !va.isSize(n))
151
+ st = this.mark(f, n);
152
+
153
+ if (this.hasClass(n, s.id_cls) && !va.isId(n))
154
+ st = this.mark(f, n);
155
+
156
+ if (this.hasClass(n, s.min_cls, true)) {
157
+ v = this.getNum(n, s.min_cls);
158
+
159
+ if (isNaN(v) || parseInt(n.value) < parseInt(v))
160
+ st = this.mark(f, n);
161
+ }
162
+
163
+ if (this.hasClass(n, s.max_cls, true)) {
164
+ v = this.getNum(n, s.max_cls);
165
+
166
+ if (isNaN(v) || parseInt(n.value) > parseInt(v))
167
+ st = this.mark(f, n);
168
+ }
169
+ }
170
+
171
+ return st;
172
+ },
173
+
174
+ hasClass : function(n, c, d) {
175
+ return new RegExp('\\b' + c + (d ? '[0-9]+' : '') + '\\b', 'g').test(n.className);
176
+ },
177
+
178
+ getNum : function(n, c) {
179
+ c = n.className.match(new RegExp('\\b' + c + '([0-9]+)\\b', 'g'))[0];
180
+ c = c.replace(/[^0-9]/g, '');
181
+
182
+ return c;
183
+ },
184
+
185
+ addClass : function(n, c, b) {
186
+ var o = this.removeClass(n, c);
187
+ n.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c;
188
+ },
189
+
190
+ removeClass : function(n, c) {
191
+ c = n.className.replace(new RegExp("(^|\\s+)" + c + "(\\s+|$)"), ' ');
192
+ return n.className = c != ' ' ? c : '';
193
+ },
194
+
195
+ tags : function(f, s) {
196
+ return f.getElementsByTagName(s);
197
+ },
198
+
199
+ mark : function(f, n) {
200
+ var s = this.settings;
201
+
202
+ this.addClass(n, s.invalid_cls);
203
+ this.markLabels(f, n, s.invalid_cls);
204
+
205
+ return false;
206
+ },
207
+
208
+ markLabels : function(f, n, ic) {
209
+ var nl, i;
210
+
211
+ nl = this.tags(f, "label");
212
+ for (i=0; i<nl.length; i++) {
213
+ if (nl[i].getAttribute("for") == n.id || nl[i].htmlFor == n.id)
214
+ this.addClass(nl[i], ic);
215
+ }
216
+
217
+ return null;
218
+ }
219
+ };
@@ -228,11 +228,15 @@ h3 {
228
228
 
229
229
  /* @group Table Listings */
230
230
 
231
- .operation {
231
+ td.operation {
232
232
  width: 25px;
233
233
  text-align: center;
234
234
  }
235
235
 
236
+ th.operation {
237
+ text-align: center;
238
+ }
239
+
236
240
  .list {
237
241
  clear: left;
238
242
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  body {
4
4
  font: 1em/1.2em Arial, Verdana, Helvetica, sans-serif;
5
+ background: #f00;
5
6
  }
6
7
 
7
8
  #main {
@@ -90,9 +90,9 @@ class Admin::CategoriesControllerTest < Test::Unit::TestCase
90
90
  assert_response :success
91
91
  assert_template "_categories"
92
92
  assert_tag :tag => "table",
93
- :children => { :count => Category.count + 1,
93
+ :children => { :count => Category.count,
94
94
  :only => { :tag => "tr",
95
- :children => { :count => 3,
95
+ :children => { :count => 6,
96
96
  :only => { :tag => /t[dh]/ } } } }
97
97
  end
98
98
 
@@ -33,6 +33,11 @@ class XmlControllerTest < Test::Unit::TestCase
33
33
  fixtures :contents, :categories, :categorizations, :tags,
34
34
  :articles_tags, :users, :blogs, :resources
35
35
 
36
+ def assert_select(*args, &block)
37
+ @html_document ||= HTML::Document.new(@response.body, false, true)
38
+ super(*args,&block)
39
+ end
40
+
36
41
  def setup
37
42
  @controller = XmlController.new
38
43
  @request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
@@ -87,7 +92,7 @@ class XmlControllerTest < Test::Unit::TestCase
87
92
  assert_xml @response.body
88
93
  assert_feedvalidator @response.body, :todo
89
94
 
90
- assert_rss20(7)
95
+ assert_rss20
91
96
  end
92
97
 
93
98
  def test_feed_rss20_comments
@@ -96,7 +101,7 @@ class XmlControllerTest < Test::Unit::TestCase
96
101
  assert_xml @response.body
97
102
  assert_feedvalidator @response.body
98
103
 
99
- assert_rss20(3)
104
+ assert_rss20
100
105
  end
101
106
 
102
107
  def test_feed_rss20_trackbacks
@@ -104,8 +109,7 @@ class XmlControllerTest < Test::Unit::TestCase
104
109
  assert_response :success
105
110
  assert_xml @response.body
106
111
  assert_feedvalidator @response.body
107
-
108
- assert_rss20(3)
112
+ assert_rss20
109
113
  end
110
114
 
111
115
  def test_feed_rss20_article
@@ -114,7 +118,7 @@ class XmlControllerTest < Test::Unit::TestCase
114
118
  assert_xml @response.body
115
119
  assert_feedvalidator @response.body, :todo
116
120
 
117
- assert_rss20(2)
121
+ assert_rss20
118
122
  end
119
123
 
120
124
  def test_feed_rss20_category
@@ -123,7 +127,7 @@ class XmlControllerTest < Test::Unit::TestCase
123
127
  assert_xml @response.body
124
128
  assert_feedvalidator @response.body, :todo
125
129
 
126
- assert_rss20(3)
130
+ assert_rss20
127
131
  end
128
132
 
129
133
  def test_feed_rss20_tag
@@ -132,7 +136,7 @@ class XmlControllerTest < Test::Unit::TestCase
132
136
  assert_xml @response.body
133
137
  assert_feedvalidator @response.body, :todo
134
138
 
135
- assert_rss20(2)
139
+ assert_rss20
136
140
  end
137
141
 
138
142
  def test_feed_atom10_feed
@@ -145,7 +149,7 @@ class XmlControllerTest < Test::Unit::TestCase
145
149
  assert_equal(assigns(:items).sort { |a, b| b.created_at <=> a.created_at },
146
150
  assigns(:items))
147
151
 
148
- assert_atom10(7)
152
+ assert_atom10
149
153
  end
150
154
 
151
155
  def test_feed_atom10_comments
@@ -157,9 +161,9 @@ class XmlControllerTest < Test::Unit::TestCase
157
161
  assert_equal(assigns(:items).sort { |a, b| b.created_at <=> a.created_at },
158
162
  assigns(:items))
159
163
 
160
- assert_atom10(3)
164
+ assert_atom10
161
165
 
162
- assert_xpath('//title[@type="html"]')
166
+ assert_select 'title[type=html]'
163
167
  end
164
168
 
165
169
  def test_feed_atom10_trackbacks
@@ -171,10 +175,10 @@ class XmlControllerTest < Test::Unit::TestCase
171
175
  assert_equal(assigns(:items).sort { |a, b| b.created_at <=> a.created_at },
172
176
  assigns(:items))
173
177
 
174
- assert_atom10(3)
178
+ assert_atom10
175
179
 
176
- assert_xpath('//title[@type="html"]')
177
- assert_xpath('//summary', "Trackback entry has no summaries")
180
+ assert_select 'title[type=html]'
181
+ assert_select 'summary'
178
182
  end
179
183
 
180
184
  def test_feed_atom10_article
@@ -186,7 +190,7 @@ class XmlControllerTest < Test::Unit::TestCase
186
190
  assert_equal(assigns(:items).sort { |a, b| b.created_at <=> a.created_at },
187
191
  assigns(:items))
188
192
 
189
- assert_atom10(2)
193
+ assert_atom10
190
194
  end
191
195
 
192
196
  def test_feed_atom10_category
@@ -198,7 +202,7 @@ class XmlControllerTest < Test::Unit::TestCase
198
202
  assert_equal(assigns(:items).sort { |a, b| b.created_at <=> a.created_at },
199
203
  assigns(:items))
200
204
 
201
- assert_atom10(3)
205
+ assert_atom10
202
206
  end
203
207
 
204
208
  def test_feed_atom10_tag
@@ -210,7 +214,7 @@ class XmlControllerTest < Test::Unit::TestCase
210
214
  assert_equal(assigns(:items).sort { |a, b| b.created_at <=> a.created_at },
211
215
  assigns(:items))
212
216
 
213
- assert_atom10(2)
217
+ assert_atom10
214
218
  end
215
219
 
216
220
  def test_articlerss
@@ -242,7 +246,10 @@ class XmlControllerTest < Test::Unit::TestCase
242
246
  get :feed, :format => 'rss20', :type => 'feed'
243
247
  assert_response :success
244
248
 
245
- assert_equal contents(:article2).created_at.rfc822, get_xpath('/rss/channel/item[title="Article 2!"]/pubDate').first.text
249
+ assert_select 'rss:root > channel > item' do
250
+ assert_select '> title', :text => 'Article 2!'
251
+ assert_select '~pubDate', :text => contents(:article2).created_at.rfc822
252
+ end
246
253
  end
247
254
 
248
255
  def test_rsd
@@ -277,16 +284,17 @@ class XmlControllerTest < Test::Unit::TestCase
277
284
  get :feed, :format => 'atom10', :type => 'feed'
278
285
  assert_response :success
279
286
  assert_match /extended content/, @response.body
280
- assert_not_equal 0, get_xpath(%{//summary]}).size, "Extended feed has no summaries"
281
- assert_not_equal 0, get_xpath(%{//content]}).size, "Extended feed has no content"
287
+ assert_select 'summary'
288
+ assert_select 'content'
289
+ end
282
290
 
283
- @controller = XmlController.new
291
+ def test_extended_atom10_with_extended_on_rss_set_to_false
284
292
  set_extended_on_rss false
285
293
  get :feed, :format => 'atom10', :type => 'feed'
286
294
  assert_response :success
287
295
  assert_no_match /extended content/, @response.body
288
- assert_not_equal 0, get_xpath(%{//summary]}).size, "Non-Extended feed has no summaries"
289
- assert_equal 0, get_xpath(%{//content]}).size, "Non-extended feed has content"
296
+ assert_select 'summary'
297
+ assert_select ':not(content)'
290
298
  end
291
299
 
292
300
  def test_xml_atom10
@@ -294,7 +302,10 @@ class XmlControllerTest < Test::Unit::TestCase
294
302
  assert_response :success
295
303
 
296
304
  # titles are escaped html
297
- assert_xpath('//entry/title[text()="Associations aren\'t :dependent =&amp;gt; true anymore" and @type="html"]')
305
+ assert_select 'entry' do
306
+ assert_select '> title', :text => "Associations aren\'t :dependent =&amp;gt; true anymore"
307
+ assert_select '> title[type=html]'
308
+ end
298
309
 
299
310
  # categories are well formed
300
311
  assert_match /this &amp; that/, @response.body
@@ -305,33 +316,54 @@ class XmlControllerTest < Test::Unit::TestCase
305
316
  assert_response :success
306
317
 
307
318
  # There's an enclosure in there somewhere
308
- assert_xpath('/rss/channel/item/enclosure')
319
+ assert_select('rss:root > channel > item > enclosure')
309
320
 
310
321
  # There's an enclosure attached to the node with the title "Article 1!"
311
- assert_xpath('/rss/channel/item[title="Article 1!"]/enclosure')
312
- assert_xpath('/rss/channel/item[title="Article 2!"]/enclosure')
313
-
322
+ assert_select 'rss:root > channel > item' do
323
+ assert_select '>title', :text => 'Article 1!' do
324
+ assert_select '~enclosure', :count => 1
325
+ end
326
+ end
327
+ # And Article 2
328
+ assert_select 'rss:root > channel > item' do
329
+ assert_select '>title', :text => 'Article 2!' do
330
+ assert_select '~enclosure', :count => 1
331
+ end
332
+ end
314
333
  # Article 3 exists, but has no enclosure
315
- assert_xpath('/rss/channel/item[title="Article 3!"]')
316
- assert_not_xpath('/rss/channel/item[title="Article 3!"]/enclosure')
334
+ assert_select 'rss:root > channel > item' do
335
+ assert_select '>title', :text => 'Article 3!' do
336
+ assert_select '~enclosure', :count => 0
337
+ end
338
+ end
317
339
  end
318
340
 
319
341
  def test_enclosure_atom10
320
342
  get :feed, :format => 'atom10', :type => 'feed'
321
343
  assert_response :success
322
344
 
323
- # There's an enclosure in there somewhere
324
- assert_xpath('/feed/entry/link[@rel="enclosure"]')
325
-
326
345
  # There's an enclosure attached to "Article 1!" with a length
327
- assert_xpath('/feed/entry[title="Article 1!"]/link[@rel="enclosure" and @length]')
346
+ assert_select 'feed > entry' do
347
+ assert_select '> title', :text => 'Article 1!' do
348
+ assert_select '~ link' do
349
+ assert_select '[rel=enclosure][length]'
350
+ end
351
+ end
352
+ end
328
353
 
329
354
  # There's an enclosure attached to "Article 2!" with no length
330
- assert_xpath('/feed/entry[title="Article 2!"]/link[@rel="enclosure" and not(@length)]')
355
+ assert_select 'feed > entry' do
356
+ assert_select '> title', :text => "Article 2!" do
357
+ assert_select '~ link[rel=enclosure]:not([length])'
358
+ end
359
+ end
331
360
 
332
361
  # Article 3 exists, but has no enclosure
333
- assert_xpath('/feed/entry[title="Article 3!"]')
334
- assert_not_xpath('/feed/entry[title="Article 3!"]/link[@rel="enclosure"]')
362
+ assert_select 'feed > entry' do
363
+ assert_select '> title', :text => "Article 3!" do
364
+ assert_select '~ :not(link[rel=enclosure])'
365
+ end
366
+ end
335
367
  end
336
368
 
337
369
  def test_itunes
@@ -349,12 +381,12 @@ class XmlControllerTest < Test::Unit::TestCase
349
381
  assert_xml @response.body
350
382
  end
351
383
 
352
- def assert_rss20(items)
353
- assert_equal 1, get_xpath(%{/rss[@version="2.0"]/channel[count(child::item)=#{items}]}).size, "RSS 2.0 feed has wrong number of channel/item nodes"
384
+ def assert_rss20
385
+ assert_select 'rss:root[version=2.0] > channel item', :count => assigns(:items).size
354
386
  end
355
387
 
356
- def assert_atom10(entries)
357
- assert_equal 1, get_xpath(%{/feed[@xmlns="http://www.w3.org/2005/Atom" and count(child::entry)=#{entries}]}).size, "Atom 1.0 feed has wrong number of feed/entry nodes"
388
+ def assert_atom10
389
+ assert_select 'feed:root[xmlns="http://www.w3.org/2005/Atom"] > entry', :count => assigns(:items).size
358
390
  end
359
391
 
360
392
  def set_extended_on_rss(value)
data/test/test_helper.rb CHANGED
@@ -7,8 +7,7 @@ $TESTING = true
7
7
  User.salt = 'change-me'
8
8
 
9
9
  class Test::Unit::TestCase
10
- # Turn off transactional fixtures if you're working with MyISAM tables in MySQL
11
- self.use_transactional_fixtures = true
10
+ self.use_transactional_fixtures = false
12
11
 
13
12
  # Instantiated fixtures are slow, but give you @david where you otherwise would need people(:david)
14
13
  self.use_instantiated_fixtures = false
@@ -60,21 +59,6 @@ class Test::Unit::TestCase
60
59
  assert !tag, "expected no tag, but tag found matching #{opts.inspect} in:\n#{source.inspect}"
61
60
  end
62
61
 
63
- def get_xpath(xpath)
64
- rexml = REXML::Document.new(@response.body)
65
- assert rexml
66
-
67
- REXML::XPath.match(rexml, xpath)
68
- end
69
-
70
- def assert_xpath(xpath, msg=nil)
71
- assert !(get_xpath(xpath).empty?), msg
72
- end
73
-
74
- def assert_not_xpath(xpath, msg=nil)
75
- assert get_xpath(xpath).empty?, msg
76
- end
77
-
78
62
  def this_blog
79
63
  Blog.default || Blog.create!
80
64
  end
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../test_helper'
3
3
  require 'http_mock'
4
4
 
5
5
  class ArticleTest < Test::Unit::TestCase
6
- fixtures :blogs, :contents, :articles_tags, :tags, :resources, :categories, :categorizations, :users, :notifications, :text_filters
6
+ fixtures :blogs, :contents, :articles_tags, :tags, :resources, :categories, :categorizations, :users, :notifications, :text_filters, :triggers
7
7
 
8
8
  def setup
9
9
  @articles = []
@@ -8,7 +8,7 @@ class Page
8
8
  end
9
9
 
10
10
  class TriggerTest < Test::Unit::TestCase
11
- fixtures :contents
11
+ fixtures :contents, :triggers
12
12
 
13
13
  def test_post_action
14
14
  assert Trigger.post_action(Time.now + 2.seconds,
@@ -1,18 +1,14 @@
1
- <ol id="comments" class="comments">
2
- <% if @article.published_comments.any? -%>
3
- <% for comment in @article.published_comments -%>
4
- <li class="comment" id="comment-<%= comment.id %>">
5
- <div class="author">
6
- <%= content_tag(:div, gravatar_tag(comment.email)) if this_blog.use_gravatar and comment.email %>
7
- <cite><%= (comment.url.blank?) ? h(comment.author) : link_to(h(comment.author), comment.url) %></cite>
8
- <abbr title="<%= comment.created_at.xmlschema %>"><%= distance_of_time_in_words comment.article.published_at, comment.created_at %> later:</abbr>
9
- </div>
10
- <div class="content">
11
- <%= comment.html %>
12
- </div>
13
- </li>
14
- <% end -%>
15
- <% else -%>
16
- <li class="dummy_comment" style="display:none">No comments</li>
1
+ <li class="comment" id="comment-<%= comment.id %>">
2
+ <div class="author">
3
+ <%= content_tag(:div, gravatar_tag(comment.email)) if this_blog.use_gravatar and comment.email %>
4
+ <cite><%= (comment.url.blank?) ? h(comment.author) : link_to(h(comment.author), comment.url) %></cite>
5
+ <abbr title="<%= comment.created_at.xmlschema %>"><%= distance_of_time_in_words comment.article.published_at, comment.created_at %> later:</abbr>
6
+ </div>
7
+ <div class="content">
8
+ <%= comment.html %>
9
+ </div>
10
+ <% unless comment.published -%>
11
+ <div class="spamwarning"><%= _("This comment has been flagged for moderator approval.") %></div>
17
12
  <% end -%>
18
- </ol>
13
+ </li>
14
+
@@ -1,7 +1,9 @@
1
1
  <%= form_remote_tag :url => {:action => 'comment', :id => @article},
2
- :update => 'comments_div',
3
- :loading => 'commentLoading()',
4
- :complete => 'commentComplete()',
2
+ :position => :bottom,
3
+ :update => {:success => 'commentList'},
4
+ :loading => "loading()",
5
+ :complete => "complete(request)",
6
+ :failure => "failure(request)",
5
7
  :html => {:id => 'commentform', :class => 'comments' } %>
6
8
 
7
9
  <div id="preview" style="display:none"></div>
@@ -43,8 +45,8 @@
43
45
  :update => 'preview',
44
46
  :complete => "Element.show('preview')",
45
47
  :url => { :action => 'comment_preview' }) %>
46
- <%= submit_tag 'Submit', :onclick => "$('commentform').onsubmit();this.disabled=true;Element.hide('preview');return false;" %>
47
- <%= image_tag '/images/theme/spinner.gif', :id => 'spinner', :style => 'display:none' %>
48
+ <%= submit_tag 'Submit', :id => 'form-submit-button', :onclick => "$('commentform').onsubmit();this.disabled=true;Element.hide('preview');return false;" %>
49
+ <%= image_tag '/images/theme/spinner.gif', :id => 'comment_loading', :style => 'display:none' %>
48
50
  </p>
49
51
  </fieldset>
50
52
  <%= end_form_tag %>
@@ -0,0 +1,7 @@
1
+ <ol id="commentList" class="comments">
2
+ <% if @article.published_comments.any? -%>
3
+ <%= render(:partial => "comment", :collection => @article.published_comments) %>
4
+ <% else -%>
5
+ <li class="dummy_comment" style="display:none">No comments</li>
6
+ <% end -%>
7
+ </ol>
@@ -35,7 +35,7 @@
35
35
  <p><a href="#commentform">Leave a response</a></p>
36
36
 
37
37
  <div id="comments_div">
38
- <%= render :partial => "comment" %>
38
+ <%= render :partial => "comment_list" %>
39
39
  </div>
40
40
  <% end -%>
41
41
 
@@ -1,4 +1,4 @@
1
- <h3>AIM Status</h3>
1
+ <h3><%= _("AIM Status")%></h3>
2
2
  <a class="im" href="aim:GoIM?screenname=<%= @sidebar.sn %>">
3
3
  <img alt=" " src="http://api.oscar.aol.com/SOA/key=<%= @sidebar.devkey %>/presence/<%= @sidebar.sn %>" border="0" /> <%= @sidebar.sn %>
4
4
  </a>
@@ -1,5 +1,5 @@
1
1
  <% unless sidebar.archives.blank? %>
2
- <h3>Archives</h3>
2
+ <h3><%= _("Archives")%></h3>
3
3
  <ul id="archives">
4
4
  <% sidebar.archives.each do |month| %>
5
5
  <li>