radiant 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of radiant might be problematic. Click here for more details.

Files changed (197) hide show
  1. data/CHANGELOG +61 -7
  2. data/CONTRIBUTORS +15 -0
  3. data/app/controllers/admin/export_controller.rb +1 -1
  4. data/app/controllers/admin/page_controller.rb +1 -0
  5. data/app/controllers/admin/user_controller.rb +2 -1
  6. data/app/controllers/application.rb +7 -8
  7. data/app/helpers/admin/node_helper.rb +84 -0
  8. data/app/helpers/admin/page_helper.rb +1 -19
  9. data/app/helpers/application_helper.rb +15 -9
  10. data/app/models/file_not_found_page.rb +2 -2
  11. data/app/models/page.rb +22 -18
  12. data/app/models/page_context.rb +9 -0
  13. data/app/models/radiant/config.rb +4 -2
  14. data/app/models/response_cache.rb +18 -12
  15. data/app/models/standard_tags.rb +111 -50
  16. data/app/views/admin/extension/index.rhtml +2 -2
  17. data/app/views/admin/layout/edit.rhtml +2 -2
  18. data/app/views/admin/layout/remove.rhtml +2 -2
  19. data/app/views/admin/page/_node.rhtml +4 -26
  20. data/app/views/admin/page/_part.rhtml +9 -14
  21. data/app/views/admin/page/edit.rhtml +38 -121
  22. data/app/views/admin/page/index.rhtml +2 -6
  23. data/app/views/admin/page/remove.rhtml +2 -2
  24. data/app/views/admin/snippet/edit.rhtml +3 -3
  25. data/app/views/admin/snippet/index.rhtml +2 -2
  26. data/app/views/admin/snippet/remove.rhtml +2 -2
  27. data/app/views/admin/user/edit.rhtml +4 -4
  28. data/app/views/admin/user/preferences.rhtml +2 -2
  29. data/app/views/admin/welcome/login.rhtml +1 -1
  30. data/config/environment.rb +79 -78
  31. data/db/schema.rb +2 -0
  32. data/lib/local_time.rb +12 -0
  33. data/lib/plugins/extension_patches/lib/fixture_loading_extension.rb +1 -1
  34. data/lib/plugins/extension_patches/lib/mailer_view_paths_extension.rb +3 -3
  35. data/lib/radiant.rb +1 -1
  36. data/lib/radiant/extension.rb +9 -3
  37. data/lib/radiant/extension_loader.rb +2 -2
  38. data/lib/tasks/extensions.rake +23 -8
  39. data/public/javascripts/admin.js +89 -0
  40. data/public/javascripts/controls.js +486 -354
  41. data/public/javascripts/dragdrop.js +90 -58
  42. data/public/javascripts/effects.js +398 -364
  43. data/public/javascripts/pngfix.js +37 -37
  44. data/public/javascripts/prototype.js +2764 -1095
  45. data/public/javascripts/ruledtable.js +10 -25
  46. data/public/javascripts/sitemap.js +74 -112
  47. data/public/javascripts/string.js +1 -7
  48. data/public/javascripts/tabcontrol.js +71 -86
  49. data/public/javascripts/tag_reference_search.js +19 -26
  50. data/public/stylesheets/admin/main.css +11 -5
  51. data/test/fixtures/extensions/01_basic/lib/new_module.rb +2 -0
  52. data/test/fixtures/page_parts.yml +16 -1
  53. data/test/fixtures/pages.yml +47 -84
  54. data/test/functional/extension_initialization_test.rb +11 -0
  55. data/test/helpers/login_test_helper.rb +12 -1
  56. data/test/helpers/page_test_helper.rb +6 -0
  57. data/test/helpers/render_test_helper.rb +11 -8
  58. data/test/test_helper.rb +1 -12
  59. data/test/unit/file_not_found_page_test.rb +5 -1
  60. data/test/unit/local_time_test.rb +45 -0
  61. data/test/unit/page_context_test.rb +32 -1
  62. data/test/unit/page_test.rb +45 -11
  63. data/test/unit/radiant/config_test.rb +1 -1
  64. data/test/unit/response_cache_test.rb +27 -2
  65. data/test/unit/standard_tags_test.rb +60 -15
  66. data/vendor/extensions/archive/README +29 -0
  67. data/vendor/extensions/archive/Rakefile +25 -0
  68. data/{app → vendor/extensions/archive/app}/models/archive_day_index_page.rb +0 -0
  69. data/{app → vendor/extensions/archive/app}/models/archive_finder.rb +8 -6
  70. data/{app → vendor/extensions/archive/app}/models/archive_month_index_page.rb +0 -0
  71. data/{app → vendor/extensions/archive/app}/models/archive_page.rb +0 -0
  72. data/{app → vendor/extensions/archive/app}/models/archive_year_index_page.rb +0 -0
  73. data/vendor/extensions/archive/archive_extension.rb +19 -0
  74. data/{lib → vendor/extensions/archive/lib}/archive_index_tags_and_methods.rb +0 -0
  75. data/vendor/extensions/archive/lib/tasks/archive_extension_tasks.rake +28 -0
  76. data/vendor/extensions/archive/test/fixtures/pages.yml +397 -0
  77. data/vendor/extensions/archive/test/functional/archive_extension_test.rb +16 -0
  78. data/{test → vendor/extensions/archive/test}/helpers/archive_index_test_helper.rb +0 -0
  79. data/vendor/extensions/archive/test/test_helper.rb +19 -0
  80. data/{test → vendor/extensions/archive/test}/unit/archive_day_index_page_test.rb +0 -0
  81. data/{test → vendor/extensions/archive/test}/unit/archive_month_index_page_test.rb +0 -0
  82. data/{test → vendor/extensions/archive/test}/unit/archive_page_test.rb +7 -1
  83. data/{test → vendor/extensions/archive/test}/unit/archive_year_index_page_test.rb +0 -0
  84. data/vendor/rails/actionmailer/CHANGELOG +10 -0
  85. data/vendor/rails/actionmailer/Rakefile +1 -1
  86. data/vendor/rails/actionmailer/lib/action_mailer/version.rb +1 -1
  87. data/vendor/rails/actionpack/CHANGELOG +51 -2
  88. data/vendor/rails/actionpack/Rakefile +1 -1
  89. data/vendor/rails/actionpack/lib/action_controller/assertions/dom_assertions.rb +2 -2
  90. data/vendor/rails/actionpack/lib/action_controller/assertions/model_assertions.rb +1 -1
  91. data/vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb +3 -0
  92. data/vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb +1 -0
  93. data/vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb +2 -0
  94. data/vendor/rails/actionpack/lib/action_controller/base.rb +7 -1
  95. data/vendor/rails/actionpack/lib/action_controller/caching.rb +39 -38
  96. data/vendor/rails/actionpack/lib/action_controller/cgi_ext/pstore_performance_fix.rb +30 -0
  97. data/vendor/rails/actionpack/lib/action_controller/cgi_ext/raw_post_data_fix.rb +1 -1
  98. data/vendor/rails/actionpack/lib/action_controller/cgi_process.rb +13 -4
  99. data/vendor/rails/actionpack/lib/action_controller/cookies.rb +5 -3
  100. data/vendor/rails/actionpack/lib/action_controller/filters.rb +176 -77
  101. data/vendor/rails/actionpack/lib/action_controller/integration.rb +31 -21
  102. data/vendor/rails/actionpack/lib/action_controller/macros/in_place_editing.rb +1 -1
  103. data/vendor/rails/actionpack/lib/action_controller/pagination.rb +7 -1
  104. data/vendor/rails/actionpack/lib/action_controller/resources.rb +117 -32
  105. data/vendor/rails/actionpack/lib/action_controller/routing.rb +56 -23
  106. data/vendor/rails/actionpack/lib/action_controller/test_process.rb +5 -2
  107. data/vendor/rails/actionpack/lib/action_controller/url_rewriter.rb +4 -1
  108. data/vendor/rails/actionpack/lib/action_controller/verification.rb +1 -0
  109. data/vendor/rails/actionpack/lib/action_pack/version.rb +1 -1
  110. data/vendor/rails/actionpack/lib/action_view/base.rb +25 -19
  111. data/vendor/rails/actionpack/lib/action_view/compiled_templates.rb +2 -2
  112. data/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb +18 -18
  113. data/vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb +10 -0
  114. data/vendor/rails/actionpack/lib/action_view/helpers/deprecated_helper.rb +3 -0
  115. data/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb +33 -17
  116. data/vendor/rails/actionpack/test/activerecord/pagination_test.rb +9 -0
  117. data/vendor/rails/actionpack/test/controller/action_pack_assertions_test.rb +13 -0
  118. data/vendor/rails/actionpack/test/controller/addresses_render_test.rb +4 -1
  119. data/vendor/rails/actionpack/test/controller/base_test.rb +1 -1
  120. data/vendor/rails/actionpack/test/controller/caching_test.rb +3 -2
  121. data/vendor/rails/actionpack/test/controller/cookie_test.rb +11 -0
  122. data/vendor/rails/actionpack/test/controller/deprecation/deprecated_base_methods_test.rb +18 -0
  123. data/vendor/rails/actionpack/test/controller/filter_params_test.rb +1 -0
  124. data/vendor/rails/actionpack/test/controller/filters_test.rb +149 -26
  125. data/vendor/rails/actionpack/test/controller/integration_test.rb +93 -8
  126. data/vendor/rails/actionpack/test/controller/resources_test.rb +215 -36
  127. data/vendor/rails/actionpack/test/controller/routing_test.rb +2 -2
  128. data/vendor/rails/actionpack/test/controller/test_test.rb +16 -0
  129. data/vendor/rails/actionpack/test/controller/url_rewriter_test.rb +66 -10
  130. data/vendor/rails/actionpack/test/controller/verification_test.rb +15 -0
  131. data/vendor/rails/actionpack/test/fixtures/test/hello_world.rxml +2 -1
  132. data/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb +5 -0
  133. data/vendor/rails/actionpack/test/template/compiled_templates_test.rb +29 -17
  134. data/vendor/rails/actionpack/test/template/javascript_helper_test.rb +4 -4
  135. data/vendor/rails/actionpack/test/template/number_helper_test.rb +1 -1
  136. data/vendor/rails/actionpack/test/template/prototype_helper_test.rb +13 -13
  137. data/vendor/rails/actionwebservice/CHANGELOG +14 -0
  138. data/vendor/rails/actionwebservice/Rakefile +2 -2
  139. data/vendor/rails/actionwebservice/lib/action_web_service/version.rb +1 -1
  140. data/vendor/rails/activerecord/CHANGELOG +34 -0
  141. data/vendor/rails/activerecord/Rakefile +1 -1
  142. data/vendor/rails/activerecord/lib/active_record/acts/list.rb +14 -2
  143. data/vendor/rails/activerecord/lib/active_record/acts/tree.rb +7 -0
  144. data/vendor/rails/activerecord/lib/active_record/associations.rb +29 -14
  145. data/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb +5 -1
  146. data/vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb +2 -2
  147. data/vendor/rails/activerecord/lib/active_record/associations/has_many_through_association.rb +10 -0
  148. data/vendor/rails/activerecord/lib/active_record/base.rb +12 -3
  149. data/vendor/rails/activerecord/lib/active_record/calculations.rb +2 -2
  150. data/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  151. data/vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  152. data/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +2 -2
  153. data/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb +54 -38
  154. data/vendor/rails/activerecord/lib/active_record/deprecated_finders.rb +3 -3
  155. data/vendor/rails/activerecord/lib/active_record/fixtures.rb +1 -1
  156. data/vendor/rails/activerecord/lib/active_record/timestamp.rb +0 -9
  157. data/vendor/rails/activerecord/lib/active_record/version.rb +1 -1
  158. data/vendor/rails/activerecord/test/associations/eager_test.rb +13 -0
  159. data/vendor/rails/activerecord/test/associations/join_model_test.rb +10 -1
  160. data/vendor/rails/activerecord/test/associations_test.rb +36 -3
  161. data/vendor/rails/activerecord/test/base_test.rb +17 -4
  162. data/vendor/rails/activerecord/test/defaults_test.rb +15 -0
  163. data/vendor/rails/activerecord/test/fixtures/author.rb +1 -0
  164. data/vendor/rails/activerecord/test/fixtures/binaries.yml +437 -0
  165. data/vendor/rails/activerecord/test/fixtures/db_definitions/schema.rb +13 -0
  166. data/vendor/rails/activerecord/test/fixtures/developer.rb +10 -0
  167. data/vendor/rails/activerecord/test/fixtures_test.rb +9 -5
  168. data/vendor/rails/activerecord/test/migration_test.rb +9 -10
  169. data/vendor/rails/activerecord/test/mixin_test.rb +47 -0
  170. data/vendor/rails/activerecord/test/validations_test.rb +2 -2
  171. data/vendor/rails/activesupport/CHANGELOG +16 -0
  172. data/vendor/rails/activesupport/lib/active_support/core_ext/blank.rb +9 -3
  173. data/vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb +48 -3
  174. data/vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb +14 -0
  175. data/vendor/rails/activesupport/lib/active_support/dependencies.rb +3 -3
  176. data/vendor/rails/activesupport/lib/active_support/json/encoders/core.rb +5 -3
  177. data/vendor/rails/activesupport/lib/active_support/multibyte/chars.rb +6 -6
  178. data/vendor/rails/activesupport/lib/active_support/version.rb +1 -1
  179. data/vendor/rails/activesupport/test/core_ext/hash_ext_test.rb +37 -0
  180. data/vendor/rails/activesupport/test/core_ext/module_test.rb +8 -0
  181. data/vendor/rails/activesupport/test/dependencies_test.rb +11 -0
  182. data/vendor/rails/activesupport/test/{json.rb → json_test.rb} +15 -5
  183. data/vendor/rails/railties/CHANGELOG +25 -1
  184. data/vendor/rails/railties/README +32 -3
  185. data/vendor/rails/railties/Rakefile +5 -5
  186. data/vendor/rails/railties/environments/boot.rb +12 -18
  187. data/vendor/rails/railties/environments/environment.rb +15 -15
  188. data/vendor/rails/railties/lib/dispatcher.rb +1 -2
  189. data/vendor/rails/railties/lib/initializer.rb +33 -9
  190. data/vendor/rails/railties/lib/rails/version.rb +1 -1
  191. data/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +1 -1
  192. data/vendor/rails/railties/lib/rails_generator/generators/components/scaffold_resource/scaffold_resource_generator.rb +1 -0
  193. data/vendor/rails/railties/lib/railties_path.rb +1 -1
  194. data/vendor/rails/railties/lib/tasks/framework.rake +4 -4
  195. data/vendor/rails/railties/lib/tasks/routes.rake +17 -0
  196. data/vendor/rails/release.rb +2 -2
  197. metadata +1877 -1848
@@ -1,28 +1,13 @@
1
- var RuledTable = Class.create();
2
- RuledTable.prototype = {
3
-
4
- initialize: function(element_id) {
5
- var table = $(element_id);
6
- var rows = table.getElementsByTagName('tr');
7
- for (var i = 0; i < rows.length; i++) {
8
- this.setupRow(rows[i]);
9
- }
10
- },
11
-
12
- onMouseOverRow: function(event) {
13
- // Element.addClassName(this, 'highlight');
14
- this.className = this.className.replace(/\s*\bhighlight\b|$/, ' highlight'); // faster than the above
1
+ var RuledTable = Class.create({
2
+ initialize: function(element) {
3
+ if (Prototype.Browser.IE)
4
+ $(element).
5
+ observe('mouseover', this.onMouseOverRow.bindAsEventListener(this, 'addClassName')).
6
+ observe('mouseout', this.onMouseOverRow.bindAsEventListener(this, 'removeClassName'));
15
7
  },
16
8
 
17
- onMouseOutRow: function(event) {
18
- // Element.removeClassName(this, 'highlight');
19
- this.className = this.className.replace(/\s*\bhighlight\b\s*/, ' '); // faster than the above
20
- },
21
-
22
- setupRow: function(row) {
23
- Event.observe(row, 'mouseover', this.onMouseOverRow.bindAsEventListener(row));
24
- Event.observe(row, 'mouseout', this.onMouseOutRow.bindAsEventListener(row));
25
- if (this.onRowSetup) this.onRowSetup(row);
9
+ onMouseOverRow: function(event, method) {
10
+ var row = event.findElement('tr');
11
+ if (row) row[method]('highlight');
26
12
  }
27
-
28
- };
13
+ });
@@ -1,43 +1,33 @@
1
- var SiteMap = Class.create();
2
- SiteMap.prototype = Object.extend({}, RuledTable.prototype); // Inherit from RuledTable
3
-
4
- Object.extend(SiteMap.prototype, {
5
-
6
- ruledTableInitialize: RuledTable.prototype.initialize,
7
-
8
- initialize: function(id, expanded) {
9
- this.ruledTableInitialize(id);
10
- this.expandedRows = expanded
11
- },
12
-
13
- onRowSetup: function(row) {
14
- Event.observe(row, 'click', this.onMouseClickRow.bindAsEventListener(this), false);
1
+ var SiteMap = Class.create(RuledTable, {
2
+ initialize: function($super, element) {
3
+ $super(element);
4
+ this.readExpandedCookie();
5
+ Event.observe(element, 'click', this.onMouseClickRow.bindAsEventListener(this));
15
6
  },
16
7
 
17
8
  onMouseClickRow: function(event) {
18
- var element = Event.element(event);
19
- if (this.isExpander(element)) {
20
- var row = Event.findElement(event, 'tr');
9
+ if (this.isExpander(event.target)) {
10
+ var row = event.findElement('tr');
21
11
  if (this.hasChildren(row)) {
22
- this.toggleBranch(row, element);
12
+ this.toggleBranch(row, event.target);
23
13
  }
24
14
  }
25
15
  },
26
16
 
27
17
  hasChildren: function(row) {
28
- return ! /\bno-children\b/.test(row.className);
18
+ return !row.hasClassName('no-children');
29
19
  },
30
20
 
31
21
  isExpander: function(element) {
32
- return (element.tagName.strip().downcase() == 'img') && /\bexpander\b/i.test(element.className);
22
+ return element.match('img.expander');
33
23
  },
34
24
 
35
25
  isExpanded: function(row) {
36
- return /\bchildren-visible\b/i.test(row.className);
26
+ return row.hasClassName('children-visible');
37
27
  },
38
28
 
39
29
  isRow: function(element) {
40
- return element.tagName && (element.tagName.strip().downcase() == 'tr');
30
+ return element && element.tagName && element.match('tr');
41
31
  },
42
32
 
43
33
  extractLevel: function(row) {
@@ -51,119 +41,91 @@ Object.extend(SiteMap.prototype, {
51
41
  },
52
42
 
53
43
  getExpanderImageForRow: function(row) {
54
- var images = $A(row.getElementsByTagName('img', row));
55
- var expanders = [];
56
- images.each(function(image){
57
- expanders.push(image);
58
- }.bind(this));
59
- return expanders.first();
60
- },
44
+ return row.down('img');
45
+ },
61
46
 
47
+ readExpandedCookie: function() {
48
+ var matches = document.cookie.match(/expanded_rows=(.+?);/);
49
+ this.expandedRows = matches ? matches[1].split(',') : [];
50
+ },
51
+
62
52
  saveExpandedCookie: function() {
63
53
  document.cookie = "expanded_rows=" + this.expandedRows.uniq().join(",") + "; path=/admin";
64
54
  },
65
-
66
- hideBranch: function(row, img) {
67
- var level = this.extractLevel(row);
68
- var sibling = row.nextSibling;
69
- while(sibling != null) {
70
- if (this.isRow(sibling)) {
71
- if (this.extractLevel(sibling) <= level) break;
72
- Element.hide(sibling);
73
- }
74
- sibling = sibling.nextSibling;
75
- }
55
+
56
+ persistCollapsed: function(row) {
76
57
  var pageId = this.extractPageId(row);
77
- var newExpanded = [];
78
- for(i = 0; i < this.expandedRows.length; i++)
79
- if(this.expandedRows[i] != pageId)
80
- newExpanded.push(this.expandedRows[i]);
81
- this.expandedRows = newExpanded;
58
+ this.expandedRows = this.expandedRows.without(pageId);
59
+ this.saveExpandedCookie();
60
+ },
61
+
62
+ persistExpanded: function(row) {
63
+ this.expandedRows.push(this.extractPageId(row));
82
64
  this.saveExpandedCookie();
83
- if (img == null)
84
- img = this.getExpanderImageForRow(row);
85
- img.src = img.src.replace(/collapse/, 'expand');
86
- Element.removeClassName(row, 'children-visible');
87
- Element.addClassName(row, 'children-hidden');
65
+ },
66
+
67
+ toggleExpanded: function(row, img) {
68
+ if (!img) img = this.getExpanderImageForRow(row);
69
+ if (this.isExpanded(row)) {
70
+ img.src = img.src.replace('collapse', 'expand');
71
+ row.removeClassName('children-visible');
72
+ row.addClassName('children-hidden');
73
+ this.persistCollapsed(row);
74
+ } else {
75
+ img.src = img.src.replace('expand', 'collapse');
76
+ row.removeClassName('children-hidden');
77
+ row.addClassName('children-visible');
78
+ this.persistExpanded(row);
79
+ }
88
80
  },
89
81
 
90
- showBranchInternal: function(row, img) {
91
- var level = this.extractLevel(row);
92
- var sibling = row.nextSibling;
93
- var children = false;
94
- var childOwningSiblings = [];
95
- while(sibling != null) {
96
- if (this.isRow(sibling)) {
97
- var siblingLevel = this.extractLevel(sibling);
98
- if (siblingLevel <= level) break;
99
- if (siblingLevel == level + 1) {
100
- Element.show(sibling);
101
- if(sibling.className.match(/children-visible/)) {
102
- childOwningSiblings.push(sibling);
103
- } else {
104
- this.hideBranch(sibling);
105
- }
106
- }
107
- children = true;
108
- }
109
- sibling = sibling.nextSibling;
82
+ hideBranch: function(parent, img) {
83
+ var level = this.extractLevel(parent), row = parent.next();
84
+ while (this.isRow(row) && this.extractLevel(row) > level) {
85
+ row.hide();
86
+ row = row.next();
110
87
  }
111
- if (!children)
112
- this.getBranch(row);
113
- if (img == null)
114
- img = this.getExpanderImageForRow(row);
115
- img.src = img.src.replace(/expand/, 'collapse');
116
- for(i=0; i < childOwningSiblings.length; i++) {
117
- this.showBranch(childOwningSiblings[i], null);
118
- }
119
- Element.removeClassName(row, 'children-hidden');
120
- Element.addClassName(row, 'children-visible');
88
+ this.toggleExpanded(parent, img);
121
89
  },
122
90
 
123
- showBranch: function(row, img) {
124
- this.showBranchInternal(row, img);
125
- this.expandedRows.push(this.extractPageId(row));
126
- this.saveExpandedCookie();
91
+ showBranch: function(parent, img) {
92
+ var level = this.extractLevel(parent), row = parent.next(),
93
+ children = false, expandLevels = [level + 1];
94
+
95
+ while (this.isRow(row)) {
96
+ var currentLevel = this.extractLevel(row);
97
+ if (currentLevel <= level) break;
98
+ children = true;
99
+ if (currentLevel < expandLevels.last()) expandLevels.pop();
100
+ if (expandLevels.include(currentLevel)) {
101
+ row.show();
102
+ if (this.isExpanded(row)) expandLevels.push(currentLevel + 1);
103
+ }
104
+ row = row.next();
105
+ }
106
+ if (!children) this.getBranch(parent);
107
+ this.toggleExpanded(parent, img);
127
108
  },
128
109
 
129
110
  getBranch: function(row) {
130
- var level = this.extractLevel(row).toString();
131
- var id = this.extractPageId(row).toString();
111
+ var id = this.extractPageId(row), level = this.extractLevel(row),
112
+ spinner = $('busy-' + id);
113
+
132
114
  new Ajax.Updater(
133
115
  row,
134
116
  '../admin/ui/pages/children/' + id + '/' + level,
135
117
  {
136
- asynchronous: true,
137
- insertion: Insertion.After,
138
- onLoading: function(request) {
139
- Element.show('busy-' + id);
140
- this.updating = true;
141
- }.bind(this),
142
- onComplete: function(request) {
143
- var sibling = row.nextSibling;
144
- while (sibling != null) {
145
- if (this.isRow(sibling)) {
146
- var siblingLevel = this.extractLevel(sibling);
147
- if (siblingLevel <= level) break;
148
- this.setupRow(sibling);
149
- }
150
- sibling = sibling.nextSibling;
151
- }
152
- this.updating = false;
153
- Effect.Fade('busy-' + id);
154
- }.bind(this)
118
+ insertion: "after",
119
+ onLoading: function() { spinner.show(); this.updating = true }.bind(this),
120
+ onComplete: function() { spinner.fade(); this.updating = false }.bind(this)
155
121
  }
156
122
  );
157
123
  },
158
124
 
159
125
  toggleBranch: function(row, img) {
160
- if (! this.updating) {
161
- if (this.isExpanded(row)) {
162
- this.hideBranch(row, img);
163
- } else {
164
- this.showBranch(row, img);
165
- }
126
+ if (!this.updating) {
127
+ var method = (this.isExpanded(row) ? 'hide' : 'show') + 'Branch';
128
+ this[method](row, img);
166
129
  }
167
130
  }
168
-
169
131
  });
@@ -1,5 +1,4 @@
1
1
  Object.extend(String.prototype, {
2
-
3
2
  upcase: function() {
4
3
  return this.toUpperCase();
5
4
  },
@@ -8,10 +7,6 @@ Object.extend(String.prototype, {
8
7
  return this.toLowerCase();
9
8
  },
10
9
 
11
- strip: function() {
12
- return this.replace(/^\s+/, '').replace(/\s+$/, '');
13
- },
14
-
15
10
  toInteger: function() {
16
11
  return parseInt(this);
17
12
  },
@@ -19,5 +14,4 @@ Object.extend(String.prototype, {
19
14
  toSlug: function() {
20
15
  return this.strip().downcase().replace(/[^-a-z0-9~\s\.:;+=_]/g, '').replace(/[\s\.:;=+]+/g, '-');
21
16
  }
22
-
23
- });
17
+ });
@@ -1,19 +1,14 @@
1
- var TabControl = Class.create();
2
-
3
- TabControl.controls = $H();
4
- TabControl.BadTabError = new Error('TabControl: Invalid tab.');
5
-
6
- TabControl.prototype = {
1
+ var TabControl = Class.create({
7
2
  /*
8
3
  Initializes a tab control. The variable +element_id+ must be the id of an HTML element
9
4
  containing one element with it's class name set to 'tabs' and another element with it's
10
5
  class name set to 'pages'.
11
6
  */
12
- initialize: function(element_id) {
13
- TabControl.controls[element_id] = this;
14
- this.control_id = element_id;
15
- this.element = $(element_id);
16
- this.tab_container = document.getElementsByClassName('tabs', this.element).first();
7
+ initialize: function(element) {
8
+ this.element = $(element);
9
+ this.control_id = this.element.identify();
10
+ TabControl.controls.set(this.control_id, this);
11
+ this.tab_container = this.element.down('.tabs');
17
12
  this.tabs = $H();
18
13
  },
19
14
 
@@ -24,37 +19,24 @@ TabControl.prototype = {
24
19
  itself. When a tab is initially added the page element is hidden.
25
20
  */
26
21
  addTab: function(tab_id, caption, page) {
27
- new Insertion.Bottom(
28
- this.tab_container,
29
- '<a class="tab" href="javascript:TabControl.controls[\''
30
- + this.control_id
31
- + '\'].select(\'' + tab_id + '\');">' + caption + '</a>'
32
- );
33
- var tab = this.tab_container.lastChild;
34
- tab.tab_id = tab_id;
35
- tab.caption = caption;
36
- tab.page = $(page);
37
- this.tabs[tab_id] = tab;
38
- this._setNotHere(tab);
39
- return tab;
22
+ var tab = new TabControl.Tab(this, tab_id, caption, page);
23
+
24
+ this.tabs.set(tab.id, tab);
25
+ return this.tab_container.appendChild(tab.createElement());
40
26
  },
41
27
 
42
28
  /*
43
29
  Removes +tab+. The variable +tab+ may be either a tab ID or a tab element.
44
30
  */
45
31
  removeTab: function(tab) {
46
- var t = this._tabify(tab);
47
- var id = t.tab_id;
48
- Element.remove(t.page);
49
- Element.remove(t);
50
- new_tabs = $H();
51
- this.tabs.each(function(pair) {
52
- if (pair.key != id) new_tabs[pair.key] = pair.value;
53
- });
54
- this.tabs = new_tabs;
55
- if (this.selected.tab_id == id) {
32
+ if (Object.isString(tab)) tab = this.tabs.get(tab);
33
+ tab.remove();
34
+ this.tabs.unset(tab);
35
+
36
+ if (this.selected == tab) {
56
37
  var first = this.firstTab();
57
- if (typeof first != 'undefined') this.select(first.tab_id);
38
+ if (first) this.select(first);
39
+ else this.selected = null;
58
40
  }
59
41
  },
60
42
 
@@ -63,32 +45,26 @@ TabControl.prototype = {
63
45
  tab element.
64
46
  */
65
47
  select: function(tab) {
66
- var t = this._tabify(tab);
67
- this.tabs.each(function(pair) {
68
- if (pair.key == t.tab_id) {
69
- if (this.selected) this.selected.selected = false;
70
- this.selected = t;
71
- t.selected = true;
72
- this._setHere(pair.key);
73
- } else {
74
- this._setNotHere(pair.key);
75
- }
76
- }.bind(this));
77
- false;
48
+ if (Object.isString(tab)) tab = this.tabs.get(tab);
49
+ if (this.selected) this.selected.unselect();
50
+ tab.select();
51
+ this.selected = tab;
52
+ var persist = this.pageId() + ':' + this.selected.id;
53
+ document.cookie = "current_tab=" + persist + "; path=/admin";
78
54
  },
79
55
 
80
56
  /*
81
57
  Returns the first tab element that was added using #addTab().
82
58
  */
83
59
  firstTab: function() {
84
- return this.tabs[this.tabs.keys().first()];
60
+ return this.tabs.get(this.tabs.keys().first());
85
61
  },
86
62
 
87
63
  /*
88
64
  Returns the the last tab element that was added using #addTab().
89
65
  */
90
66
  lastTab: function() {
91
- return this.tabs[this.tabs.keys().last()];
67
+ return this.tabs.get(this.tabs.keys().last());
92
68
  },
93
69
 
94
70
  /*
@@ -97,44 +73,53 @@ TabControl.prototype = {
97
73
  tabCount: function() {
98
74
  return this.tabs.keys().length;
99
75
  },
100
-
101
- /*
102
- Private Methods
103
- */
104
-
105
- /*
106
- Shows the page for +tab+ and adds the class 'here' to tab. The variable +tab+ may
107
- be either a tab ID or a tab element.
108
- */
109
- _setHere: function(tab) {
110
- var t = this._tabify(tab);
111
- Element.show(t.page);
112
- Element.addClassName(t, 'here');
76
+
77
+ autoSelect: function() {
78
+ var tab, matches = document.cookie.match(/current_tab=(.+?);/);
79
+ if (matches) {
80
+ matches = matches[1].split(':');
81
+ var page = matches[0], tabId = matches[1];
82
+ if (!page || page == this.pageId()) tab = this.tabs.get(tabId);
83
+ }
84
+ this.select(tab || this.firstTab());
113
85
  },
114
-
115
- /*
116
- Hides the page for +tab+ and removes the class 'here' from tab. The variable +tab+
117
- may be either a tab ID or a tab element.
118
- */
119
- _setNotHere: function(tab) {
120
- var t = this._tabify(tab);
121
- Element.hide(t.page);
122
- Element.removeClassName(t, 'here');
86
+
87
+ pageId: function() {
88
+ return /(\d+)/.test(window.location.pathname) ? RegExp.$1 : '';
89
+ }
90
+ });
91
+
92
+ TabControl.controls = $H();
93
+
94
+ TabControl.Tab = Class.create({
95
+ initialize: function(control, id, label, content) {
96
+ this.content = $(content).hide();
97
+ this.label = label || id;
98
+ this.id = id;
99
+ this.control = control;
123
100
  },
124
101
 
125
- /*
126
- Returns a tab when passed a string or tab element. Throws a BadTabError otherwise.
127
- */
128
- _tabify: function(something) {
129
- if (typeof something == 'string') {
130
- var object = this.tabs[something];
131
- } else {
132
- var object = something;
133
- }
134
- if ((typeof object != 'undefined') && (object.tab_id)) {
135
- return object;
136
- } else {
137
- throw TabControl.BadTabError;
138
- }
102
+ createElement: function() {
103
+ return this.element = new Element('a', { className: 'tab', href: '#' }).
104
+ update("<span>" + this.label + "</span>").
105
+ observe('click', function(event){
106
+ this.control.select(this.id);
107
+ event.stop();
108
+ }.bindAsEventListener(this));
109
+ },
110
+
111
+ select: function() {
112
+ this.content.show();
113
+ this.element.addClassName('here');
114
+ },
115
+
116
+ unselect: function() {
117
+ this.content.hide();
118
+ this.element.removeClassName('here');
119
+ },
120
+
121
+ remove: function() {
122
+ this.content.remove();
123
+ this.element.stopObserving('click').remove();
139
124
  }
140
- };
125
+ });