mcms_blog 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (216) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/images/icons/accept.png +0 -0
  5. data/app/assets/images/icons/add.png +0 -0
  6. data/app/assets/images/icons/ajax-loader.gif +0 -0
  7. data/app/assets/images/icons/application_edit.png +0 -0
  8. data/app/assets/images/icons/application_go.png +0 -0
  9. data/app/assets/images/icons/arrow_left.png +0 -0
  10. data/app/assets/images/icons/arrow_switch.png +0 -0
  11. data/app/assets/images/icons/arrow_up.png +0 -0
  12. data/app/assets/images/icons/bin.png +0 -0
  13. data/app/assets/images/icons/bin_closed.png +0 -0
  14. data/app/assets/images/icons/cancel.png +0 -0
  15. data/app/assets/images/icons/cog_add.png +0 -0
  16. data/app/assets/images/icons/cog_edit.png +0 -0
  17. data/app/assets/images/icons/cross.png +0 -0
  18. data/app/assets/images/icons/delete.png +0 -0
  19. data/app/assets/images/icons/doc.png +0 -0
  20. data/app/assets/images/icons/down.gif +0 -0
  21. data/app/assets/images/icons/edit.png +0 -0
  22. data/app/assets/images/icons/email.png +0 -0
  23. data/app/assets/images/icons/email_edit.png +0 -0
  24. data/app/assets/images/icons/email_go.png +0 -0
  25. data/app/assets/images/icons/email_open.png +0 -0
  26. data/app/assets/images/icons/eye.png +0 -0
  27. data/app/assets/images/icons/folder_page_white.png +0 -0
  28. data/app/assets/images/icons/image_add.png +0 -0
  29. data/app/assets/images/icons/image_edit.png +0 -0
  30. data/app/assets/images/icons/img.png +0 -0
  31. data/app/assets/images/icons/information.png +0 -0
  32. data/app/assets/images/icons/layout_add.png +0 -0
  33. data/app/assets/images/icons/layout_edit.png +0 -0
  34. data/app/assets/images/icons/music.png +0 -0
  35. data/app/assets/images/icons/page_add.png +0 -0
  36. data/app/assets/images/icons/page_edit.png +0 -0
  37. data/app/assets/images/icons/page_white_edit.png +0 -0
  38. data/app/assets/images/icons/page_white_gear.png +0 -0
  39. data/app/assets/images/icons/page_white_put.png +0 -0
  40. data/app/assets/images/icons/pdf.png +0 -0
  41. data/app/assets/images/icons/ppt.png +0 -0
  42. data/app/assets/images/icons/star.png +0 -0
  43. data/app/assets/images/icons/tick.png +0 -0
  44. data/app/assets/images/icons/up.gif +0 -0
  45. data/app/assets/images/icons/user_add.png +0 -0
  46. data/app/assets/images/icons/user_comment.png +0 -0
  47. data/app/assets/images/icons/user_edit.png +0 -0
  48. data/app/assets/images/icons/xls.png +0 -0
  49. data/app/assets/images/icons/zip.png +0 -0
  50. data/app/assets/images/icons/zoom.png +0 -0
  51. data/app/assets/images/page_bg.png +0 -0
  52. data/app/assets/images/rails.png +0 -0
  53. data/app/assets/javascripts/admin/blog/mcms-blog-submenu.js +50 -0
  54. data/app/assets/javascripts/contrib/ui.core.js +519 -0
  55. data/app/assets/javascripts/contrib/ui.tabs.js +688 -0
  56. data/app/assets/javascripts/posts.js +3 -0
  57. data/app/assets/stylesheets/blog_global.css +1587 -0
  58. data/app/assets/stylesheets/blog_home.css +1432 -0
  59. data/app/assets/stylesheets/home.css +1429 -0
  60. data/app/assets/stylesheets/images/back_ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
  61. data/app/assets/stylesheets/images/spellayt.gif +0 -0
  62. data/app/assets/stylesheets/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  63. data/app/assets/stylesheets/images/ui-bg_flat_55_fbec88_40x100.png +0 -0
  64. data/app/assets/stylesheets/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  65. data/app/assets/stylesheets/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  66. data/app/assets/stylesheets/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  67. data/app/assets/stylesheets/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  68. data/app/assets/stylesheets/images/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
  69. data/app/assets/stylesheets/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  70. data/app/assets/stylesheets/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  71. data/app/assets/stylesheets/images/ui-bg_glass_85_dfeffc_1x400.png +0 -0
  72. data/app/assets/stylesheets/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  73. data/app/assets/stylesheets/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
  74. data/app/assets/stylesheets/images/ui-bg_green.png +1 -0
  75. data/app/assets/stylesheets/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  76. data/app/assets/stylesheets/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  77. data/app/assets/stylesheets/images/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
  78. data/app/assets/stylesheets/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
  79. data/app/assets/stylesheets/images/ui-icons_217bc0_256x240.png +0 -0
  80. data/app/assets/stylesheets/images/ui-icons_222222_256x240.png +0 -0
  81. data/app/assets/stylesheets/images/ui-icons_2e83ff_256x240.png +0 -0
  82. data/app/assets/stylesheets/images/ui-icons_454545_256x240.png +0 -0
  83. data/app/assets/stylesheets/images/ui-icons_469bdd_256x240.png +0 -0
  84. data/app/assets/stylesheets/images/ui-icons_6da8d5_256x240.png +0 -0
  85. data/app/assets/stylesheets/images/ui-icons_888888_256x240.png +0 -0
  86. data/app/assets/stylesheets/images/ui-icons_cd0a0a_256x240.png +0 -0
  87. data/app/assets/stylesheets/images/ui-icons_d8e7f3_256x240.png +0 -0
  88. data/app/assets/stylesheets/images/ui-icons_f9bd01_256x240.png +0 -0
  89. data/app/assets/stylesheets/jquery-ui-1.8.6.custom.css +572 -0
  90. data/app/assets/stylesheets/submenu.css.scss +32 -0
  91. data/app/controllers/admin/blog/categories_controller.rb +47 -0
  92. data/app/controllers/admin/blog/comments_controller.rb +64 -0
  93. data/app/controllers/admin/blog/posts_controller.rb +80 -0
  94. data/app/controllers/admin/blog/settings_controller.rb +67 -0
  95. data/app/controllers/application_controller.rb +29 -0
  96. data/app/controllers/blog/categories_controller.rb +34 -0
  97. data/app/controllers/blog/comments_controller.rb +34 -0
  98. data/app/controllers/blog/posts_controller.rb +123 -0
  99. data/app/controllers/blog_controller.rb +31 -0
  100. data/app/helpers/application_helper.rb +5 -0
  101. data/app/helpers/blog_helper.rb +66 -0
  102. data/app/helpers/notification_hepler.rb +5 -0
  103. data/app/helpers/settings_helper.rb +38 -0
  104. data/app/mailers/blog/comment_mailer.rb +12 -0
  105. data/app/models/blog_category.rb +29 -0
  106. data/app/models/blog_comment.rb +109 -0
  107. data/app/models/blog_post.rb +121 -0
  108. data/app/models/categorization.rb +16 -0
  109. data/app/models/ckeditor/asset.rb +6 -0
  110. data/app/models/ckeditor/attachment_file.rb +12 -0
  111. data/app/models/ckeditor/picture.rb +13 -0
  112. data/app/models/setting.rb +59 -0
  113. data/app/views/admin/blog/_submenu.html.erb +89 -0
  114. data/app/views/admin/blog/categories/_category.html.erb +20 -0
  115. data/app/views/admin/blog/categories/_form.html.erb +21 -0
  116. data/app/views/admin/blog/categories/_sortable_list.html.erb +3 -0
  117. data/app/views/admin/blog/categories/edit.html.erb +1 -0
  118. data/app/views/admin/blog/categories/index.html.erb +23 -0
  119. data/app/views/admin/blog/categories/new.html.erb +2 -0
  120. data/app/views/admin/blog/comments/_comment.html.erb +27 -0
  121. data/app/views/admin/blog/comments/_sortable_list.html.erb +11 -0
  122. data/app/views/admin/blog/comments/index.html.erb +12 -0
  123. data/app/views/admin/blog/comments/show.html.erb +70 -0
  124. data/app/views/admin/blog/posts/_form.css.erb +22 -0
  125. data/app/views/admin/blog/posts/_form.html.erb +92 -0
  126. data/app/views/admin/blog/posts/_form.js.erb +34 -0
  127. data/app/views/admin/blog/posts/_form_part.html.erb +10 -0
  128. data/app/views/admin/blog/posts/_post.html.erb +26 -0
  129. data/app/views/admin/blog/posts/_sortable_list.html.erb +3 -0
  130. data/app/views/admin/blog/posts/_teaser_part.html.erb +11 -0
  131. data/app/views/admin/blog/posts/edit.html.erb +1 -0
  132. data/app/views/admin/blog/posts/index.html.erb +29 -0
  133. data/app/views/admin/blog/posts/new.html.erb +13 -0
  134. data/app/views/admin/blog/settings/notification_recipients.html.erb +23 -0
  135. data/app/views/blog/categories/show.html.erb +17 -0
  136. data/app/views/blog/posts/_comment.html.erb +17 -0
  137. data/app/views/blog/posts/_nav.html.erb +18 -0
  138. data/app/views/blog/posts/_post.html.erb +25 -0
  139. data/app/views/blog/posts/archive.html.erb +17 -0
  140. data/app/views/blog/posts/index.html.erb +15 -0
  141. data/app/views/blog/posts/show.html.erb +64 -0
  142. data/app/views/blog/posts/tagged.html.erb +20 -0
  143. data/app/views/blog/shared/_categories.html.erb +19 -0
  144. data/app/views/blog/shared/_post.html.erb +34 -0
  145. data/app/views/blog/shared/_posts.html.erb +17 -0
  146. data/app/views/blog/shared/_rss_feed.html.erb +2 -0
  147. data/app/views/blog/shared/_tags.html.erb +17 -0
  148. data/app/views/layouts/_javascript.html.erb +3 -0
  149. data/app/views/layouts/_scripts.html.erb +6 -0
  150. data/app/views/layouts/_stylesheets.html.erb +6 -0
  151. data/app/views/layouts/admin.html.erb +25 -0
  152. data/app/views/layouts/application.html.erb +38 -0
  153. data/app/views/layouts/home.html.erb +38 -0
  154. data/app/views/shared/_footer.html.erb +3 -0
  155. data/app/views/shared/_head.html.erb +4 -0
  156. data/app/views/shared/_header.html.erb +7 -0
  157. data/app/views/shared/_javascripts.html.erb +3 -0
  158. data/app/views/shared/_menu.html.erb +9 -0
  159. data/app/views/shared/_stylesheets.html.erb +6 -0
  160. data/app/views/shared/admin/_error_messages.html.erb +16 -0
  161. data/app/views/shared/admin/_form_actions.html.erb +34 -0
  162. data/config/locales/en.yml +192 -0
  163. data/config/routes.rb +65 -0
  164. data/db/migrate/20120606150655_create_mcms_assets.rb +26 -0
  165. data/db/migrate/20120608071959_create_blog_categories.rb +9 -0
  166. data/db/migrate/20120608072013_create_blog_comments.rb +14 -0
  167. data/db/migrate/20120608072027_create_blog_posts.rb +16 -0
  168. data/db/migrate/20120612055745_create_categorizations.rb +9 -0
  169. data/db/migrate/20120618104134_add_index_in_blog_comments.rb +5 -0
  170. data/db/migrate/20120618105246_add_custom_index_in_mcms_blog_comments.rb +5 -0
  171. data/db/migrate/20120618105511_add_custom_index_in_mcms_blog_posts.rb +5 -0
  172. data/db/migrate/20120619094143_create_settings.rb +12 -0
  173. data/db/migrate/20120627063009_acts_as_taggable_on_migration.rb +28 -0
  174. data/db/migrate/20120629065434_add_slug_to_blog_post.rb +6 -0
  175. data/db/migrate/20120629113457_add_slug_to_mcms_blog_category.rb +6 -0
  176. data/db/seeds.rb +26 -0
  177. data/lib/generators/mcms_blog/USAGE +8 -0
  178. data/lib/generators/mcms_blog/mcms_blog_generator.rb +60 -0
  179. data/lib/generators/mcms_blog/templates/asset_manager.rb +107 -0
  180. data/lib/generators/mcms_blog/templates/ckeditor.rb +18 -0
  181. data/lib/mcms_blog/engine.rb +18 -0
  182. data/lib/mcms_blog/version.rb +3 -0
  183. data/lib/mcms_blog.rb +4 -0
  184. data/lib/tasks/mcms_blog_tasks.rake +4 -0
  185. data/test/dummy/README.rdoc +261 -0
  186. data/test/dummy/Rakefile +7 -0
  187. data/test/dummy/app/assets/javascripts/application.js +15 -0
  188. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  189. data/test/dummy/app/controllers/application_controller.rb +3 -0
  190. data/test/dummy/app/helpers/application_helper.rb +2 -0
  191. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  192. data/test/dummy/config/application.rb +59 -0
  193. data/test/dummy/config/boot.rb +10 -0
  194. data/test/dummy/config/database.yml +25 -0
  195. data/test/dummy/config/environment.rb +5 -0
  196. data/test/dummy/config/environments/development.rb +37 -0
  197. data/test/dummy/config/environments/production.rb +67 -0
  198. data/test/dummy/config/environments/test.rb +37 -0
  199. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  200. data/test/dummy/config/initializers/inflections.rb +15 -0
  201. data/test/dummy/config/initializers/mime_types.rb +5 -0
  202. data/test/dummy/config/initializers/secret_token.rb +7 -0
  203. data/test/dummy/config/initializers/session_store.rb +8 -0
  204. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  205. data/test/dummy/config/locales/en.yml +5 -0
  206. data/test/dummy/config/routes.rb +58 -0
  207. data/test/dummy/config.ru +4 -0
  208. data/test/dummy/public/404.html +26 -0
  209. data/test/dummy/public/422.html +26 -0
  210. data/test/dummy/public/500.html +25 -0
  211. data/test/dummy/public/favicon.ico +0 -0
  212. data/test/dummy/script/rails +6 -0
  213. data/test/integration/navigation_test.rb +10 -0
  214. data/test/mcms_blog_test.rb +7 -0
  215. data/test/test_helper.rb +15 -0
  216. metadata +403 -0
@@ -0,0 +1,688 @@
1
+ /*
2
+ * jQuery UI Tabs 1.7.3
3
+ *
4
+ * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
5
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
6
+ * and GPL (GPL-LICENSE.txt) licenses.
7
+ *
8
+ * http://docs.jquery.com/UI/Tabs
9
+ *
10
+ * Depends:
11
+ * ui.core.js
12
+ */
13
+ (function($) {
14
+
15
+ var tabId = 0,
16
+ listId = 0;
17
+
18
+ $.widget("ui.tabs", {
19
+
20
+ _init: function() {
21
+ if (this.options.deselectable !== undefined) {
22
+ this.options.collapsible = this.options.deselectable;
23
+ }
24
+ this._tabify(true);
25
+ },
26
+
27
+ _setData: function(key, value) {
28
+ if (key == 'selected') {
29
+ if (this.options.collapsible && value == this.options.selected) {
30
+ return;
31
+ }
32
+ this.select(value);
33
+ }
34
+ else {
35
+ this.options[key] = value;
36
+ if (key == 'deselectable') {
37
+ this.options.collapsible = value;
38
+ }
39
+ this._tabify();
40
+ }
41
+ },
42
+
43
+ _tabId: function(a) {
44
+ return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') ||
45
+ this.options.idPrefix + (++tabId);
46
+ },
47
+
48
+ _sanitizeSelector: function(hash) {
49
+ return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":"
50
+ },
51
+
52
+ _cookie: function() {
53
+ var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + (++listId));
54
+ return $.cookie.apply(null, [cookie].concat($.makeArray(arguments)));
55
+ },
56
+
57
+ _ui: function(tab, panel) {
58
+ return {
59
+ tab: tab,
60
+ panel: panel,
61
+ index: this.anchors.index(tab)
62
+ };
63
+ },
64
+
65
+ _cleanup: function() {
66
+ // restore all former loading tabs labels
67
+ this.lis.filter('.ui-state-processing').removeClass('ui-state-processing')
68
+ .find('span:data(label.tabs)')
69
+ .each(function() {
70
+ var el = $(this);
71
+ el.html(el.data('label.tabs')).removeData('label.tabs');
72
+ });
73
+ },
74
+
75
+ _tabify: function(init) {
76
+
77
+ this.list = this.element.children('ul:first');
78
+ this.lis = $('li:has(a[href])', this.list);
79
+ this.anchors = this.lis.map(function() { return $('a', this)[0]; });
80
+ this.panels = $([]);
81
+
82
+ var self = this, o = this.options;
83
+
84
+ var fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash
85
+ this.anchors.each(function(i, a) {
86
+ var href = $(a).attr('href');
87
+
88
+ // For dynamically created HTML that contains a hash as href IE < 8 expands
89
+ // such href to the full page url with hash and then misinterprets tab as ajax.
90
+ // Same consideration applies for an added tab with a fragment identifier
91
+ // since a[href=#fragment-identifier] does unexpectedly not match.
92
+ // Thus normalize href attribute...
93
+ var hrefBase = href.split('#')[0], baseEl;
94
+ if (hrefBase && (hrefBase === location.toString().split('#')[0] ||
95
+ (baseEl = $('base')[0]) && hrefBase === baseEl.href)) {
96
+ href = a.hash;
97
+ a.href = href;
98
+ }
99
+
100
+ // inline tab
101
+ if (fragmentId.test(href)) {
102
+ self.panels = self.panels.add(self._sanitizeSelector(href));
103
+ }
104
+
105
+ // remote tab
106
+ else if (href != '#') { // prevent loading the page itself if href is just "#"
107
+ $.data(a, 'href.tabs', href); // required for restore on destroy
108
+
109
+ // TODO until #3808 is fixed strip fragment identifier from url
110
+ // (IE fails to load from such url)
111
+ $.data(a, 'load.tabs', href.replace(/#.*$/, '')); // mutable data
112
+
113
+ var id = self._tabId(a);
114
+ a.href = '#' + id;
115
+ var $panel = $('#' + id);
116
+ if (!$panel.length) {
117
+ $panel = $(o.panelTemplate).attr('id', id).addClass('ui-tabs-panel ui-widget-content ui-corner-bottom')
118
+ .insertAfter(self.panels[i - 1] || self.list);
119
+ $panel.data('destroy.tabs', true);
120
+ }
121
+ self.panels = self.panels.add($panel);
122
+ }
123
+
124
+ // invalid tab href
125
+ else {
126
+ o.disabled.push(i);
127
+ }
128
+ });
129
+
130
+ // initialization from scratch
131
+ if (init) {
132
+
133
+ // attach necessary classes for styling
134
+ this.element.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all');
135
+ this.list.addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');
136
+ this.lis.addClass('ui-state-default ui-corner-top');
137
+ this.panels.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom');
138
+
139
+ // Selected tab
140
+ // use "selected" option or try to retrieve:
141
+ // 1. from fragment identifier in url
142
+ // 2. from cookie
143
+ // 3. from selected class attribute on <li>
144
+ if (o.selected === undefined) {
145
+ if (location.hash) {
146
+ this.anchors.each(function(i, a) {
147
+ if (a.hash == location.hash) {
148
+ o.selected = i;
149
+ return false; // break
150
+ }
151
+ });
152
+ }
153
+ if (typeof o.selected != 'number' && o.cookie) {
154
+ o.selected = parseInt(self._cookie(), 10);
155
+ }
156
+ if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) {
157
+ o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));
158
+ }
159
+ o.selected = o.selected || 0;
160
+ }
161
+ else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release
162
+ o.selected = -1;
163
+ }
164
+
165
+ // sanity check - default to first tab...
166
+ o.selected = ((o.selected >= 0 && this.anchors[o.selected]) || o.selected < 0) ? o.selected : 0;
167
+
168
+ // Take disabling tabs via class attribute from HTML
169
+ // into account and update option properly.
170
+ // A selected tab cannot become disabled.
171
+ o.disabled = $.unique(o.disabled.concat(
172
+ $.map(this.lis.filter('.ui-state-disabled'),
173
+ function(n, i) { return self.lis.index(n); } )
174
+ )).sort();
175
+
176
+ if ($.inArray(o.selected, o.disabled) != -1) {
177
+ o.disabled.splice($.inArray(o.selected, o.disabled), 1);
178
+ }
179
+
180
+ // highlight selected tab
181
+ this.panels.addClass('ui-tabs-hide');
182
+ this.lis.removeClass('ui-tabs-selected ui-state-active');
183
+ if (o.selected >= 0 && this.anchors.length) { // check for length avoids error when initializing empty list
184
+ this.panels.eq(o.selected).removeClass('ui-tabs-hide');
185
+ this.lis.eq(o.selected).addClass('ui-tabs-selected ui-state-active');
186
+
187
+ // seems to be expected behavior that the show callback is fired
188
+ self.element.queue("tabs", function() {
189
+ self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected]));
190
+ });
191
+
192
+ this.load(o.selected);
193
+ }
194
+
195
+ // clean up to avoid memory leaks in certain versions of IE 6
196
+ $(window).bind('unload', function() {
197
+ self.lis.add(self.anchors).unbind('.tabs');
198
+ self.lis = self.anchors = self.panels = null;
199
+ });
200
+
201
+ }
202
+ // update selected after add/remove
203
+ else {
204
+ o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));
205
+ }
206
+
207
+ // update collapsible
208
+ this.element[o.collapsible ? 'addClass' : 'removeClass']('ui-tabs-collapsible');
209
+
210
+ // set or update cookie after init and add/remove respectively
211
+ if (o.cookie) {
212
+ this._cookie(o.selected, o.cookie);
213
+ }
214
+
215
+ // disable tabs
216
+ for (var i = 0, li; (li = this.lis[i]); i++) {
217
+ $(li)[$.inArray(i, o.disabled) != -1 &&
218
+ !$(li).hasClass('ui-tabs-selected') ? 'addClass' : 'removeClass']('ui-state-disabled');
219
+ }
220
+
221
+ // reset cache if switching from cached to not cached
222
+ if (o.cache === false) {
223
+ this.anchors.removeData('cache.tabs');
224
+ }
225
+
226
+ // remove all handlers before, tabify may run on existing tabs after add or option change
227
+ this.lis.add(this.anchors).unbind('.tabs');
228
+
229
+ if (o.event != 'mouseover') {
230
+ var addState = function(state, el) {
231
+ if (el.is(':not(.ui-state-disabled)')) {
232
+ el.addClass('ui-state-' + state);
233
+ }
234
+ };
235
+ var removeState = function(state, el) {
236
+ el.removeClass('ui-state-' + state);
237
+ };
238
+ this.lis.bind('mouseover.tabs', function() {
239
+ addState('hover', $(this));
240
+ });
241
+ this.lis.bind('mouseout.tabs', function() {
242
+ removeState('hover', $(this));
243
+ });
244
+ this.anchors.bind('focus.tabs', function() {
245
+ addState('focus', $(this).closest('li'));
246
+ });
247
+ this.anchors.bind('blur.tabs', function() {
248
+ removeState('focus', $(this).closest('li'));
249
+ });
250
+ }
251
+
252
+ // set up animations
253
+ var hideFx, showFx;
254
+ if (o.fx) {
255
+ if ($.isArray(o.fx)) {
256
+ hideFx = o.fx[0];
257
+ showFx = o.fx[1];
258
+ }
259
+ else {
260
+ hideFx = showFx = o.fx;
261
+ }
262
+ }
263
+
264
+ // Reset certain styles left over from animation
265
+ // and prevent IE's ClearType bug...
266
+ function resetStyle($el, fx) {
267
+ $el.css({ display: '' });
268
+ if ($.browser.msie && fx.opacity) {
269
+ $el[0].style.removeAttribute('filter');
270
+ }
271
+ }
272
+
273
+ // Show a tab...
274
+ var showTab = showFx ?
275
+ function(clicked, $show) {
276
+ $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active');
277
+ $show.hide().removeClass('ui-tabs-hide') // avoid flicker that way
278
+ .animate(showFx, showFx.duration || 'normal', function() {
279
+ resetStyle($show, showFx);
280
+ self._trigger('show', null, self._ui(clicked, $show[0]));
281
+ });
282
+ } :
283
+ function(clicked, $show) {
284
+ $(clicked).closest('li').removeClass('ui-state-default').addClass('ui-tabs-selected ui-state-active');
285
+ $show.removeClass('ui-tabs-hide');
286
+ self._trigger('show', null, self._ui(clicked, $show[0]));
287
+ };
288
+
289
+ // Hide a tab, $show is optional...
290
+ var hideTab = hideFx ?
291
+ function(clicked, $hide) {
292
+ $hide.animate(hideFx, hideFx.duration || 'normal', function() {
293
+ self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default');
294
+ $hide.addClass('ui-tabs-hide');
295
+ resetStyle($hide, hideFx);
296
+ self.element.dequeue("tabs");
297
+ });
298
+ } :
299
+ function(clicked, $hide, $show) {
300
+ self.lis.removeClass('ui-tabs-selected ui-state-active').addClass('ui-state-default');
301
+ $hide.addClass('ui-tabs-hide');
302
+ self.element.dequeue("tabs");
303
+ };
304
+
305
+ // attach tab event handler, unbind to avoid duplicates from former tabifying...
306
+ this.anchors.bind(o.event + '.tabs', function() {
307
+ var el = this, $li = $(this).closest('li'), $hide = self.panels.filter(':not(.ui-tabs-hide)'),
308
+ $show = $(self._sanitizeSelector(this.hash));
309
+
310
+ // If tab is already selected and not collapsible or tab disabled or
311
+ // or is already loading or click callback returns false stop here.
312
+ // Check if click handler returns false last so that it is not executed
313
+ // for a disabled or loading tab!
314
+ if (($li.hasClass('ui-tabs-selected') && !o.collapsible) ||
315
+ $li.hasClass('ui-state-disabled') ||
316
+ $li.hasClass('ui-state-processing') ||
317
+ self._trigger('select', null, self._ui(this, $show[0])) === false) {
318
+ this.blur();
319
+ return false;
320
+ }
321
+
322
+ o.selected = self.anchors.index(this);
323
+
324
+ self.abort();
325
+
326
+ // if tab may be closed
327
+ if (o.collapsible) {
328
+ if ($li.hasClass('ui-tabs-selected')) {
329
+ o.selected = -1;
330
+
331
+ if (o.cookie) {
332
+ self._cookie(o.selected, o.cookie);
333
+ }
334
+
335
+ self.element.queue("tabs", function() {
336
+ hideTab(el, $hide);
337
+ }).dequeue("tabs");
338
+
339
+ this.blur();
340
+ return false;
341
+ }
342
+ else if (!$hide.length) {
343
+ if (o.cookie) {
344
+ self._cookie(o.selected, o.cookie);
345
+ }
346
+
347
+ self.element.queue("tabs", function() {
348
+ showTab(el, $show);
349
+ });
350
+
351
+ self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
352
+
353
+ this.blur();
354
+ return false;
355
+ }
356
+ }
357
+
358
+ if (o.cookie) {
359
+ self._cookie(o.selected, o.cookie);
360
+ }
361
+
362
+ // show new tab
363
+ if ($show.length) {
364
+ if ($hide.length) {
365
+ self.element.queue("tabs", function() {
366
+ hideTab(el, $hide);
367
+ });
368
+ }
369
+ self.element.queue("tabs", function() {
370
+ showTab(el, $show);
371
+ });
372
+
373
+ self.load(self.anchors.index(this));
374
+ }
375
+ else {
376
+ throw 'jQuery UI Tabs: Mismatching fragment identifier.';
377
+ }
378
+
379
+ // Prevent IE from keeping other link focussed when using the back button
380
+ // and remove dotted border from clicked link. This is controlled via CSS
381
+ // in modern browsers; blur() removes focus from address bar in Firefox
382
+ // which can become a usability and annoying problem with tabs('rotate').
383
+ if ($.browser.msie) {
384
+ this.blur();
385
+ }
386
+
387
+ });
388
+
389
+ // disable click in any case
390
+ this.anchors.bind('click.tabs', function(){return false;});
391
+
392
+ },
393
+
394
+ destroy: function() {
395
+ var o = this.options;
396
+
397
+ this.abort();
398
+
399
+ this.element.unbind('.tabs')
400
+ .removeClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible')
401
+ .removeData('tabs');
402
+
403
+ this.list.removeClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');
404
+
405
+ this.anchors.each(function() {
406
+ var href = $.data(this, 'href.tabs');
407
+ if (href) {
408
+ this.href = href;
409
+ }
410
+ var $this = $(this).unbind('.tabs');
411
+ $.each(['href', 'load', 'cache'], function(i, prefix) {
412
+ $this.removeData(prefix + '.tabs');
413
+ });
414
+ });
415
+
416
+ this.lis.unbind('.tabs').add(this.panels).each(function() {
417
+ if ($.data(this, 'destroy.tabs')) {
418
+ $(this).remove();
419
+ }
420
+ else {
421
+ $(this).removeClass([
422
+ 'ui-state-default',
423
+ 'ui-corner-top',
424
+ 'ui-tabs-selected',
425
+ 'ui-state-active',
426
+ 'ui-state-hover',
427
+ 'ui-state-focus',
428
+ 'ui-state-disabled',
429
+ 'ui-tabs-panel',
430
+ 'ui-widget-content',
431
+ 'ui-corner-bottom',
432
+ 'ui-tabs-hide'
433
+ ].join(' '));
434
+ }
435
+ });
436
+
437
+ if (o.cookie) {
438
+ this._cookie(null, o.cookie);
439
+ }
440
+ },
441
+
442
+ add: function(url, label, index) {
443
+ if (index === undefined) {
444
+ index = this.anchors.length; // append by default
445
+ }
446
+
447
+ var self = this, o = this.options,
448
+ $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label)),
449
+ id = !url.indexOf('#') ? url.replace('#', '') : this._tabId($('a', $li)[0]);
450
+
451
+ $li.addClass('ui-state-default ui-corner-top').data('destroy.tabs', true);
452
+
453
+ // try to find an existing element before creating a new one
454
+ var $panel = $('#' + id);
455
+ if (!$panel.length) {
456
+ $panel = $(o.panelTemplate).attr('id', id).data('destroy.tabs', true);
457
+ }
458
+ $panel.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide');
459
+
460
+ if (index >= this.lis.length) {
461
+ $li.appendTo(this.list);
462
+ $panel.appendTo(this.list[0].parentNode);
463
+ }
464
+ else {
465
+ $li.insertBefore(this.lis[index]);
466
+ $panel.insertBefore(this.panels[index]);
467
+ }
468
+
469
+ o.disabled = $.map(o.disabled,
470
+ function(n, i) { return n >= index ? ++n : n; });
471
+
472
+ this._tabify();
473
+
474
+ if (this.anchors.length == 1) { // after tabify
475
+ $li.addClass('ui-tabs-selected ui-state-active');
476
+ $panel.removeClass('ui-tabs-hide');
477
+ this.element.queue("tabs", function() {
478
+ self._trigger('show', null, self._ui(self.anchors[0], self.panels[0]));
479
+ });
480
+
481
+ this.load(0);
482
+ }
483
+
484
+ // callback
485
+ this._trigger('add', null, this._ui(this.anchors[index], this.panels[index]));
486
+ },
487
+
488
+ remove: function(index) {
489
+ var o = this.options, $li = this.lis.eq(index).remove(),
490
+ $panel = this.panels.eq(index).remove();
491
+
492
+ // If selected tab was removed focus tab to the right or
493
+ // in case the last tab was removed the tab to the left.
494
+ if ($li.hasClass('ui-tabs-selected') && this.anchors.length > 1) {
495
+ this.select(index + (index + 1 < this.anchors.length ? 1 : -1));
496
+ }
497
+
498
+ o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
499
+ function(n, i) { return n >= index ? --n : n; });
500
+
501
+ this._tabify();
502
+
503
+ // callback
504
+ this._trigger('remove', null, this._ui($li.find('a')[0], $panel[0]));
505
+ },
506
+
507
+ enable: function(index) {
508
+ var o = this.options;
509
+ if ($.inArray(index, o.disabled) == -1) {
510
+ return;
511
+ }
512
+
513
+ this.lis.eq(index).removeClass('ui-state-disabled');
514
+ o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });
515
+
516
+ // callback
517
+ this._trigger('enable', null, this._ui(this.anchors[index], this.panels[index]));
518
+ },
519
+
520
+ disable: function(index) {
521
+ var self = this, o = this.options;
522
+ if (index != o.selected) { // cannot disable already selected tab
523
+ this.lis.eq(index).addClass('ui-state-disabled');
524
+
525
+ o.disabled.push(index);
526
+ o.disabled.sort();
527
+
528
+ // callback
529
+ this._trigger('disable', null, this._ui(this.anchors[index], this.panels[index]));
530
+ }
531
+ },
532
+
533
+ select: function(index) {
534
+ if (typeof index == 'string') {
535
+ index = this.anchors.index(this.anchors.filter('[href$=' + index + ']'));
536
+ }
537
+ else if (index === null) { // usage of null is deprecated, TODO remove in next release
538
+ index = -1;
539
+ }
540
+ if (index == -1 && this.options.collapsible) {
541
+ index = this.options.selected;
542
+ }
543
+
544
+ this.anchors.eq(index).trigger(this.options.event + '.tabs');
545
+ },
546
+
547
+ load: function(index) {
548
+ var self = this, o = this.options, a = this.anchors.eq(index)[0], url = $.data(a, 'load.tabs');
549
+
550
+ this.abort();
551
+
552
+ // not remote or from cache
553
+ if (!url || this.element.queue("tabs").length !== 0 && $.data(a, 'cache.tabs')) {
554
+ this.element.dequeue("tabs");
555
+ return;
556
+ }
557
+
558
+ // load remote from here on
559
+ this.lis.eq(index).addClass('ui-state-processing');
560
+
561
+ if (o.spinner) {
562
+ var span = $('span', a);
563
+ span.data('label.tabs', span.html()).html(o.spinner);
564
+ }
565
+
566
+ this.xhr = $.ajax($.extend({}, o.ajaxOptions, {
567
+ url: url,
568
+ success: function(r, s) {
569
+ $(self._sanitizeSelector(a.hash)).html(r);
570
+
571
+ // take care of tab labels
572
+ self._cleanup();
573
+
574
+ if (o.cache) {
575
+ $.data(a, 'cache.tabs', true); // if loaded once do not load them again
576
+ }
577
+
578
+ // callbacks
579
+ self._trigger('load', null, self._ui(self.anchors[index], self.panels[index]));
580
+ try {
581
+ o.ajaxOptions.success(r, s);
582
+ }
583
+ catch (e) {}
584
+
585
+ // last, so that load event is fired before show...
586
+ self.element.dequeue("tabs");
587
+ }
588
+ }));
589
+ },
590
+
591
+ abort: function() {
592
+ // stop possibly running animations
593
+ this.element.queue([]);
594
+ this.panels.stop(false, true);
595
+
596
+ // terminate pending requests from other tabs
597
+ if (this.xhr) {
598
+ this.xhr.abort();
599
+ delete this.xhr;
600
+ }
601
+
602
+ // take care of tab labels
603
+ this._cleanup();
604
+
605
+ },
606
+
607
+ url: function(index, url) {
608
+ this.anchors.eq(index).removeData('cache.tabs').data('load.tabs', url);
609
+ },
610
+
611
+ length: function() {
612
+ return this.anchors.length;
613
+ }
614
+
615
+ });
616
+
617
+ $.extend($.ui.tabs, {
618
+ version: '1.7.3',
619
+ getter: 'length',
620
+ defaults: {
621
+ ajaxOptions: null,
622
+ cache: false,
623
+ cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
624
+ collapsible: false,
625
+ disabled: [],
626
+ event: 'click',
627
+ fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
628
+ idPrefix: 'ui-tabs-',
629
+ panelTemplate: '<div></div>',
630
+ spinner: '<em>Loading&#8230;</em>',
631
+ tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>'
632
+ }
633
+ });
634
+
635
+ /*
636
+ * Tabs Extensions
637
+ */
638
+
639
+ /*
640
+ * Rotate
641
+ */
642
+ $.extend($.ui.tabs.prototype, {
643
+ rotation: null,
644
+ rotate: function(ms, continuing) {
645
+
646
+ var self = this, o = this.options;
647
+
648
+ var rotate = self._rotate || (self._rotate = function(e) {
649
+ clearTimeout(self.rotation);
650
+ self.rotation = setTimeout(function() {
651
+ var t = o.selected;
652
+ self.select( ++t < self.anchors.length ? t : 0 );
653
+ }, ms);
654
+
655
+ if (e) {
656
+ e.stopPropagation();
657
+ }
658
+ });
659
+
660
+ var stop = self._unrotate || (self._unrotate = !continuing ?
661
+ function(e) {
662
+ if (e.clientX) { // in case of a true click
663
+ self.rotate(null);
664
+ }
665
+ } :
666
+ function(e) {
667
+ t = o.selected;
668
+ rotate();
669
+ });
670
+
671
+ // start rotation
672
+ if (ms) {
673
+ this.element.bind('tabsshow', rotate);
674
+ this.anchors.bind(o.event + '.tabs', stop);
675
+ rotate();
676
+ }
677
+ // stop rotation
678
+ else {
679
+ clearTimeout(self.rotation);
680
+ this.element.unbind('tabsshow', rotate);
681
+ this.anchors.unbind(o.event + '.tabs', stop);
682
+ delete this._rotate;
683
+ delete this._unrotate;
684
+ }
685
+ }
686
+ });
687
+
688
+ })(jQuery);
@@ -0,0 +1,3 @@
1
+ $(function(){
2
+ $('#page-tabs').tabs();
3
+ });