bh 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -1
  3. data/CHANGELOG.md +19 -0
  4. data/README.md +51 -18
  5. data/bh.gemspec +13 -9
  6. data/examples/middleman/.gitignore +18 -0
  7. data/examples/middleman/Gemfile +6 -0
  8. data/examples/middleman/config.rb +1 -0
  9. data/examples/middleman/source/index.html.erb +158 -0
  10. data/examples/padrino/Gemfile +9 -0
  11. data/examples/padrino/app/app.rb +16 -0
  12. data/examples/padrino/app/views/index.html.erb +155 -0
  13. data/examples/padrino/config.ru +5 -0
  14. data/examples/padrino/config/apps.rb +5 -0
  15. data/examples/padrino/config/boot.rb +8 -0
  16. data/examples/rails/.gitignore +12 -0
  17. data/examples/rails/Gemfile +5 -0
  18. data/examples/rails/app/controllers/application_controller.rb +6 -0
  19. data/examples/rails/app/controllers/users_controller.rb +2 -0
  20. data/examples/rails/app/models/user.rb +15 -0
  21. data/examples/rails/app/views/application/index.html.erb +160 -0
  22. data/examples/rails/bin/rails +4 -0
  23. data/examples/rails/config.ru +4 -0
  24. data/examples/rails/config/application.rb +12 -0
  25. data/examples/rails/config/boot.rb +3 -0
  26. data/examples/rails/config/environment.rb +5 -0
  27. data/examples/rails/config/environments/development.rb +7 -0
  28. data/examples/rails/config/routes.rb +4 -0
  29. data/examples/rails/config/secrets.yml +22 -0
  30. data/examples/rails/log/.keep +0 -0
  31. data/gemfiles/Gemfile.rails-3.x +2 -0
  32. data/gemfiles/Gemfile.rails-4.x +2 -0
  33. data/lib/bh.rb +15 -4
  34. data/lib/bh/classes/alert_box.rb +35 -0
  35. data/lib/bh/classes/base.rb +125 -0
  36. data/lib/bh/classes/button.rb +58 -0
  37. data/lib/bh/classes/button_to.rb +33 -0
  38. data/lib/bh/classes/cdn.rb +35 -0
  39. data/lib/bh/classes/dropdown.rb +56 -0
  40. data/lib/bh/classes/icon.rb +34 -0
  41. data/lib/bh/classes/link_to.rb +22 -0
  42. data/lib/bh/classes/modal.rb +68 -0
  43. data/lib/bh/classes/nav.rb +37 -0
  44. data/lib/bh/classes/navbar.rb +78 -0
  45. data/lib/bh/classes/panel.rb +72 -0
  46. data/lib/bh/classes/panel_row.rb +13 -0
  47. data/lib/bh/classes/progress_bar.rb +89 -0
  48. data/lib/bh/classes/stack.rb +19 -0
  49. data/lib/bh/classes/vertical.rb +27 -0
  50. data/lib/bh/core_ext/middleman.rb +24 -0
  51. data/lib/bh/core_ext/padrino.rb +25 -0
  52. data/lib/bh/core_ext/rails/base_helper.rb +21 -0
  53. data/lib/bh/{helpers → core_ext/rails}/form/base_helper.rb +3 -1
  54. data/lib/bh/{helpers → core_ext/rails}/form/check_box_helper.rb +1 -1
  55. data/lib/bh/{helpers → core_ext/rails}/form/field_helper.rb +1 -1
  56. data/lib/bh/{helpers → core_ext/rails}/form/fields_for_helper.rb +1 -1
  57. data/lib/bh/{helpers → core_ext/rails}/form/fieldset_helper.rb +1 -1
  58. data/lib/bh/{helpers → core_ext/rails}/form/file_field_helper.rb +1 -1
  59. data/lib/bh/{helpers → core_ext/rails}/form/legend_helper.rb +1 -1
  60. data/lib/bh/{helpers → core_ext/rails}/form/radio_button_helper.rb +1 -1
  61. data/lib/bh/{helpers → core_ext/rails}/form/select_helper.rb +1 -1
  62. data/lib/bh/{helpers → core_ext/rails}/form/static_control_helper.rb +1 -1
  63. data/lib/bh/{helpers → core_ext/rails}/form/submit_helper.rb +1 -1
  64. data/lib/bh/{form_builders → core_ext/rails}/form_builder.rb +11 -10
  65. data/lib/bh/core_ext/rails/form_for_helper.rb +32 -0
  66. data/lib/bh/core_ext/railtie.rb +27 -0
  67. data/lib/bh/helpers/alert_box_helper.rb +40 -0
  68. data/lib/bh/helpers/button_helper.rb +35 -58
  69. data/lib/bh/helpers/button_to_helper.rb +48 -10
  70. data/lib/bh/helpers/cdn_helper.rb +11 -35
  71. data/lib/bh/helpers/dropdown_helper.rb +29 -62
  72. data/lib/bh/helpers/glyphicon_helper.rb +7 -13
  73. data/lib/bh/helpers/horizontal_helper.rb +35 -0
  74. data/lib/bh/helpers/icon_helper.rb +15 -29
  75. data/lib/bh/helpers/link_to_helper.rb +52 -41
  76. data/lib/bh/helpers/modal_helper.rb +49 -79
  77. data/lib/bh/helpers/nav_helper.rb +25 -40
  78. data/lib/bh/helpers/navbar_helper.rb +36 -170
  79. data/lib/bh/helpers/panel_helper.rb +45 -72
  80. data/lib/bh/helpers/panel_row_helper.rb +20 -38
  81. data/lib/bh/helpers/progress_bar_helper.rb +48 -59
  82. data/lib/bh/helpers/vertical_helper.rb +33 -0
  83. data/lib/bh/version.rb +1 -1
  84. data/lib/bh/views/bh/_alert_dismiss_button.html +4 -0
  85. data/lib/bh/views/bh/_dropdown.html.erb +5 -5
  86. data/lib/bh/views/bh/_dropdown_split.html.erb +5 -5
  87. data/lib/bh/views/bh/_modal.html.erb +5 -8
  88. data/lib/bh/views/bh/_navbar.html.erb +5 -0
  89. data/spec/padrino/button_to_helper.rb +35 -0
  90. data/spec/padrino_spec.rb +28 -0
  91. data/spec/rails/button_to_helper.rb +31 -0
  92. data/spec/{helpers → rails}/form/check_box_helper_spec.rb +3 -3
  93. data/spec/{helpers → rails}/form/field_helper_spec.rb +3 -3
  94. data/spec/{helpers → rails}/form/fields_for_helper_spec.rb +3 -3
  95. data/spec/{helpers → rails}/form/fieldset_helper_spec.rb +3 -3
  96. data/spec/{helpers → rails}/form/file_field_helper_spec.rb +3 -3
  97. data/spec/{helpers → rails}/form/legend_helper_spec.rb +3 -3
  98. data/spec/{helpers → rails}/form/radio_button_helper_spec.rb +3 -3
  99. data/spec/{helpers → rails}/form/select_helper_spec.rb +3 -3
  100. data/spec/{helpers → rails}/form/static_control_helper_spec.rb +3 -3
  101. data/spec/{helpers → rails}/form/submit_helper_spec.rb +3 -3
  102. data/spec/{helpers → rails}/form_for_helper_spec.rb +3 -3
  103. data/spec/rails_helper.rb +25 -0
  104. data/spec/rails_spec.rb +28 -0
  105. data/spec/shared/alert_box_helper.rb +62 -0
  106. data/spec/shared/button_helper.rb +52 -0
  107. data/spec/shared/button_to_helper.rb +42 -0
  108. data/spec/shared/cdn_helper.rb +36 -0
  109. data/spec/shared/dropdown_helper.rb +112 -0
  110. data/spec/shared/glyphicon_helper.rb +21 -0
  111. data/spec/shared/horizontal_helper.rb +37 -0
  112. data/spec/shared/icon_helper.rb +31 -0
  113. data/spec/shared/link_to_helper.rb +62 -0
  114. data/spec/shared/modal_helper.rb +104 -0
  115. data/spec/shared/nav_helper.rb +49 -0
  116. data/spec/shared/navbar_helper.rb +63 -0
  117. data/spec/shared/panel_helper.rb +76 -0
  118. data/spec/shared/panel_row_helper.rb +21 -0
  119. data/spec/shared/progress_bar_helper.rb +103 -0
  120. data/spec/shared/vertical_helper.rb +43 -0
  121. data/spec/spec_helper.rb +6 -29
  122. data/spec/support/matchers.rb +38 -0
  123. data/spec/support/padrino.rb +33 -0
  124. data/spec/support/rails.rb +27 -0
  125. metadata +183 -94
  126. data/config.rb +0 -6
  127. data/lib/bh/helpers/alert_helper.rb +0 -77
  128. data/lib/bh/helpers/base_helper.rb +0 -39
  129. data/lib/bh/helpers/form_for_helper.rb +0 -30
  130. data/lib/bh/middleman.rb +0 -39
  131. data/lib/bh/railtie.rb +0 -42
  132. data/spec/dummy/index.html.erb +0 -60
  133. data/spec/dummy/layouts/default.erb +0 -17
  134. data/spec/helpers/alert_helper_spec.rb +0 -84
  135. data/spec/helpers/button_helper_spec.rb +0 -100
  136. data/spec/helpers/button_to_helper_spec.rb +0 -25
  137. data/spec/helpers/cdn_helper_spec.rb +0 -100
  138. data/spec/helpers/dropdown_helper_spec.rb +0 -146
  139. data/spec/helpers/glyphicon_helper_spec.rb +0 -21
  140. data/spec/helpers/icon_helper_spec.rb +0 -45
  141. data/spec/helpers/link_to_helper_spec.rb +0 -124
  142. data/spec/helpers/modal_helper_spec.rb +0 -133
  143. data/spec/helpers/nav_helper_spec.rb +0 -53
  144. data/spec/helpers/navbar_helper_spec.rb +0 -194
  145. data/spec/helpers/panel_helper_spec.rb +0 -95
  146. data/spec/helpers/panel_row_helper_spec.rb +0 -27
  147. data/spec/helpers/progress_bar_helper_spec.rb +0 -114
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env rackup
2
+ # encoding: utf-8
3
+
4
+ require File.expand_path("../config/boot.rb", __FILE__)
5
+ run Padrino.application
@@ -0,0 +1,5 @@
1
+ Padrino.configure_apps do
2
+ set :session_secret, '95d177cde28c10318dce7c955cc7a047a410a9a9bed0cf2c4b6032803a223d43'
3
+ end
4
+
5
+ Padrino.mount('TestBh::App', app_file: Padrino.root('app/app.rb')).to('/')
@@ -0,0 +1,8 @@
1
+ RACK_ENV = ENV['RACK_ENV'] ||= 'development' unless defined?(RACK_ENV)
2
+ PADRINO_ROOT = File.expand_path('../..', __FILE__) unless defined?(PADRINO_ROOT)
3
+
4
+ require 'rubygems' unless defined?(Gem)
5
+ require 'bundler/setup'
6
+ Bundler.require(:default, RACK_ENV)
7
+
8
+ Padrino.load!
@@ -0,0 +1,12 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+
10
+ # Ignore all logfiles and tempfiles.
11
+ /log/*.log
12
+ /tmp
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '~> 4.2.0.beta3'
4
+
5
+ gem 'bh', path: '../../../bh'
@@ -0,0 +1,6 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery with: :exception
3
+
4
+ def index
5
+ end
6
+ end
@@ -0,0 +1,2 @@
1
+ class UsersController < ApplicationController
2
+ end
@@ -0,0 +1,15 @@
1
+ class User
2
+ include ActiveModel::Validations
3
+ include ActiveModel::Conversion
4
+ extend ActiveModel::Naming
5
+
6
+ attr_accessor :email, :password, :remember_me, :phone, :subscribe, :avatar
7
+
8
+ def persisted?
9
+ true
10
+ end
11
+
12
+ def id
13
+ 2
14
+ end
15
+ end
@@ -0,0 +1,160 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta content="IE=edge" http-equiv="X-UA-Compatible" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <%= stylesheet_link_tag font_awesome_css, bootstrap_css, bootstrap_theme_css %>
8
+ <title>Bh test page (Rails)</title>
9
+ </head>
10
+ <body>
11
+ <div class='container'>
12
+
13
+ <h1>Alerts</h1>
14
+
15
+ <!-- Try setting different :dismissible and :context options -->
16
+ <%= alert_box 'You accepted the Terms of service.' %>
17
+
18
+ <%= alert_box context: :warning, dismissible: true, id: 'alert', class: :en, data: {js: 1} do %>
19
+ <em>Thanks!</em> You accepted the <%= link_to 'Terms of service', '/#terms' %>.
20
+ <% end %>
21
+
22
+ <h1>Panels</h1>
23
+
24
+ <!-- Try setting different :title, :tag and :context options -->
25
+ <%= panel 'You accepted the Terms of service', title: 'Thanks', tag: :aside %>
26
+
27
+ <%= panel heading: 'Thanks', context: :info, id: 'panel', class: :en, data: {js: 1} do %>
28
+ <div class='panel-body'>You accepted the Terms of service. <%= icon :ok %></div>
29
+ <% end %>
30
+
31
+ <h1>Panel rows</h1>
32
+
33
+ <!-- Try setting a different :column_class option -->
34
+ <%= panel_row column_class: 'col-sm-12' do %>
35
+ <%= panel 'Plain full-width panel' %>
36
+ <% end %>
37
+
38
+ <%= panel_row column_class: 'col-sm-6', id: 'panel-row', class: :en, data: {js: 1} do %>
39
+ <%= panel 'John Smith', title: 'User', context: :info %>
40
+ <%= panel title: 'Phone' do %>
41
+ <div class='panel-body'><%= icon :earphone %> 323-555-5555</div>
42
+ <% end %>
43
+ <% end %>
44
+
45
+ <h1>Modals</h1>
46
+
47
+ <!-- Try setting different :title, :size, :button or :context options -->
48
+ <%= modal 'Do what you want!', button: {size: :small, context: :info} %>
49
+
50
+ <%= modal title: 'Terms of service', size: :large, id: 'modal', button: {class: :en} do %>
51
+ <div class="modal-body">Please accept the Terms of service.</div>
52
+ <div class="modal-footer"><button type="button" class="btn btn-primary">Accept</button></div>
53
+ <% end %>
54
+
55
+ <h1>Navs</h1>
56
+
57
+ <!-- Try setting different :layout or :as options -->
58
+ <%= nav do %>
59
+ <%= link_to 'Home', '/' %>
60
+ <%= link_to 'Users', '/#users' %>
61
+ <%= link_to 'Profile', '/#profile' %>
62
+ <% end %>
63
+
64
+ <br />
65
+
66
+ <%= nav as: :pills, id: 'nav', class: :en, data: {js: 1} do %>
67
+ <li class="active"><a href="/">Home</a></li>
68
+ <%= link_to 'Users', '/#users' %>
69
+ <%= link_to 'Profile', '/#profile' %>
70
+ <% end %>
71
+
72
+ <h1>Navbars</h1>
73
+
74
+ <!-- Try adding a horizontal element and setting different :inverted, :fluid, :position or :padding options -->
75
+ <%= navbar inverted: true do %>
76
+ <%= vertical do %>
77
+ <%= link_to 'Home', '/' %>
78
+ <% end %>
79
+ <% end %>
80
+
81
+ <%= navbar id: 'navbar' do %>
82
+ <%= vertical id: 'vertical', class: :en, data: {js: 1} do %>
83
+ <%= link_to 'Home', '/' %>
84
+ <% end %>
85
+ <%= horizontal class: :en, data: {js: 2} do %>
86
+ <%= nav class: 'navbar-left' do %>
87
+ <%= link_to 'Profile', '/#profile' %>
88
+ <%= link_to 'Settings', '/#settings' %>
89
+ <% end %>
90
+ <% end %>
91
+ <% end %>
92
+
93
+ <h1>Buttons</h1>
94
+
95
+ <!-- Try setting different :context, :size and :layout options -->
96
+ <%= button 'Menu' %>
97
+
98
+ <%= button context: :warning, id: 'button', class: :en, data: {js: 1} do %>
99
+ Your <em>personal</em> menu
100
+ <% end %>
101
+
102
+ <h1>Dropdowns</h1>
103
+
104
+ <!-- Try setting different :split, :direction, :align, :groupable, :layout, :context or :size options -->
105
+ <%= dropdown 'Menu', direction: :up, context: :success, align: :right do %>
106
+ <%= link_to 'Home', '/' %>
107
+ <%= link_to 'Profile', '/#profile' %>
108
+ <%= link_to 'Settings', '/#settings' %>
109
+ <% end %>
110
+
111
+ <%= dropdown 'Menu', split: true, id: 'dropdown', button: {class: :en} do %>
112
+ <li role="presentation"><a href="#">Home</a></li>
113
+ <li role="presentation"><a href="#"><%= content_tag :em, 'Profile' %></a></li>
114
+ <% end %>
115
+
116
+ <h1>Progress bars</h1>
117
+
118
+ <!-- Try passing multiple values with different :percentage, :label, :context, :striped, :animated options -->
119
+ <%= progress_bar [{percentage: 75, striped: true}, {percentage: 20, context: :warning, label: true}] %>
120
+
121
+ <%= progress_bar({percentage: 30, id: 'bar', data: {js: 1}}, id: 'container', class: :en) %>
122
+
123
+ <h1>Icons</h1>
124
+
125
+ <!-- Try setting a different :library option -->
126
+ <%= icon :user %>
127
+
128
+ <%= icon :user, library: :font_awesome, class: 'fa-2x', id: 'icon', data: {value: 1} %>
129
+
130
+ <h1>Button to</h1>
131
+
132
+ <%= button_to 'New', '#new', class: 'b', form_class: 'f', method: :get %>
133
+ <br />
134
+ <%= button_to 'New', '#new', class: 'b', form_class: 'f', method: :get, context: :primary %>
135
+
136
+ <%= button_to '/#edit', method: :get, context: :link, id: 'my-btn-to', data: {value: 1} do %>
137
+ Button <strong>styled</strong> as a link
138
+ <% end %>
139
+
140
+ <h1>Forms</h1>
141
+
142
+ <%= form_for User.new, url: '/', method: :get, layout: :basic do |f| %>
143
+ <%= f.legend 'User detail' %>
144
+ <%= f.email_field :email, label: 'E-mail address' %>
145
+ <%= f.password_field :password, placeholder: 'Your Password' %>
146
+ <%= f.file_field :avatar %>
147
+ <%= f.fieldset 'Newsletter' do %>
148
+ <%= f.radio_button :subscribe, true, label: 'Subscribe to newsletter' %>
149
+ <%= f.radio_button :subscribe, false, label: 'Do not subscribe to newsletter' %>
150
+ <% end %>
151
+ <%= f.telephone_field :phone, suffix: '☏' %>
152
+ <%= f.check_box :remember_me, checked: true %>
153
+ <%= f.submit 'Sign in' %>
154
+ <% end %>
155
+
156
+ </div>
157
+ <%= javascript_include_tag '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js' %>
158
+ <%= javascript_include_tag bootstrap_js %>
159
+ </body>
160
+ </html>
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
3
+ require_relative '../config/boot'
4
+ require 'rails/commands'
@@ -0,0 +1,4 @@
1
+ # This file is used by Rack-based servers to start the application.
2
+
3
+ require ::File.expand_path('../config/environment', __FILE__)
4
+ run Rails.application
@@ -0,0 +1,12 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require "active_model/railtie"
4
+ require "action_controller/railtie"
5
+ require "action_view/railtie"
6
+
7
+ require 'bh'
8
+
9
+ module TestRails
10
+ class Application < Rails::Application
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
2
+
3
+ require 'bundler/setup' # Set up gems listed in the Gemfile.
@@ -0,0 +1,5 @@
1
+ # Load the Rails application.
2
+ require File.expand_path('../application', __FILE__)
3
+
4
+ # Initialize the Rails application.
5
+ Rails.application.initialize!
@@ -0,0 +1,7 @@
1
+ Rails.application.configure do
2
+ config.cache_classes = false
3
+ config.eager_load = false
4
+ config.consider_all_requests_local = true
5
+ config.action_controller.perform_caching = false
6
+ config.active_support.deprecation = :log
7
+ end
@@ -0,0 +1,4 @@
1
+ Rails.application.routes.draw do
2
+ resources :users
3
+ root 'application#index'
4
+ end
@@ -0,0 +1,22 @@
1
+ # Be sure to restart your server when you modify this file.
2
+
3
+ # Your secret key is used for verifying the integrity of signed cookies.
4
+ # If you change this key, all old signed cookies will become invalid!
5
+
6
+ # Make sure the secret is at least 30 characters and all random,
7
+ # no regular words or you'll be exposed to dictionary attacks.
8
+ # You can use `rake secret` to generate a secure secret key.
9
+
10
+ # Make sure the secrets in this file are kept private
11
+ # if you're sharing your code publicly.
12
+
13
+ development:
14
+ secret_key_base: 4d85d117bf624cdf5a8a3baedcba52fdfb6b1e3fa92e39c4170f8ac25824a3a59a68f14b17227181acd5141255cf2ac1a63bd22662e187c0f1653a1b8e399e2c
15
+
16
+ test:
17
+ secret_key_base: b182bca1180765aeec063200f2666b1a4c854f0d93d5840764a7bb19c06ba9ba4003c57624f24fac936dd6828796687c667ca9e3dbb33e85737a771fcaa819f9
18
+
19
+ # Do not keep production secrets in the repository,
20
+ # instead read values from the environment.
21
+ production:
22
+ secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
File without changes
@@ -3,4 +3,6 @@ source 'http://rubygems.org'
3
3
  gem 'activesupport', '~> 3.0'
4
4
  gem 'actionpack', '~> 3.0'
5
5
  gem 'activemodel', '~> 3.0'
6
+ gem 'middleman-core', '~> 3.2.2'
7
+
6
8
  gemspec path: '../'
@@ -3,4 +3,6 @@ source 'http://rubygems.org'
3
3
  gem 'activesupport', '~> 4.0'
4
4
  gem 'actionpack', '~> 4.0'
5
5
  gem 'activemodel', '~> 4.0'
6
+ gem 'middleman-core', '~> 3.3.0'
7
+
6
8
  gemspec path: '../'
data/lib/bh.rb CHANGED
@@ -1,6 +1,17 @@
1
- require 'bh/railtie' if defined?(Rails)
2
- require 'bh/middleman' if defined?(Middleman)
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
3
 
4
- # Adds Bootstrap styles to Rails helpers
4
+ # Bootstrap Helpers
5
5
  module Bh
6
- end
6
+ mattr_accessor :framework
7
+ end
8
+
9
+ # Always require every generic helper
10
+ helpers_folder = File.expand_path '../bh/helpers/*_helper.rb', __FILE__
11
+ Dir[helpers_folder].each{|file| require file}
12
+
13
+ # Conditionally require platform-specific helpers
14
+ extension = :railtie if defined?(Rails)
15
+ extension ||= :middleman if defined?(Middleman)
16
+ extension ||= :padrino if defined?(Padrino)
17
+ require "bh/core_ext/#{extension}" if extension
@@ -0,0 +1,35 @@
1
+ require 'bh/classes/base'
2
+
3
+ module Bh
4
+ module Classes
5
+ class AlertBox < Base
6
+ # @return [#to_s] the content-related class to assign to the alert box.
7
+ def context_class
8
+ AlertBox.contexts[@options.fetch :context, @options[:priority]]
9
+ end
10
+
11
+ # @return [#to_s] the HTML to show a dismissible button for the alert box.
12
+ def dismissible_button
13
+ if @options[:dismissible] || @options[:priority]
14
+ path = '../../views/bh/_alert_dismiss_button.html'
15
+ File.read File.expand_path(path, __FILE__)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ # @return [Hash<Symbol, String>] the class that Bootstrap requires to
22
+ # append to an alert box based on its context.
23
+ def self.contexts
24
+ HashWithIndifferentAccess.new(:'alert-info').tap do |klass|
25
+ klass[:alert] = :'alert-danger'
26
+ klass[:danger] = :'alert-danger'
27
+ klass[:info] = :'alert-info'
28
+ klass[:notice] = :'alert-success'
29
+ klass[:success] = :'alert-success'
30
+ klass[:warning] = :'alert-warning'
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,125 @@
1
+ require 'bh/classes/stack'
2
+ require 'ostruct'
3
+ require 'active_support'
4
+ require 'active_support/core_ext'
5
+
6
+ module Bh
7
+ # @api private
8
+ module Classes
9
+ class Base
10
+ def initialize(app = nil, *args, &block)
11
+ @app = app
12
+ @concat = block_given? && @app.respond_to?(:concat_content)
13
+ @options = extract_options_from(*args, &block).dup
14
+ @content = extract_content_from *args, &block
15
+ end
16
+
17
+ def extract!(*keys)
18
+ @attributes = @options.slice! *keys
19
+ @options.any?
20
+ end
21
+
22
+ def merge!(attributes = {})
23
+ html_attributes.deep_merge! attributes
24
+ end
25
+
26
+ def append_class!(new_class, hash = html_attributes, attribute = :class)
27
+ existing_class = hash[attribute]
28
+ hash[attribute] = [existing_class, new_class].compact.join ' '
29
+ end
30
+
31
+ def append_class_to!(key, new_class)
32
+ append_class! new_class, (html_attributes[key] ||= {})
33
+ end
34
+
35
+ def prepend_html!(html)
36
+ @content = safe_join [html, @content]
37
+ end
38
+
39
+ def render_tag(tag)
40
+ render content_tag(tag)
41
+ end
42
+
43
+ def render_partial(partial)
44
+ file = File.expand_path "../../views/bh/_#{partial}.html.erb", __FILE__
45
+ template = ERB.new(File.read file)
46
+ assigns = OpenStruct.new attributes.merge(content: @content)
47
+ render template.result(assigns.instance_eval{ binding &nil }).html_safe
48
+ end
49
+
50
+ def tag
51
+ :div
52
+ end
53
+
54
+ def attributes
55
+ @attributes || @options
56
+ end
57
+
58
+ def content
59
+ items = Array.wrap(@content).map do |item|
60
+ item.is_a?(Base) ? item.content_tag(item.tag) : item
61
+ end
62
+ safe_join items
63
+ end
64
+
65
+ def content_tag(tag)
66
+ @app.content_tag tag, content, attributes
67
+ end
68
+
69
+ def url
70
+ @url
71
+ end
72
+
73
+ def extract_from(option, attributes = [])
74
+ if @options[option]
75
+ @attributes[option] = @options[option].except *attributes
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def safe_join(array = [])
82
+ array.compact.join("\n").html_safe
83
+ end
84
+
85
+ def stack(&block)
86
+ Stack.unshift self
87
+ yield.tap{ Stack.shift }
88
+ end
89
+
90
+ def html_attributes
91
+ @html_attributes || attributes
92
+ end
93
+
94
+ def render(html)
95
+ @concat && html ? @app.concat_content(html) : html
96
+ end
97
+
98
+ def extract_options_from(*args, &block)
99
+ args.shift unless block_given?
100
+ args.extract_options!
101
+ end
102
+
103
+ def extract_content_from(*args, &block)
104
+ if block_given?
105
+ stack { capture_content &block }
106
+ else
107
+ args.shift
108
+ end
109
+ end
110
+
111
+ def extract_url_from(*args)
112
+ args.delete_at(block_given? ? 0 : 1)
113
+ end
114
+
115
+ def capture_content(&block)
116
+ content = @app.capture &block
117
+ if content.is_a? String
118
+ ActiveSupport::SafeBuffer.new.safe_concat(content)
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ include Classes
125
+ end