turbo-rails 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yml +24 -0
  3. data/.gitignore +2 -0
  4. data/Gemfile +6 -0
  5. data/Gemfile.lock +147 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +66 -0
  8. data/Rakefile +11 -0
  9. data/app/assets/javascripts/turbo.js +3161 -0
  10. data/app/channels/turbo/streams/broadcasts.rb +66 -0
  11. data/app/channels/turbo/streams/stream_name.rb +24 -0
  12. data/app/channels/turbo/streams_channel.rb +17 -0
  13. data/app/controllers/turbo/frames/frame_request.rb +24 -0
  14. data/app/controllers/turbo/native/navigation.rb +49 -0
  15. data/app/controllers/turbo/native/navigation_controller.rb +13 -0
  16. data/app/controllers/turbo/streams/turbo_streams_tag_builder.rb +22 -0
  17. data/app/helpers/turbo/drive_helper.rb +16 -0
  18. data/app/helpers/turbo/frames_helper.rb +23 -0
  19. data/app/helpers/turbo/includes_helper.rb +5 -0
  20. data/app/helpers/turbo/streams/action_helper.rb +25 -0
  21. data/app/helpers/turbo/streams_helper.rb +22 -0
  22. data/app/javascript/turbo/cable.js +16 -0
  23. data/app/javascript/turbo/cable_stream_source_element.js +27 -0
  24. data/app/javascript/turbo/index.js +3 -0
  25. data/app/jobs/turbo/streams/action_broadcast_job.rb +6 -0
  26. data/app/jobs/turbo/streams/broadcast_job.rb +7 -0
  27. data/app/models/concerns/turbo/broadcastable.rb +236 -0
  28. data/app/models/turbo/streams/tag_builder.rb +127 -0
  29. data/config/routes.rb +6 -0
  30. data/lib/install/turbo.rb +11 -0
  31. data/lib/tasks/turbo_tasks.rake +6 -0
  32. data/lib/turbo-rails.rb +17 -0
  33. data/lib/turbo/engine.rb +65 -0
  34. data/lib/turbo/test_assertions.rb +22 -0
  35. data/lib/turbo/version.rb +3 -0
  36. data/package.json +42 -0
  37. data/rollup.config.js +23 -0
  38. data/test/drive/drive_helper_test.rb +8 -0
  39. data/test/dummy/.babelrc +18 -0
  40. data/test/dummy/.gitignore +3 -0
  41. data/test/dummy/.postcssrc.yml +3 -0
  42. data/test/dummy/Rakefile +6 -0
  43. data/test/dummy/app/assets/config/manifest.js +2 -0
  44. data/test/dummy/app/assets/images/.keep +0 -0
  45. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  46. data/test/dummy/app/assets/stylesheets/scaffold.css +80 -0
  47. data/test/dummy/app/channels/application_cable/channel.rb +4 -0
  48. data/test/dummy/app/channels/application_cable/connection.rb +4 -0
  49. data/test/dummy/app/controllers/application_controller.rb +2 -0
  50. data/test/dummy/app/controllers/concerns/.keep +0 -0
  51. data/test/dummy/app/controllers/messages_controller.rb +12 -0
  52. data/test/dummy/app/controllers/trays_controller.rb +17 -0
  53. data/test/dummy/app/helpers/application_helper.rb +2 -0
  54. data/test/dummy/app/javascript/packs/application.js +0 -0
  55. data/test/dummy/app/jobs/application_job.rb +2 -0
  56. data/test/dummy/app/mailboxes/application_mailbox.rb +2 -0
  57. data/test/dummy/app/mailboxes/messages_mailbox.rb +4 -0
  58. data/test/dummy/app/mailers/application_mailer.rb +4 -0
  59. data/test/dummy/app/models/application_record.rb +3 -0
  60. data/test/dummy/app/models/concerns/.keep +0 -0
  61. data/test/dummy/app/models/message.rb +29 -0
  62. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  63. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  64. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  65. data/test/dummy/app/views/messages/_message.html.erb +1 -0
  66. data/test/dummy/app/views/messages/_message.turbo_stream.erb +1 -0
  67. data/test/dummy/app/views/messages/show.turbo_stream.erb +9 -0
  68. data/test/dummy/app/views/trays/index.html.erb +3 -0
  69. data/test/dummy/app/views/trays/show.html.erb +3 -0
  70. data/test/dummy/bin/bundle +3 -0
  71. data/test/dummy/bin/rails +4 -0
  72. data/test/dummy/bin/rake +4 -0
  73. data/test/dummy/bin/setup +36 -0
  74. data/test/dummy/bin/update +31 -0
  75. data/test/dummy/bin/yarn +11 -0
  76. data/test/dummy/config.ru +5 -0
  77. data/test/dummy/config/application.rb +22 -0
  78. data/test/dummy/config/boot.rb +5 -0
  79. data/test/dummy/config/cable.yml +10 -0
  80. data/test/dummy/config/environment.rb +5 -0
  81. data/test/dummy/config/environments/development.rb +34 -0
  82. data/test/dummy/config/environments/production.rb +96 -0
  83. data/test/dummy/config/environments/test.rb +38 -0
  84. data/test/dummy/config/initializers/application_controller_renderer.rb +8 -0
  85. data/test/dummy/config/initializers/assets.rb +14 -0
  86. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  87. data/test/dummy/config/initializers/content_security_policy.rb +22 -0
  88. data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
  89. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  90. data/test/dummy/config/initializers/inflections.rb +16 -0
  91. data/test/dummy/config/initializers/mime_types.rb +4 -0
  92. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  93. data/test/dummy/config/locales/en.yml +33 -0
  94. data/test/dummy/config/puma.rb +34 -0
  95. data/test/dummy/config/routes.rb +4 -0
  96. data/test/dummy/config/spring.rb +6 -0
  97. data/test/dummy/config/webpack/development.js +3 -0
  98. data/test/dummy/config/webpack/environment.js +3 -0
  99. data/test/dummy/config/webpack/production.js +3 -0
  100. data/test/dummy/config/webpack/test.js +3 -0
  101. data/test/dummy/config/webpacker.yml +65 -0
  102. data/test/dummy/lib/assets/.keep +0 -0
  103. data/test/dummy/log/.keep +0 -0
  104. data/test/dummy/public/404.html +67 -0
  105. data/test/dummy/public/422.html +67 -0
  106. data/test/dummy/public/500.html +66 -0
  107. data/test/dummy/public/apple-touch-icon-precomposed.png +0 -0
  108. data/test/dummy/public/apple-touch-icon.png +0 -0
  109. data/test/dummy/public/favicon.ico +0 -0
  110. data/test/frames/frame_request_controller_test.rb +21 -0
  111. data/test/frames/frames_helper_test.rb +15 -0
  112. data/test/native/navigation_controller_test.rb +42 -0
  113. data/test/streams/broadcastable_test.rb +80 -0
  114. data/test/streams/streams_channel_test.rb +105 -0
  115. data/test/streams/streams_controller_test.rb +29 -0
  116. data/test/turbo_test.rb +10 -0
  117. data/turbo-rails.gemspec +16 -0
  118. data/yarn.lock +282 -0
  119. metadata +254 -0
@@ -0,0 +1,127 @@
1
+ # This tag builder is used both for inline controller turbo actions (see <tt>Turbo::Streams::TurboStreamsTagBuilder</tt>) and for
2
+ # turbo stream templates. This object plays together with any normal Ruby you'd run in an ERB template, so you can iterate, like:
3
+ #
4
+ # <% # app/views/postings/destroy.turbo_stream.erb %>
5
+ # <% @postings.each do |posting| %>
6
+ # <%= turbo_stream.remove posting %>
7
+ # <% end %>
8
+ #
9
+ # Or string several separate updates together:
10
+ #
11
+ # <% # app/views/entries/_entry.turbo_stream.erb %>
12
+ # <%= turbo_stream.remove entry %>
13
+ #
14
+ # <%= turbo_stream.append "entries" do %>
15
+ # <% # format ensures that the _entry.html.erb partial is rendered, not _entry.turbo_stream.erb %>
16
+ # <%= render partial: "entries/entry", locals: { entry: entry }, formats: [ :html ] %>
17
+ # <%= end %>
18
+ #
19
+ # Or you can render the HTML that should be part of the update inline:
20
+ #
21
+ # <% # app/views/topics/merges/_merge.turbo_stream.erb %>
22
+ # <%= turbo_stream.append dom_id(topic_merge) do %>
23
+ # <%= link_to topic_merge.topic.name, topic_path(topic_merge.topic) %>
24
+ # <% end %>
25
+ class Turbo::Streams::TagBuilder
26
+ include Turbo::Streams::ActionHelper
27
+
28
+ def initialize(view_context)
29
+ @view_context = view_context
30
+ end
31
+
32
+ # Removes the <tt>target</tt> from the dom. The target can either be a dom id string or an object that responds to
33
+ # <tt>to_key</tt>, which is then called and passed through <tt>ActionView::RecordIdentifier.dom_id</tt> (all Active Records
34
+ # do). Examples:
35
+ #
36
+ # <%= turbo_stream.remove "clearance_5" %>
37
+ # <%= turbo_stream.remove clearance %>
38
+ def remove(target)
39
+ action :remove, target, allow_inferred_rendering: false
40
+ end
41
+
42
+ # Replace the <tt>target</tt> in the dom with the either the <tt>content</tt> passed in, a rendering result determined
43
+ # by the <tt>rendering</tt> keyword arguments, the content in the block, or the rendering of the target as a record. Examples:
44
+ #
45
+ # <%= turbo_stream.replace "clearance_5", "<div id='clearance_5'>Replace the dom target identified by clearance_5</div>" %>
46
+ # <%= turbo_stream.replace clearance %>
47
+ # <%= turbo_stream.replace clearance, partial: "clearances/clearance", locals: { title: "Hello" } %>
48
+ # <%= turbo_stream.replace "clearance_5" do %>
49
+ # <div id='clearance_5'>Replace the dom target identified by clearance_5</div>
50
+ # <% end %>
51
+ def replace(target, content = nil, **rendering, &block)
52
+ action :replace, target, content, **rendering, &block
53
+ end
54
+
55
+ # Update the <tt>target</tt> in the dom with the either the <tt>content</tt> passed in or a rendering result determined
56
+ # by the <tt>rendering</tt> keyword arguments, the content in the block, or the rendering of the target as a record. Examples:
57
+ #
58
+ # <%= turbo_stream.update "clearance_5", "Update the content of the dom target identified by clearance_5" %>
59
+ # <%= turbo_stream.update clearance %>
60
+ # <%= turbo_stream.update clearance, partial: "clearances/unique_clearance", locals: { title: "Hello" } %>
61
+ # <%= turbo_stream.update "clearance_5" do %>
62
+ # Update the content of the dom target identified by clearance_5
63
+ # <% end %>
64
+ def update(target, content = nil, **rendering, &block)
65
+ action :update, target, content, **rendering, &block
66
+ end
67
+
68
+ # Append to the target in the dom identified with <tt>target</tt> either the <tt>content</tt> passed in or a
69
+ # rendering result determined by the <tt>rendering</tt> keyword arguments, the content in the block,
70
+ # or the rendering of the content as a record. Examples:
71
+ #
72
+ # <%= turbo_stream.append "clearances", "<div id='clearance_5'>Append this to .clearances</div>" %>
73
+ # <%= turbo_stream.append "clearances", clearance %>
74
+ # <%= turbo_stream.append "clearances", partial: "clearances/unique_clearance", locals: { clearance: clearance } %>
75
+ # <%= turbo_stream.append "clearances" do %>
76
+ # <div id='clearance_5'>Append this to .clearances</div>
77
+ # <% end %>
78
+ def append(target, content = nil, **rendering, &block)
79
+ action :append, target, content, **rendering, &block
80
+ end
81
+
82
+ # Prepend to the target in the dom identified with <tt>target</tt> either the <tt>content</tt> passed in or a
83
+ # rendering result determined by the <tt>rendering</tt> keyword arguments or the content in the block,
84
+ # or the rendering of the content as a record. Examples:
85
+ #
86
+ # <%= turbo_stream.prepend "clearances", "<div id='clearance_5'>Prepend this to .clearances</div>" %>
87
+ # <%= turbo_stream.prepend "clearances", clearance %>
88
+ # <%= turbo_stream.prepend "clearances", partial: "clearances/unique_clearance", locals: { clearance: clearance } %>
89
+ # <%= turbo_stream.prepend "clearances" do %>
90
+ # <div id='clearance_5'>Prepend this to .clearances</div>
91
+ # <% end %>
92
+ def prepend(target, content = nil, **rendering, &block)
93
+ action :prepend, target, content, **rendering, &block
94
+ end
95
+
96
+ # Send an action of the type <tt>name</tt>. Options described in the concrete methods.
97
+ def action(name, target, content = nil, allow_inferred_rendering: true, **rendering, &block)
98
+ target_name = extract_target_name_from(target)
99
+
100
+ case
101
+ when content
102
+ turbo_stream_action_tag name, target: target_name, template: (render_record(content) if allow_inferred_rendering) || content
103
+ when block_given?
104
+ turbo_stream_action_tag name, target: target_name, template: @view_context.capture(&block)
105
+ when rendering.any?
106
+ turbo_stream_action_tag name, target: target_name, template: @view_context.render(formats: [ :html ], **rendering)
107
+ else
108
+ turbo_stream_action_tag name, target: target_name, template: (render_record(target) if allow_inferred_rendering)
109
+ end
110
+ end
111
+
112
+ private
113
+ def extract_target_name_from(target)
114
+ if target.respond_to?(:to_key)
115
+ ActionView::RecordIdentifier.dom_id(target)
116
+ else
117
+ target
118
+ end
119
+ end
120
+
121
+ def render_record(possible_record)
122
+ if possible_record.respond_to?(:to_partial_path)
123
+ record = possible_record
124
+ @view_context.render(partial: record.to_partial_path, locals: { record.model_name.singular.to_sym => record }, formats: [ :html ])
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,6 @@
1
+ # FIXME: Offer flag to opt out of these native routes
2
+ Rails.application.routes.draw do
3
+ get "recede_historical_location" => "turbo/native/navigation#recede", as: :turbo_recede_historical_location
4
+ get "resume_historical_location" => "turbo/native/navigation#resume", as: :turbo_resume_historical_location
5
+ get "refresh_historical_location" => "turbo/native/navigation#refresh", as: :turbo_refresh_historical_location
6
+ end
@@ -0,0 +1,11 @@
1
+ say "Yield head in application layout for cache helper"
2
+ insert_into_file Rails.root.join("app/views/layouts/application.html.erb").to_s, "\n <%= yield :head %>", before: /\s*<\/head>/
3
+
4
+ say "Add Turbo include tags in application layout"
5
+ insert_into_file Rails.root.join("app/views/layouts/application.html.erb").to_s, "\n <%= turbo_include_tags %>", before: /\s*<\/head>/
6
+
7
+ say "Enable redis in bundle"
8
+ uncomment_lines "Gemfile", %(gem 'redis')
9
+
10
+ say "Switch development cable to use redis"
11
+ gsub_file "config/cable.yml", /development:\n\s+adapter: async/, "development:\n adapter: redis\n url: redis://localhost:6379/1"
@@ -0,0 +1,6 @@
1
+ namespace :turbo do
2
+ desc "Install Turbo into the app"
3
+ task :install do
4
+ system "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{File.expand_path("../install/turbo.rb", __dir__)}"
5
+ end
6
+ end
@@ -0,0 +1,17 @@
1
+ require "turbo/engine"
2
+
3
+ module Turbo
4
+ extend ActiveSupport::Autoload
5
+
6
+ class << self
7
+ attr_writer :signed_stream_verifier_key
8
+
9
+ def signed_stream_verifier
10
+ @signed_stream_verifier ||= ActiveSupport::MessageVerifier.new(signed_stream_verifier_key, digest: "SHA256", serializer: JSON)
11
+ end
12
+
13
+ def signed_stream_verifier_key
14
+ @signed_stream_verifier_key or raise ArgumentError, "Turbo requires a signed_stream_verifier_key"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,65 @@
1
+ require "rails/engine"
2
+ require "turbo/test_assertions"
3
+
4
+ module Turbo
5
+ class Engine < Rails::Engine
6
+ isolate_namespace Turbo
7
+ config.eager_load_namespaces << Turbo
8
+ config.turbo = ActiveSupport::OrderedOptions.new
9
+
10
+ initializer "turbo.assets" do
11
+ Rails.application.config.assets.precompile += %w( turbo )
12
+ end
13
+
14
+ initializer "turbo.helpers" do
15
+ ActiveSupport.on_load(:action_controller_base) do
16
+ include Turbo::Streams::TurboStreamsTagBuilder, Turbo::Frames::FrameRequest, Turbo::Native::Navigation
17
+ helper Turbo::Engine.helpers
18
+ end
19
+ end
20
+
21
+ initializer "turbo.broadcastable" do
22
+ ActiveSupport.on_load(:active_record) do
23
+ include Turbo::Broadcastable
24
+ end
25
+ end
26
+
27
+ initializer "turbo.mimetype" do
28
+ Mime::Type.register "text/html; turbo-stream", :turbo_stream
29
+ end
30
+
31
+ initializer "turbo.renderer" do
32
+ ActiveSupport.on_load(:action_controller) do
33
+ ActionController::Renderers.add :turbo_stream do |turbo_streams_html, options|
34
+ self.content_type = Mime[:turbo_stream] if media_type.nil?
35
+ turbo_streams_html
36
+ end
37
+ end
38
+ end
39
+
40
+ initializer "turbo.signed_stream_verifier_key" do
41
+ Turbo.signed_stream_verifier_key = config.turbo.signed_stream_verifier_key ||
42
+ Rails.application.key_generator.generate_key("turbo/signed_stream_verifier_key")
43
+ end
44
+
45
+ initializer "turbo.test_assertions" do
46
+ ActiveSupport.on_load(:active_support_test_case) do
47
+ include Turbo::TestAssertions
48
+ end
49
+ end
50
+
51
+ initializer "turbo.integration_test_request_encoding" do
52
+ ActiveSupport.on_load(:action_dispatch_integration_test) do
53
+ # Support `as: :turbo_stream`. Public `register_encoder` API is a little too strict.
54
+ class ActionDispatch::RequestEncoder
55
+ class TurboStreamEncoder < IdentityEncoder
56
+ header = [ Mime[:turbo_stream], Mime[:html] ].join(",")
57
+ define_method(:accept_header) { header }
58
+ end
59
+
60
+ @encoders[:turbo_stream] = TurboStreamEncoder.new
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,22 @@
1
+ module Turbo
2
+ module TestAssertions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # FIXME: Should happen in Rails at a different level
7
+ delegate :dom_id, :dom_class, to: ActionView::RecordIdentifier
8
+ end
9
+
10
+ def assert_turbo_stream(action:, target: nil, &block)
11
+ assert_response :ok
12
+ assert_equal Mime[:turbo_stream], response.media_type
13
+ assert_select %(turbo-stream[action="#{action}"][target="#{target.respond_to?(:to_key) ? dom_id(target) : target}"]), count: 1, &block
14
+ end
15
+
16
+ def assert_no_turbo_stream(action:, target: nil)
17
+ assert_response :ok
18
+ assert_equal Mime[:turbo_stream], response.media_type
19
+ assert_select %(turbo-stream[action="#{action}"][target="#{target.respond_to?(:to_key) ? dom_id(target) : target}"]), count: 0
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Turbo
2
+ VERSION = "0.5.0"
3
+ end
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@hotwired/turbo-rails",
3
+ "version": "7.0.0-beta.1",
4
+ "description": "The speed of a single-page web application without having to write any JavaScript",
5
+ "module": "app/javascript/turbo/index.js",
6
+ "main": "app/assets/javascripts/turbo.js",
7
+ "files": [
8
+ "app/javascript/turbo"
9
+ ],
10
+ "scripts": {
11
+ "build": "rollup -c"
12
+ },
13
+ "dependencies": {
14
+ "@hotwired/turbo": "^7.0.0-beta.1",
15
+ "@rails/actioncable": "^6.1.0"
16
+ },
17
+ "devDependencies": {
18
+ "@rollup/plugin-node-resolve": "^11.0.1",
19
+ "rollup": "^2.35.1",
20
+ "rollup-plugin-terser": "^7.0.2"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Basecamp, LLC",
24
+ "contributors": [
25
+ "David Heinemeier Hansson <david@basecamp.com>",
26
+ "Javan Makhmali <javan@javan.us>",
27
+ "Sam Stephenson <sstephenson@gmail.com>"
28
+ ],
29
+ "keywords": [
30
+ "hotwire",
31
+ "turbo",
32
+ "rails"
33
+ ],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/hotwired/turbo-rails.git"
37
+ },
38
+ "bugs": {
39
+ "url": "https://github.com/hotwired/turbo-rails/issues"
40
+ },
41
+ "homepage": "https://github.com/hotwired/turbo-rails"
42
+ }
@@ -0,0 +1,23 @@
1
+ import resolve from "@rollup/plugin-node-resolve"
2
+ import { terser } from "rollup-plugin-terser"
3
+ import pkg from "./package.json"
4
+
5
+ export default {
6
+ input: pkg.module,
7
+ output: {
8
+ file: pkg.main,
9
+ format: "es",
10
+ inlineDynamicImports: true
11
+ },
12
+ plugins: [
13
+ resolve(),
14
+ terser({
15
+ mangle: false,
16
+ compress: false,
17
+ format: {
18
+ beautify: true,
19
+ indent_level: 2
20
+ }
21
+ })
22
+ ]
23
+ }
@@ -0,0 +1,8 @@
1
+ require "turbo_test"
2
+
3
+ class Turbo::DriveHelperTest < ActionDispatch::IntegrationTest
4
+ test "opting out of the default cache" do
5
+ get trays_path
6
+ assert_select "meta", name: "turbo-cache-control", content: "no-cache"
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ {
2
+ "presets": [
3
+ ["env", {
4
+ "modules": false,
5
+ "targets": {
6
+ "browsers": "> 1%",
7
+ "uglify": true
8
+ },
9
+ "useBuiltIns": true
10
+ }]
11
+ ],
12
+
13
+ "plugins": [
14
+ "syntax-dynamic-import",
15
+ "transform-object-rest-spread",
16
+ ["transform-class-properties", { "spec": true }]
17
+ ]
18
+ }
@@ -0,0 +1,3 @@
1
+ *.log
2
+ *.sqlite3
3
+ tmp/*
@@ -0,0 +1,3 @@
1
+ plugins:
2
+ postcss-import: {}
3
+ postcss-cssnext: {}
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,2 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../stylesheets .css
File without changes
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,80 @@
1
+ body {
2
+ background-color: #fff;
3
+ color: #333;
4
+ margin: 33px;
5
+ }
6
+
7
+ body, p, ol, ul, td {
8
+ font-family: verdana, arial, helvetica, sans-serif;
9
+ font-size: 13px;
10
+ line-height: 18px;
11
+ }
12
+
13
+ pre {
14
+ background-color: #eee;
15
+ padding: 10px;
16
+ font-size: 11px;
17
+ }
18
+
19
+ a {
20
+ color: #000;
21
+ }
22
+
23
+ a:visited {
24
+ color: #666;
25
+ }
26
+
27
+ a:hover {
28
+ color: #fff;
29
+ background-color: #000;
30
+ }
31
+
32
+ th {
33
+ padding-bottom: 5px;
34
+ }
35
+
36
+ td {
37
+ padding: 0 5px 7px;
38
+ }
39
+
40
+ div.field,
41
+ div.actions {
42
+ margin-bottom: 10px;
43
+ }
44
+
45
+ #notice {
46
+ color: green;
47
+ }
48
+
49
+ .field_with_errors {
50
+ padding: 2px;
51
+ background-color: red;
52
+ display: table;
53
+ }
54
+
55
+ #error_explanation {
56
+ width: 450px;
57
+ border: 2px solid red;
58
+ padding: 7px 7px 0;
59
+ margin-bottom: 20px;
60
+ background-color: #f0f0f0;
61
+ }
62
+
63
+ #error_explanation h2 {
64
+ text-align: left;
65
+ font-weight: bold;
66
+ padding: 5px 5px 5px 15px;
67
+ font-size: 12px;
68
+ margin: -7px -7px 0;
69
+ background-color: #c00;
70
+ color: #fff;
71
+ }
72
+
73
+ #error_explanation ul li {
74
+ font-size: 12px;
75
+ list-style: square;
76
+ }
77
+
78
+ label {
79
+ display: block;
80
+ }