aaf-lipstick 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ module Lipstick
2
+ module Helpers
3
+ module NavHelper
4
+ include ActionView::Helpers::TagHelper
5
+ include ActionView::Helpers::TextHelper
6
+
7
+ def nav_bar(&block)
8
+ content_tag('nav') do
9
+ css_class = 'ui borderless inverted menu collapsing nav parent'
10
+ content_tag('div', class: css_class) do
11
+ concat(nav_collapse_button)
12
+ concat(capture(&block))
13
+ end
14
+ end
15
+ end
16
+
17
+ def nav_collapsing_items(&block)
18
+ content_tag('span', class: 'collapsing nav content', &block)
19
+ end
20
+
21
+ def nav_item(text, url, html_opts = {})
22
+ html_opts[:class] = "#{html_opts[:class]} item".strip
23
+ content_tag('a', text, html_opts.merge(href: url))
24
+ end
25
+
26
+ def nav_items_right(&block)
27
+ content_tag('div', class: 'right menu', &block)
28
+ end
29
+
30
+ def nav_dropdown(title, &block)
31
+ content_tag('div', class: 'ui simple dropdown item') do
32
+ concat(content_tag('i', '', class: 'dropdown icon'))
33
+ concat(title)
34
+ concat(content_tag('div', class: 'menu', &block))
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def nav_collapse_button
41
+ content_tag('div', class: 'collapsing nav button') do
42
+ content_tag('a', href: '#',
43
+ class: 'ui icon mini black open button') do
44
+ content_tag('i', '', class: 'list layout icon')
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,2 @@
1
+ class SemanticFormBuilder < ActionView::Helpers::FormBuilder
2
+ end
@@ -0,0 +1,7 @@
1
+ module Lipstick
2
+ module Images
3
+ end
4
+ end
5
+
6
+ require 'lipstick/images/email_banner'
7
+ require 'lipstick/images/processor'
@@ -0,0 +1,154 @@
1
+ require 'rmagick'
2
+
3
+ module Lipstick
4
+ module Images
5
+ # Creates an AAF standard email banner, with three elements, positioned as
6
+ # follows:
7
+ #
8
+ # 1. AAF Logo. Vertically centered and left-aligned within the content box,
9
+ # and with a blank space to the right.
10
+ # 2. Application title. Vertically centered, and left-aligned to the logo's
11
+ # right margin.
12
+ # 3. Environment string. Positioned 10 pixels below the app title, and
13
+ # left-aligned to the logo's right margin.
14
+ #
15
+ # The "box" containing these three elements is horizontally centered in the
16
+ # resulting image.
17
+ #
18
+ # Text metrics work as follows, using "Alimony" as the example word:
19
+ #
20
+ # * (x, y) is the position of the bottom left tip of 'A'
21
+ # * `ascent` is the letter height from that point (i.e. the height of 'A')
22
+ # * `descent` is a negative value; the letter height *below* that point
23
+ # (i.e. the height of the 'tail' of 'y')
24
+ # * `height` is greater than `(ascent - descent)`, making it useless for our
25
+ # purposes here.
26
+ #
27
+ # For image compositing, (x, y) is the position of the top-left corner.
28
+ class EmailBanner
29
+ def initialize(image:, title:, environment:)
30
+ @title = title
31
+ @environment = environment
32
+ @image = image
33
+ end
34
+
35
+ def to_png
36
+ canvas = Magick::ImageList.new
37
+ canvas.new_image(WIDTH, HEIGHT) do |f|
38
+ f.format = 'PNG'
39
+ f.background_color = '#495666'
40
+ end
41
+
42
+ annotate_title(canvas)
43
+ annotate_environment(canvas)
44
+
45
+ canvas.composite!(logo, logo_x, logo_y, Magick::SrcOverCompositeOp)
46
+
47
+ canvas.to_blob
48
+ end
49
+
50
+ private
51
+
52
+ WIDTH = 600
53
+ HEIGHT = 150
54
+ MID_Y = HEIGHT / 2
55
+ private_constant :WIDTH, :HEIGHT, :MID_Y
56
+
57
+ def title_format
58
+ @title_format ||= Magick::Draw.new do |title|
59
+ title.font_family = 'Helvetica'
60
+ title.pointsize = 24
61
+ title.gravity = Magick::ForgetGravity
62
+ title.fill = 'white'
63
+ end
64
+ end
65
+
66
+ def environment_format
67
+ @environment_format ||= Magick::Draw.new do |title|
68
+ title.font_family = 'Helvetica'
69
+ title.pointsize = 20
70
+ title.gravity = Magick::ForgetGravity
71
+ title.fill = '#dd7727'
72
+ end
73
+ end
74
+
75
+ def annotate_title(canvas)
76
+ title_format.annotate(canvas, 0, 0, title_x, title_y, @title)
77
+ end
78
+
79
+ def annotate_environment(canvas)
80
+ environment_format.annotate(canvas, 0, 0, env_x, env_y, @environment)
81
+ end
82
+
83
+ def logo
84
+ asset = Rails.application.assets.find_asset(@image)
85
+ @logo ||= Magick::Image.read(asset.pathname.to_s).first
86
+ .resize_to_fill(150, 80)
87
+ end
88
+
89
+ def gap
90
+ @gap ||= environment_format.get_type_metrics('AAF').width
91
+ end
92
+
93
+ def logo_w
94
+ logo.bounding_box.width
95
+ end
96
+
97
+ def logo_x
98
+ margin_x
99
+ end
100
+
101
+ # y position to vertically center logo
102
+ def logo_y
103
+ ((HEIGHT - logo.bounding_box.height) / 2).round
104
+ end
105
+
106
+ def title_metrics
107
+ title_format.get_type_metrics(@title)
108
+ end
109
+
110
+ def env_metrics
111
+ environment_format.get_type_metrics(@environment)
112
+ end
113
+
114
+ # Halve the total margin to horizontally center the whole content area.
115
+ def margin_x
116
+ # | whitespace | logo | whitespace | text | whitespace |
117
+ # |<---------->|
118
+ ((WIDTH - total_w) / 2).round
119
+ end
120
+
121
+ def title_x
122
+ # | whitespace | logo | whitespace | text | whitespace |
123
+ # ^ this position
124
+ margin_x + logo_w + gap
125
+ end
126
+
127
+ # y position to vertically center title
128
+ def title_y
129
+ MID_Y + (title_metrics.ascent / 2).round
130
+ end
131
+
132
+ def env_x
133
+ title_x
134
+ end
135
+
136
+ # `ascent` is a positive value, and `descent` is a negative value. They
137
+ # describe the full height of the letters. See RMagick documentation.
138
+ def env_y
139
+ MID_Y + title_metrics.ascent - title_metrics.descent + 10
140
+ end
141
+
142
+ # Center using the largest width for aesthetics.
143
+ def text_w
144
+ [title_metrics.width, env_metrics.width].max
145
+ end
146
+
147
+ def total_w
148
+ # | whitespace | logo | whitespace | text | whitespace |
149
+ # |<------------------------>|
150
+ logo_w + gap + text_w
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,27 @@
1
+ require 'sprockets/processor'
2
+
3
+ module Lipstick
4
+ module Images
5
+ class Processor < Sprockets::Processor
6
+ class DSL
7
+ def initialize(context)
8
+ @context = context
9
+ end
10
+
11
+ def run(data)
12
+ binding.eval(data)
13
+ end
14
+
15
+ def email_banner(image: 'logo.png', title:, environment:)
16
+ @context.depend_on_asset(image)
17
+ EmailBanner.new(image: image, title: title, environment: environment)
18
+ .to_png
19
+ end
20
+ end
21
+
22
+ def evaluate(context, _locals)
23
+ DSL.new(context).run(data)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ module Lipstick
2
+ VERSION = '1.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,275 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aaf-lipstick
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Shaun Mangelsdorf
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: actionview
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: kramdown
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rmagick
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: sprockets
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.12'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: faker
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: tilt
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec-rails
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: capybara
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: simplecov
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: guard
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: guard-rspec
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: guard-rubocop
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: guard-bundler
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
223
+ description:
224
+ email:
225
+ - s.mangelsdorf@gmail.com
226
+ executables: []
227
+ extensions: []
228
+ extra_rdoc_files: []
229
+ files:
230
+ - Rakefile
231
+ - app/assets/images/favicon.png
232
+ - app/assets/images/logo.png
233
+ - app/assets/javascripts/aaf-layout.js
234
+ - app/assets/stylesheets/aaf-layout.css.scss
235
+ - app/views/layouts/email_branding.html.erb
236
+ - lib/aaf-lipstick.rb
237
+ - lib/lipstick.rb
238
+ - lib/lipstick/action_view_tilt_template.rb
239
+ - lib/lipstick/auto_validation.rb
240
+ - lib/lipstick/email_message.rb
241
+ - lib/lipstick/engine.rb
242
+ - lib/lipstick/helpers.rb
243
+ - lib/lipstick/helpers/form_helper.rb
244
+ - lib/lipstick/helpers/layout_helper.rb
245
+ - lib/lipstick/helpers/nav_helper.rb
246
+ - lib/lipstick/helpers/semantic_form_builder.rb
247
+ - lib/lipstick/images.rb
248
+ - lib/lipstick/images/email_banner.rb
249
+ - lib/lipstick/images/processor.rb
250
+ - lib/lipstick/version.rb
251
+ homepage: https://github.com/ausaccessfed/aaf-lipstick
252
+ licenses:
253
+ - Apache-2.0
254
+ metadata: {}
255
+ post_install_message:
256
+ rdoc_options: []
257
+ require_paths:
258
+ - lib
259
+ required_ruby_version: !ruby/object:Gem::Requirement
260
+ requirements:
261
+ - - ">="
262
+ - !ruby/object:Gem::Version
263
+ version: '0'
264
+ required_rubygems_version: !ruby/object:Gem::Requirement
265
+ requirements:
266
+ - - ">="
267
+ - !ruby/object:Gem::Version
268
+ version: '0'
269
+ requirements: []
270
+ rubyforge_project:
271
+ rubygems_version: 2.2.2
272
+ signing_key:
273
+ specification_version: 4
274
+ summary: A gem for applying AAF branding to our services
275
+ test_files: []