hobo 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/bin/hobo +24 -7
  2. data/hobo_files/plugin/CHANGES.txt +501 -0
  3. data/hobo_files/plugin/generators/hobo/hobo_generator.rb +8 -6
  4. data/hobo_files/plugin/generators/hobo/templates/application.dryml +3 -0
  5. data/hobo_files/plugin/generators/hobo/templates/dryml-support.js +132 -0
  6. data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +4 -5
  7. data/hobo_files/plugin/generators/hobo_model_resource/hobo_model_resource_generator.rb +75 -0
  8. data/hobo_files/plugin/generators/hobo_model_resource/templates/controller.rb +7 -0
  9. data/hobo_files/plugin/generators/hobo_model_resource/templates/functional_test.rb +8 -0
  10. data/hobo_files/plugin/generators/hobo_model_resource/templates/helper.rb +2 -0
  11. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo-rapid.js +30 -11
  12. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/application.css +149 -92
  13. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +0 -48
  14. data/hobo_files/plugin/init.rb +45 -13
  15. data/hobo_files/plugin/lib/action_view_extensions/base.rb +4 -3
  16. data/hobo_files/plugin/lib/active_record/association_proxy.rb +18 -0
  17. data/hobo_files/plugin/lib/active_record/association_reflection.rb +5 -0
  18. data/hobo_files/plugin/lib/active_record/has_many_association.rb +7 -11
  19. data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +8 -0
  20. data/hobo_files/plugin/lib/extensions/test_case.rb +1 -1
  21. data/hobo_files/plugin/lib/hobo.rb +38 -60
  22. data/hobo_files/plugin/lib/hobo/authentication_support.rb +1 -1
  23. data/hobo_files/plugin/lib/hobo/bundle.rb +131 -34
  24. data/hobo_files/plugin/lib/hobo/composite_model.rb +1 -1
  25. data/hobo_files/plugin/lib/hobo/controller.rb +7 -8
  26. data/hobo_files/plugin/lib/hobo/dev_controller.rb +21 -0
  27. data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +14 -8
  28. data/hobo_files/plugin/lib/hobo/dryml/dryml_support_controller.rb +13 -0
  29. data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +6 -7
  30. data/hobo_files/plugin/lib/hobo/dryml/template.rb +207 -73
  31. data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +67 -55
  32. data/hobo_files/plugin/lib/hobo/dryml/template_handler.rb +53 -3
  33. data/hobo_files/plugin/lib/hobo/hobo_helper.rb +75 -107
  34. data/hobo_files/plugin/lib/hobo/model.rb +236 -429
  35. data/hobo_files/plugin/lib/hobo/model_controller.rb +277 -437
  36. data/hobo_files/plugin/lib/hobo/model_router.rb +62 -29
  37. data/hobo_files/plugin/lib/hobo/rapid_helper.rb +48 -9
  38. data/hobo_files/plugin/lib/hobo/scopes.rb +98 -0
  39. data/hobo_files/plugin/lib/hobo/scopes/association_proxy_extensions.rb +31 -0
  40. data/hobo_files/plugin/lib/hobo/scopes/automatic_scopes.rb +282 -0
  41. data/hobo_files/plugin/lib/hobo/scopes/defined_scope_proxy_extender.rb +88 -0
  42. data/hobo_files/plugin/lib/hobo/scopes/scope_reflection.rb +18 -0
  43. data/hobo_files/plugin/lib/hobo/scopes/scoped_proxy.rb +59 -0
  44. data/hobo_files/plugin/lib/hobo/undefined.rb +2 -0
  45. data/hobo_files/plugin/lib/hobo/user.rb +31 -14
  46. data/hobo_files/plugin/lib/hobo/user_controller.rb +41 -27
  47. data/hobo_files/plugin/taglibs/core.dryml +9 -11
  48. data/hobo_files/plugin/taglibs/rapid.dryml +51 -108
  49. data/hobo_files/plugin/taglibs/rapid_editing.dryml +25 -25
  50. data/hobo_files/plugin/taglibs/rapid_forms.dryml +111 -79
  51. data/hobo_files/plugin/taglibs/rapid_generics.dryml +74 -0
  52. data/hobo_files/plugin/taglibs/rapid_navigation.dryml +23 -21
  53. data/hobo_files/plugin/taglibs/rapid_pages.dryml +83 -169
  54. data/hobo_files/plugin/taglibs/rapid_plus.dryml +16 -2
  55. data/hobo_files/plugin/taglibs/rapid_support.dryml +3 -3
  56. data/hobo_files/plugin/taglibs/rapid_user_pages.dryml +104 -0
  57. metadata +60 -55
  58. data/hobo_files/plugin/generators/hobo_migration/hobo_migration_generator.rb +0 -276
  59. data/hobo_files/plugin/generators/hobo_migration/templates/migration.rb +0 -9
  60. data/hobo_files/plugin/lib/active_record/table_definition.rb +0 -34
  61. data/hobo_files/plugin/lib/extensions.rb +0 -375
  62. data/hobo_files/plugin/lib/hobo/email_address.rb +0 -12
  63. data/hobo_files/plugin/lib/hobo/enum_string.rb +0 -50
  64. data/hobo_files/plugin/lib/hobo/field_declaration_dsl.rb +0 -43
  65. data/hobo_files/plugin/lib/hobo/field_spec.rb +0 -68
  66. data/hobo_files/plugin/lib/hobo/html_string.rb +0 -7
  67. data/hobo_files/plugin/lib/hobo/lazy_hash.rb +0 -40
  68. data/hobo_files/plugin/lib/hobo/markdown_string.rb +0 -11
  69. data/hobo_files/plugin/lib/hobo/migrations.rb +0 -12
  70. data/hobo_files/plugin/lib/hobo/model_queries.rb +0 -117
  71. data/hobo_files/plugin/lib/hobo/password_string.rb +0 -7
  72. data/hobo_files/plugin/lib/hobo/percentage.rb +0 -14
  73. data/hobo_files/plugin/lib/hobo/predicate_dispatch.rb +0 -78
  74. data/hobo_files/plugin/lib/hobo/proc_binding.rb +0 -32
  75. data/hobo_files/plugin/lib/hobo/text.rb +0 -3
  76. data/hobo_files/plugin/lib/hobo/textile_string.rb +0 -25
  77. data/hobo_files/plugin/lib/hobo/where_fragment.rb +0 -28
@@ -7,19 +7,21 @@ class HoboGenerator < Rails::Generator::Base
7
7
  route = " Hobo.add_routes(map)\n"
8
8
 
9
9
  route_src = File.read(routes_path)
10
- return if route_src.include?(route)
11
-
12
- head = "ActionController::Routing::Routes.draw do |map|"
13
- route_src.sub!(head, head + "\n\n" + route)
14
- File.open(routes_path, 'w') {|f| f.write(route_src) }
10
+
11
+ unless route_src.include?(route)
12
+ head = "ActionController::Routing::Routes.draw do |map|"
13
+ route_src.sub!(head, head + "\n\n" + route)
14
+ File.open(routes_path, 'w') {|f| f.write(route_src) }
15
+ end
15
16
  end
16
17
 
17
18
  record do |m|
18
19
  m.directory File.join("app/views/taglibs")
19
20
  m.directory File.join("app/views/taglibs/themes")
20
21
  m.directory File.join("public/hobothemes")
21
- m.file "application.dryml", File.join("app/views/taglibs/application.dryml")
22
+ m.template "application.dryml", File.join("app/views/taglibs/application.dryml")
22
23
  m.file "guest.rb", File.join("app/models/guest.rb")
24
+ m.file "dryml-support.js", File.join("public/javascripts/dryml-support.js")
23
25
  end
24
26
  end
25
27
 
@@ -1,2 +1,5 @@
1
1
  <!-- Define your application-wide tags here -->
2
2
 
3
+ <def tag="app-name"><%= File.basename(Dir.chdir(RAILS_ROOT) { Dir.getwd }).strip.titleize %></def>
4
+
5
+
@@ -0,0 +1,132 @@
1
+ Event.addBehavior({
2
+ 'body:click' : function(event) {
3
+ if (event.shiftKey && event.altKey) {
4
+ Dryml.click(event)
5
+ Event.stop(event)
6
+ }
7
+ }
8
+ })
9
+
10
+
11
+ var Dryml = {
12
+
13
+ menu: null,
14
+ event: null,
15
+
16
+ click: function(event) {
17
+ Dryml.event = event
18
+ Dryml.showSourceMenu(event.target)
19
+ },
20
+
21
+ showSourceMenu: function(element) {
22
+ var stack = Dryml.getSrcInfoStack(element)
23
+ Dryml.showMenu(stack)
24
+ },
25
+
26
+ getSrcInfoStack: function(element) {
27
+ var stack = $A()
28
+ while(element != document.documentElement) {
29
+ var el = Dryml.findPrecedingDrymlInfo(element)
30
+ if (el == null) {
31
+ element = element.parentNode
32
+ } else {
33
+ element = el
34
+ var info = Dryml.getDrymlInfo(element)
35
+ stack.push(info)
36
+ }
37
+ }
38
+ return stack
39
+ },
40
+
41
+ findPrecedingDrymlInfo: function(element) {
42
+ var ignoreCount = 0
43
+ var el = element
44
+ while (el = el.previousSibling) {
45
+ if (Dryml.isDrymlInfo(el)) {
46
+ if (ignoreCount > 0)
47
+ ignoreCount -= 1;
48
+ else
49
+ return el
50
+ } else if (Dryml.isDrymlInfoClose(el)) {
51
+ ignoreCount += 1
52
+ }
53
+ }
54
+ return null
55
+ },
56
+
57
+ getDrymlInfo: function(el) {
58
+ var parts = el.nodeValue.sub(/^\[DRYML\|/, "").sub(/\[$/, "").split("|")
59
+ return { kind: parts[0], tag: parts[1], line: parts[2], file: parts[3] }
60
+ },
61
+
62
+ isDrymlInfo: function(el) {
63
+ return el.nodeType == Node.COMMENT_NODE && el.nodeValue.match(/^\[DRYML/)
64
+ },
65
+
66
+ isDrymlInfoClose: function(el) {
67
+ return el.nodeType == Node.COMMENT_NODE && el.nodeValue == "]DRYML]"
68
+ },
69
+
70
+ showMenu: function(stack) {
71
+ Dryml.removeMenu()
72
+
73
+ var style = $style({id: "dryml-menu-style"},
74
+ "#dryml-src-menu { position: fixed; margin: 10px; padding: 10px; background: black; color: white; border: 1px solid white; }\n",
75
+ "#dryml-src-menu a { color: white; text-decoration: none; border: none; }\n",
76
+ "#dryml-src-menu td { padding: 2px 7px; }\n",
77
+ "#dryml-src-menu a:hover { background: black; color: white; text-decoration: none; border: none; }\n")
78
+ $$("head")[0].appendChild(style)
79
+
80
+ var items = stack.map(Dryml.makeMenuItem)
81
+
82
+ var closer = $a({href:"#"}, "[close]")
83
+ closer.onclick = Dryml.removeMenu
84
+ Dryml.menu = $div({id: "dryml-src-menu",
85
+ style: "position: fixed; margin: 10px; padding: 10px; background: black; color: #cfc; border: 1px solid white;"
86
+ },
87
+ closer,
88
+ $table(items))
89
+
90
+ document.body.appendChild(Dryml.menu)
91
+ Dryml.menu.style.top = "20px"//Dryml.event.clientY + "px"
92
+ Dryml.menu.style.left = "20px"//Dryml.event.clientX + "px"
93
+ },
94
+
95
+ editSourceFile: function(path, line) {
96
+ new Ajax.Request("/dryml/edit_source?file=" + path + "&line=" + line)
97
+ },
98
+
99
+
100
+ makeMenuItem: function(item) {
101
+ var text
102
+ switch (item.kind) {
103
+ case "call":
104
+ text = "<" + item.tag + ">"
105
+ break
106
+ case "param":
107
+ text = "<" + item.tag + ":>"
108
+ break
109
+ case "replace":
110
+ text = "<" + item.tag + ": replace>"
111
+ break
112
+ case "def":
113
+ text = "<def " + item.tag + ">"
114
+ break
115
+ }
116
+ var a = $a({href:"#"}, text)
117
+ a.onclick = function() { Dryml.editSourceFile(item.file, item.line); return false }
118
+
119
+ var filename = item.file.sub("vendor/plugins", "").sub("app/views", "").sub(/^\/+/, "").sub(".dryml", "")
120
+
121
+ return $tr($td({"class": "file"}, filename), $td(a))
122
+ },
123
+
124
+ removeMenu: function() {
125
+ if (Dryml.menu) {
126
+ $("dryml-menu-style").remove()
127
+ Dryml.menu.remove()
128
+ Dryml.menu = null
129
+ }
130
+ }
131
+
132
+ }
@@ -1,6 +1,6 @@
1
1
  class HoboFrontControllerGenerator < Rails::Generator::NamedBase
2
2
 
3
- default_options :no_user => false, :delete_index => false, :add_routes => false
3
+ default_options :delete_index => false, :add_routes => false
4
4
 
5
5
  def full_class_path
6
6
  class_path.blank? ? file_name : File.join(class_path, file_name)
@@ -34,8 +34,7 @@ class HoboFrontControllerGenerator < Rails::Generator::NamedBase
34
34
  File.join('app/helpers', class_path, "#{file_name}_helper.rb"))
35
35
 
36
36
 
37
- pages = options[:no_user] ? %w{index search} : %w{index search}
38
- for page in pages
37
+ for page in %w{index search}
39
38
  m.template("#{page}.dryml", File.join('app/views', class_path, file_name, "#{page}.dryml"))
40
39
  end
41
40
  end
@@ -49,7 +48,7 @@ class HoboFrontControllerGenerator < Rails::Generator::NamedBase
49
48
  routes_path = File.join(RAILS_ROOT, "config/routes.rb")
50
49
  name = full_class_path
51
50
 
52
- route = (" map.search 'search', :controller => '#{name}', :action => 'search'\n" +
51
+ route = (" map.site_search 'search', :controller => '#{name}', :action => 'search'\n" +
53
52
  " map.homepage '', :controller => '#{name}', :action => 'index'")
54
53
 
55
54
  route_src = File.read(routes_path)
@@ -68,7 +67,7 @@ class HoboFrontControllerGenerator < Rails::Generator::NamedBase
68
67
 
69
68
  protected
70
69
  def banner
71
- "Usage: #{$0} #{spec.name} <controller-name> [--add-routes] [--no-user] [--delete-index]"
70
+ "Usage: #{$0} #{spec.name} <controller-name> [--add-routes] [--delete-index]"
72
71
  end
73
72
 
74
73
  def add_options!(opt)
@@ -0,0 +1,75 @@
1
+ class HoboModelResourceGenerator < Rails::Generator::NamedBase
2
+
3
+ default_options :skip_timestamps => false
4
+
5
+ attr_reader :controller_name,
6
+ :controller_class_path,
7
+ :controller_file_path,
8
+ :controller_class_nesting,
9
+ :controller_class_nesting_depth,
10
+ :controller_class_name,
11
+ :controller_singular_name,
12
+ :controller_plural_name
13
+ alias_method :controller_file_name, :controller_singular_name
14
+ alias_method :controller_table_name, :controller_plural_name
15
+
16
+ def initialize(runtime_args, runtime_options = {})
17
+ super
18
+
19
+ @controller_name = @name.pluralize
20
+
21
+ base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(@controller_name)
22
+ @controller_class_name_without_nesting, @controller_singular_name, @controller_plural_name = inflect_names(base_name)
23
+
24
+ if @controller_class_nesting.empty?
25
+ @controller_class_name = @controller_class_name_without_nesting
26
+ else
27
+ @controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
28
+ end
29
+ end
30
+
31
+ def manifest
32
+ record do |m|
33
+ # Check for class naming collisions.
34
+ m.class_collisions(controller_class_path, "#{controller_class_name}Controller", "#{controller_class_name}Helper")
35
+ m.class_collisions(class_path, "#{class_name}")
36
+
37
+ # Controller, helper, views, and test directories.
38
+ m.directory(File.join('app/models', class_path))
39
+ m.directory(File.join('app/controllers', controller_class_path))
40
+ m.directory(File.join('app/helpers', controller_class_path))
41
+ m.directory(File.join('app/views', controller_class_path, controller_file_name))
42
+ m.directory(File.join('test/functional', controller_class_path))
43
+ m.directory(File.join('test/unit', class_path))
44
+
45
+ m.dependency 'hobo_model', [name] + @args, :collision => :skip
46
+
47
+ m.template(
48
+ 'controller.rb', File.join('app/controllers', controller_class_path, "#{controller_file_name}_controller.rb")
49
+ )
50
+
51
+ m.template('functional_test.rb', File.join('test/functional', controller_class_path, "#{controller_file_name}_controller_test.rb"))
52
+ m.template('helper.rb', File.join('app/helpers', controller_class_path, "#{controller_file_name}_helper.rb"))
53
+
54
+ m.route_resources controller_file_name
55
+ end
56
+ end
57
+
58
+ protected
59
+ def banner
60
+ "Usage: #{$0} resource ModelName [field:type, field:type]"
61
+ end
62
+
63
+ def add_options!(opt)
64
+ opt.separator ''
65
+ opt.separator 'Options:'
66
+ opt.on("--skip-timestamps",
67
+ "Don't add timestamps to the migration file for this model") { |v| options[:skip_timestamps] = v }
68
+ opt.on("--skip-migration",
69
+ "Don't generate a migration file for this model") { |v| options[:skip_migration] = v }
70
+ end
71
+
72
+ def model_name
73
+ class_name.demodulize
74
+ end
75
+ end
@@ -0,0 +1,7 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+
3
+ hobo_model_controller
4
+
5
+ auto_actions :all
6
+
7
+ end
@@ -0,0 +1,8 @@
1
+ require File.dirname(__FILE__) + '<%= '/..' * class_nesting_depth %>/../test_helper'
2
+
3
+ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
4
+ # Replace this with your real tests.
5
+ def test_truth
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,2 @@
1
+ module <%= controller_class_name %>Helper
2
+ end
@@ -37,7 +37,7 @@ var Hobo = {
37
37
 
38
38
  var opts = Object.merge(options || {}, { params: params})
39
39
  Hobo.ajaxRequest(Hobo.putUrl(el),
40
- el.getAttribute("hobo-ajax-message") || "Changing...",
40
+ el.getAttribute("hobo-ajax-message") || "Saving...",
41
41
  updates,
42
42
  opts)
43
43
  },
@@ -73,11 +73,12 @@ var Hobo = {
73
73
  return params.join('&')
74
74
  },
75
75
 
76
- ajaxRequest: function(url_or_form, message, updates, options) {
76
+ ajaxRequest: function(url_or_form, updates, options) {
77
77
  options = Object.merge({ asynchronous:true,
78
78
  evalScripts:true,
79
79
  resetForm: false,
80
- refocusForm: false
80
+ refocusForm: false,
81
+ message: "Saving..."
81
82
  }, options)
82
83
  if (typeof url_or_form == "string") {
83
84
  var url = url_or_form
@@ -104,7 +105,7 @@ var Hobo = {
104
105
  params.push(Form.serialize(form))
105
106
  }
106
107
 
107
- Hobo.showSpinner(message, options.spinnerNextTo)
108
+ Hobo.showSpinner(options.message, options.spinnerNextTo)
108
109
  var complete = function() {
109
110
  if (form && options.resetForm) form.reset();
110
111
  Hobo.hideSpinner();
@@ -385,7 +386,7 @@ var Hobo = {
385
386
  if(t = $('ajax-progress-text')) Element.update(t, message);
386
387
  if(e = $('ajax-progress')) {
387
388
  if (nextTo) {
388
- var pos = nextTo.cumulativeOffset()
389
+ var pos = $(nextTo).cumulativeOffset()
389
390
  e.style.top = pos.top + "px"
390
391
  e.style.left = (pos.left + nextTo.offsetWidth) + "px"
391
392
  }
@@ -431,8 +432,14 @@ var Hobo = {
431
432
  return pluralisations[s] || s + "s"
432
433
  },
433
434
 
434
- addUrlParams: function(params) {
435
+ addUrlParams: function(params, options) {
435
436
  params = $H(window.location.search.toQueryParams()).merge(params)
437
+
438
+ if (options.remove) {
439
+ var remove = (options.remove instanceof Array) ? options.remove : [options.remove]
440
+ remove.each(function(k) { params.unset(k) })
441
+ }
442
+
436
443
  return window.location.href.sub(/(\?.*|$)/, "?" + params.toQueryString())
437
444
  }
438
445
 
@@ -496,7 +503,7 @@ HasManyThroughInput = Behavior.create({
496
503
  var select = this.element.down('select')
497
504
  var selected = select.options[select.selectedIndex]
498
505
  if (selected.style.display != "none" & selected.value != "") {
499
- var newItem = strToDom(this.element.down('.item-proto').innerHTML)
506
+ var newItem = DOM.Builder.fromHTML(this.element.down('.item-proto').innerHTML.strip())
500
507
  this.element.down('.items').appendChild(newItem);
501
508
  newItem.down('span').innerHTML = selected.innerHTML
502
509
  newItem.down('input[type=hidden]').value = selected.innerHTML
@@ -524,8 +531,20 @@ HasManyThroughInput = Behavior.create({
524
531
 
525
532
  Event.addBehavior({
526
533
  'div.has-many-through.input' : HasManyThroughInput(),
527
- '.dependent-collection-count:click' : function(e) {
528
- new Effect.ScrollTo('dependent-collection', {duration: 1.0, offset: -10, transition: Effect.Transitions.sinoidal});
529
- Event.stop(e);
530
- }
534
+ '.association-count:click' : function(e) {
535
+ new Effect.ScrollTo('primary-collection', {duration: 1.0, offset: -20, transition: Effect.Transitions.sinoidal});
536
+ Event.stop(e);
537
+ },
538
+ 'form.filter-menu select:change': function(event) {
539
+ var paramName = this.up('form').down('input[type=hidden]').value.gsub("-", "_")
540
+ var params = {}
541
+ remove = [ 'page' ]
542
+ if (this.value == '') {
543
+ remove.push(paramName)
544
+ } else {
545
+ params[paramName] = this.value
546
+ }
547
+ location.href = Hobo.addUrlParams(params, {remove: remove})
548
+ }
549
+
531
550
  });
@@ -1,37 +1,38 @@
1
1
  html {background: #666;}
2
2
  body {
3
- width: 760px; margin: 0 auto; background: white; color: #222;
4
- font: 12px "Lucida Grande", Arial, sans-serif;
5
- line-height: 18px; margin-bottom: 20px;
6
- }
7
- h1, h2, h3 {font-family: "Lucida Grande", "Trebuchet MS", "Arial", sans-serif; font-weight: normal;}
8
- h1 {font-size: 22px; line-height: 22px; margin: 20px 0 10px;}
9
- h2 {font-size: 18px; line-height: 18px; margin: 15px 0 10px;}
10
- h3 {font-size: 16px; line-height: 16px; margin: 10px 0 5px;}
11
- h4 {font-size: 14px; line-height: 14px; margin: 10px 0 5px;}
12
- h5 {font-size: 12px; line-height: 12px; margin: 10px 0 5px;}
13
- h6 {font-size: 10px; line-height: 10px; margin: 10px 0 5px;}
3
+ width: 760px;
4
+ margin: 0 auto 20px;
5
+ color: #222; background: white;
6
+ font: 12px "Lucida Grande", "Trebuchet MS", Arial, sans-serif; line-height: 18px;
7
+ }
8
+ h1, h2, h3 {font-weight: normal;}
9
+ h1 {margin: 20px 0 10px; font-size: 22px; line-height: 22px;}
10
+ h2 {margin: 15px 0 10px; font-size: 18px; line-height: 18px;}
11
+ h3 {margin: 10px 0 5px; font-size: 16px; line-height: 16px;}
12
+ h4 {margin: 10px 0 5px; font-size: 14px; line-height: 14px;}
13
+ h5 {margin: 10px 0 5px; font-size: 12px; line-height: 12px;}
14
+ h6 {margin: 10px 0 5px; font-size: 10px; line-height: 10px;}
14
15
 
15
16
  li {margin-left: 20px;}
16
17
 
17
18
  a {
18
- text-decoration: none; color: #222;
19
19
  border-bottom: 1px dotted #ccc;
20
- background: #fafafa;
20
+ color: #222; background: #fafafa;
21
+ text-decoration: none;
21
22
  }
22
23
  a:hover {
23
- border-bottom: 1px dotted #aaa; background: #f2f2f2; color: black;
24
+ border-bottom: 1px dotted #aaa;
25
+ color: black; background: #f2f2f2;
24
26
  }
25
- h1 a, h2 a, h3 a {background: none; border: none;}
27
+ h1 a, h2 a, h3 a {border: none; background: none;}
26
28
 
27
- input.text, input.string, input.email_address, input.password, input.search, input.integer, input.float, textarea {
28
- font-size:1.1em;
29
- line-height:1.3em;
29
+ input.text, input.string, input.email-address, input.password, input.search, input.integer, input.float, textarea {
30
30
  border-top:1px solid #7c7c7c;
31
31
  border-left:1px solid #c3c3c3;
32
32
  border-right:1px solid #c3c3c3;
33
33
  border-bottom:1px solid #ddd;
34
34
  background: #fff url(../images/fieldbg.gif) repeat-x top;
35
+ font-size: 1.1em; line-height: 1.3em;
35
36
  }
36
37
 
37
38
  input.file_upload {
@@ -40,179 +41,235 @@ input.file_upload {
40
41
 
41
42
  .button {
42
43
  padding: 6px 10px;
43
- font: bold 11px "Lucida Grande", Arial, sans-serif;
44
44
  border-top:1px solid #ddd;
45
45
  border-left:1px solid #c3c3c3;
46
46
  border-right:1px solid #c3c3c3;
47
47
  border-bottom:1px solid #8c8c8c;
48
48
  background: #eee;
49
+ font-size: 11px; font-weight: bold;
49
50
  }
50
51
  .button:hover {cursor: pointer;}
51
- .button:active {border-top:1px solid #8c8c8c; border-bottom:1px solid #ddd;}
52
- .actions {font-size: 11px;}
53
-
52
+ .button:active {border-top: 1px solid #8c8c8c; border-bottom: 1px solid #ddd;}
53
+ .actions {height: 100%; overflow:hidden; font-size: 11px;}
54
54
 
55
- #ajax-progress {
56
- background: black url(../images/spinner.gif) no-repeat 10px 8px;
57
- border: 1px solid #444;
58
- padding: 8px 20px 8px 40px;
59
- color: #cfc; font-weight: bold; font-size: 13px; text-shadow: black 2px 2px 2px;
55
+ .flash {
56
+ margin: 0px 40px; padding: 10px 30px; border-width: 2px 0;
57
+ color: white;
60
58
  }
61
- #search-results-panel {
62
- position: absolute; top: 35px; right: 25px; width: 350px; height: 500px; overflow: auto; z-index: 50;
63
- padding: 0 20px 20px; background: #f2f2f2; border: 1px solid #ddd; color: black;
59
+ .flash.notice {border: 1px solid #829862; background: #92ab6e; text-shadow: #728852 1px 1px 0;}
60
+ .flash.error {border: 1px solid #900024; background: #BC1C3D; text-shadow: #900024 1px 1px 0;}
61
+
62
+ /* rails error message */
63
+ .error-messages {
64
+ background: #BC1C3D;
65
+ border: 1px solid #900024;
66
+ padding: 15px 30px;
67
+ color: white;
68
+ margin-bottom: 20px;
69
+ text-shadow: #900024 1px 1px 0;
64
70
  }
65
- #search-results-panel .card.linkable a {
66
- color: black;
71
+ .error-messages h2 {
72
+ color: white; margin-top: 0; padding-bottom: 0; font-size: 16px; text-shadow: #900024 2px 2px 0;
67
73
  }
74
+ .error-messages li {margin-left: 20px; list-style: square;}
68
75
 
69
- .content-header, .content-body, .content-footer {margin: 10px 45px 15px; padding: 0;}
76
+ .field-with-errors input, .field-with-errors textarea, .field-with-errors select {border: 2px solid #BC1C3D;}
70
77
 
71
- .flash {
72
- margin: 20px 40px; padding: 10px 30px;
73
- border-width: 2px 0;
74
- color: white;
78
+ #ajax-progress {
79
+ padding: 8px 20px 8px 40px;
80
+ border: 1px solid #444;
81
+ color: #cfc; background: black url(../images/spinner.gif) no-repeat 10px 8px;
82
+ font-size: 13px; font-weight: bold; text-shadow: black 1px 1px 2px;
75
83
  }
76
- .flash.notice {background: #92ab6e; border: 1px solid #829862; text-shadow: #728852 2px 2px 0;}
77
- .flash.error {background: #BC1C3D; border: 1px solid #900024; text-shadow: #900024 2px 2px 0;}
78
- .article { margin: 20px 0; border-top: 1px dotted #ccc;}
79
84
 
85
+ .article {margin: 20px 0; border-top: 1px dotted #ccc;}
86
+
87
+ .field-list th {width: 120px;}
88
+ .field-list td {width: auto;}
89
+
90
+ .content-header, .content-body, .content-footer {margin: 0 45px 15px; padding: 0;}
80
91
  .content-header, .content-body {padding-bottom: 15px;}
81
92
  .content-footer {padding-bottom: 20px;}
82
93
 
83
-
84
94
  /* aside layout */
85
95
  body.aside-layout {width: 960px;}
86
- .aside-layout .page-content {overflow: hidden; height: 100%;}
96
+ .aside-layout .page-content {height: 100%; overflow: hidden;}
87
97
  .main-content {float: left; width: 670px;}
88
98
  .aside {float: right; width: 220px; padding: 20px 30px; background: #E5E5E5;}
89
99
  .aside-content {
90
- font-size: 11px; color: #444;
100
+ color: #222; font-size: 11px;
91
101
  }
102
+ .aside-content h2 {padding-bottom: 10px; border-bottom: 1px dotted #666;}
103
+ .aside-content h3 {padding-bottom: 5px; border-bottom: 1px dotted #666;}
104
+ .aside-content a {background: none;}
92
105
  /* trick to produce equal height columns */
93
106
  .aside, .main-content {padding-bottom: 10000px; margin-bottom: -10000px;}
94
107
 
95
108
 
96
- /***********/
97
-
98
- .page-header {color: white; background: black; margin-top: 20px; padding: 20px 0 0; position: relative;}
99
- .page-header h1 {margin: 0; padding: 0 30px 30px; font-family: "Arial Black", Tahoma, Arial, sans-serif; font-size: 36px; letter-spacing: -1.5pt;}
100
- .page-header .nav {margin: 0 20px; overflow: hidden; height: 100%;}
101
- .page-header .nav li {float: left; list-style: none; margin-left: 0;}
102
- .page-header a, .page-header a:hover {color: white; border: none; background: none;}
109
+ .page-header {position: relative; margin: 20px 0; padding: 20px 0 0; color: white; background: black;}
110
+ .page-header h1 {
111
+ margin: 0; padding: 0 30px 30px;
112
+ font-family: "Arial Black", Tahoma, Arial, sans-serif; font-size: 36px; letter-spacing: -1.5pt;
113
+ }
114
+ .page-header .nav {height: 100%; overflow: hidden; margin: 0 20px;}
115
+ .page-header .nav li {float: left; margin-left: 0; list-style: none;}
116
+ .page-header a, .page-header a:hover {border: none; color: white; background: none;}
103
117
 
104
118
  .page-header div.search {
105
- position: absolute; top: 10px; right: 5px; padding: 6px 30px 8px 15px;
119
+ position: absolute; top: 10px; right: 5px;
120
+ padding: 6px 30px 8px 15px;
106
121
  }
107
122
  .page-header div.search label {
108
123
  padding-right: 10px;
109
- text-transform: uppercase; font: bold 9px Arial, sans-serif; letter-spacing: 1.0pt;
124
+ font: bold 9px Arial, sans-serif; text-transform: uppercase; letter-spacing: 1.0pt;
110
125
  }
111
126
  .page-header div.search input {
112
127
  font-size: 10px;
113
128
  }
129
+ #search-results-panel {
130
+ position: absolute; top: 35px; right: 25px; z-index: 50;
131
+ width: 350px; height: 500px; overflow: auto;
132
+ padding: 0 20px 20px; border: 1px solid #ddd;
133
+ color: black; background: #f2f2f2;
134
+ }
135
+ #search-results-panel .card.linkable a {color: black;}
114
136
  #search-spinner {position: absolute; top: 6px; right: 7px;}
115
137
 
116
- .account-nav {
117
- position: absolute; top: -20px; right: 35px; font-size: 11px;
118
- }
119
138
 
120
139
  ul.main-nav {float: left; margin: 0 10px;}
121
- .main-nav li {background: black; margin-right: 10px;}
140
+ .main-nav li {margin-right: 10px;}
122
141
  .main-nav a {
142
+ display: block;
143
+ padding: 5px 15px 7px; border: 1px solid #313131; border-width: 1px 1px 0;
123
144
  background: #282828;
124
- display: block; padding: 5px 15px 7px; border: 1px solid #313131; border-width: 1px 1px 0;
125
- font: bold 13px "Lucida Grande", Arial, sans-serif; text-shadow: black 2px 2px 2px;
145
+ font-size: 13px; font-weight: bold; text-shadow: black 1px 1px 2px;
146
+ }
147
+ .main-nav a:hover {border: 1px solid #555; border-width: 1px 1px 0; background: #444;}
148
+
149
+ .account-nav {
150
+ position: absolute; top: -20px; right: 35px;
151
+ font-size: 11px;
126
152
  }
127
- .main-nav a:hover {background: #444; border: 1px solid #555; border-width: 1px 1px 0;}
128
153
  .account-nav li {
129
- padding-left: 20px; float: left; list-style: none; margin-left: 0; color: #ddd; text-shadow: #444 2px 2px 0;}
154
+ float: left;
155
+ margin-left: 0; padding-left: 20px;
156
+ color: #ddd;
157
+ text-shadow: #444 1px 1px 0;
158
+ list-style: none;
159
+ }
130
160
  .account-nav a {font-weight: bold;}
131
161
  .account-nav a:hover {border-bottom: 1px dotted #ddd;}
132
162
 
163
+ .user-account-page .change-password {width: 350px;}
164
+ .user-account-page .change-password th {width: 150px;}
133
165
 
134
166
  /* pagination nav, needs a more specific class on the wrapper */
135
- .content-body .nav {font-size: 11px; margin-bottom: 10px;}
167
+ .content-body .nav {margin-bottom: 10px; font-size: 11px;}
136
168
  .content-body .nav a {margin-right: 5px;}
137
169
 
138
- .field-list th {width: 120px;}
139
- .field-list td {width: auto;}
140
-
141
170
  .login-page, .signup-page {width: 50%; margin-top: 40px;}
142
171
  .login-page .content-header, .signup-page .content-header {padding-bottom: 0;}
143
172
  .login-page .field-list, .signup-page .field-list {width: 300px;}
144
173
  .login-page .field-list td, .signup-page .field-list td {width: auto;}
145
174
  .login-page .field-list th, .signup-page .field-list th {width: 120px;}
146
- .login-page .actions, .signup-page .actions {text-align: left; margin-left: 128px; margin-top: 20px;}
175
+ .login-page .actions, .signup-page .actions {margin-left: 128px; margin-top: 20px; text-align: left;}
147
176
  /*.login-page .submit-button, .signup-page .submit-button {margin: 10px 130px;}*/
148
177
 
149
- .edit-page .delete-button {margin-top: 25px;}
178
+ .edit-page .content-header {overflow: hidden; height: 100%;}
179
+ .edit-page .content-header h1 {float: left;}
180
+ .edit-page .content-header .delete-button {float: right; margin-top: 25px;}
181
+ form .actions {margin: 30px 0; width: 100%; text-align: center;}
150
182
 
151
183
  .show-page .content-header {position: relative; border-bottom: 1px dotted black;}
152
184
  .show-page .content-header h1, .new-in-collection-page .content-header h1 {margin-bottom: 2px; margin-right: 70px;}
153
185
  .show-page .content-header a.edit {position: absolute; top: 0; right: 0;}
154
- .content-header .creation-details, .content-header .dependent-collection-count {font-size: 11px; line-height: 11px;}
186
+ .aside-content .collection {padding-bottom: 10px;}
187
+
188
+ .content-header .creation-details, .content-header .primary-collection-count {font-size: 11px; line-height: 11px;}
155
189
  .content-header .creator {margin-right: 5px;}
156
190
  .content-header .created-at {color: #444;}
157
- .content-header .dependent-collection-count {font-weight: bold; margin-left: 15px;}
191
+ .content-header .primary-collection-count {margin-left: 15px; font-weight: bold;}
158
192
 
159
- .new-in-collection-page .content-header h2 {margin-top: 6px; font: bold 16px "Lucida Grande", Arial, sans-serif;}
193
+ .new-in-collection-page .content-header h2 {margin-top: 6px; font-size: 14px;}
160
194
  .new-in-collection-page .content-header h2, .new-in-collection-page .content-header h2 a {color: #222;}
161
195
 
162
- .show-page .create-new {
163
- padding: 0 30px;
164
- border-top: 1px dotted #ddd; margin-top: 20px; background: #f5f5f5;
196
+ .create-new {
197
+ margin-top: 20px; padding: 0 30px; border-top: 1px dotted #ddd;
198
+ background: #f5f5f5;
165
199
  }
166
- .show-page .create-new form .submit-button {margin: 20px 130px;}
167
- .show-page .create-new h2 {margin: 20px 0; padding: 0; border-bottom: none;}
200
+ .create-new form .submit-button {margin: 20px 130px;}
201
+ .primary-collection .create-new h2 {margin: 20px 0; padding: 0; border-bottom: none;}
168
202
 
169
203
  /* styling of generic elements */
170
204
  .creator {font-weight: bold;}
171
205
  .card {
206
+ clear: both;
207
+ height: 100%; overflow: hidden;
208
+ margin-bottom: 5px; padding:10px 20px; border: 1px solid #e8e8e8;
172
209
  background: #f5f5f5;
173
- border: 1px solid #e8e8e8;
174
- padding:10px 20px;
175
- margin-bottom: 5px;
176
- height: 100%; overflow: hidden; clear: both;
177
210
  }
178
211
  .card a {background: #f5f5f5;}
179
212
  .card .creation-details {
180
- font-size: 11px; color: #333; display: block;
213
+ display: block; color: #333; font-size: 11px;
181
214
  }
182
215
  .card .datetime {color: #666;}
183
216
 
184
217
  .card.content {
218
+ padding: 0; margin: 10px 0 30px; border: none;
219
+ background: none;
185
220
  font-size: 11px;
186
- border: none; background: none; padding: 0; margin: 10px 0 30px;
187
221
  }
188
222
  .card.content .creation-details {
189
- float: left; width: 155px; line-height: 14px;
223
+ float: left; width: 28%;
224
+ line-height: 14px;
190
225
  }
191
226
  .card.content .creation-details .created-at {display: block;}
192
227
  .card.content .content {
193
- float: right; width: 420px;
228
+ float: right; width: 72%;
194
229
  }
195
- ul.collection li {list-style: none; margin-left: 0;}
230
+ ul.collection li {clear: both; margin-left: 0; list-style: none;}
231
+ .empty-collection-message {margin-top: 20px;}
232
+
233
+ .new-link {margin-top: 20px;}
196
234
 
197
- .new-links {margin-top: 20px;}
198
- .new-links ul li {list-style: none; margin-left: 0;}
235
+ .primary-collection ul li {
236
+ margin-left: 0; list-style: none;
237
+ }
238
+ .primary-collection h2 {
239
+ padding: 15px 0; margin-bottom: 20px; border-bottom: 1px dotted black;
240
+ }
199
241
 
200
- .dependent-collection ul li {
201
- list-style: none; margin-left: 0;
242
+ .table-plus .header {height: 100%; overflow: hidden;}
243
+ .table-plus .header a {float: left; margin-right: 20px;}
244
+ .table-plus div.search {float: right;}
245
+ .table-plus div.search span {color: #444;}
246
+ .table-plus div.search input.search {margin: 0 5px;}
247
+ .table-plus div.search .button {padding: 2px 4px;}
248
+
249
+ .table-plus table {width: 100%; margin: 20px 0;}
250
+ .table-plus table th {
251
+ padding: 2px 10px;
252
+ color: white; background: #444;
253
+ font-weight: bold; font-size: 10px;
202
254
  }
203
- .dependent-collection h2 {
204
- padding: 15px 0; margin-bottom: 20px;
205
- border-bottom: 1px dotted black;
255
+ .table-plus table th a {color: white;}
256
+ .table-plus table td {
257
+ padding: 6px 10px; border-bottom: 1px solid #e2e2e2; color: #666;
206
258
  }
259
+ .table-plus table td input.button {padding: 1px; margin-left: 10px; }
260
+ .table-plus table td.controls {width: 100px;}
261
+ .table-plus .even {background: #f8f8f8;}
262
+ .table-plus a {background: none;}
207
263
 
208
264
  /*******************************************************/
209
265
  /* these styles are for the generated front index page */
210
266
  /* you can delete them if you over-ride it */
211
267
 
212
268
  .front-page .welcome-message {
213
- background: #eee; color: #222; border: 1px solid #e8e8e8; padding: 10px 20px 20px;
269
+ padding: 10px 20px 20px; border: 1px solid #e8e8e8;
270
+ color: #222; background: #eee;
214
271
  }
215
272
  .front-page .welcome-message h2 {
216
273
  font-size: 18px; line-height: 27px;
217
274
  }
218
- .front-page .content-body li {list-style: none; margin-left: 0;}
275
+ .front-page .content-body li {margin-left: 0; list-style: none;}