govuk_publishing_components 21.56.1 → 21.59.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +6 -1
  3. data/app/assets/javascripts/govuk_publishing_components/components/details.js +6 -4
  4. data/app/assets/javascripts/govuk_publishing_components/components/print-link.js +14 -0
  5. data/app/assets/stylesheets/govuk_publishing_components/_all_components.scss +1 -0
  6. data/app/assets/stylesheets/govuk_publishing_components/components/_action-link.scss +11 -5
  7. data/app/assets/stylesheets/govuk_publishing_components/components/_cookie-banner.scss +4 -0
  8. data/app/assets/stylesheets/govuk_publishing_components/components/_input.scss +9 -5
  9. data/app/assets/stylesheets/govuk_publishing_components/components/_list.scss +1 -0
  10. data/app/assets/stylesheets/govuk_publishing_components/components/_print-link.scss +52 -0
  11. data/app/assets/stylesheets/govuk_publishing_components/components/_search.scss +7 -2
  12. data/app/assets/stylesheets/govuk_publishing_components/components/print/_govspeak.scss +5 -1
  13. data/app/controllers/govuk_publishing_components/audit_controller.rb +52 -0
  14. data/app/controllers/govuk_publishing_components/component_guide_controller.rb +1 -0
  15. data/app/models/govuk_publishing_components/audit_applications.rb +99 -0
  16. data/app/models/govuk_publishing_components/audit_comparer.rb +172 -0
  17. data/app/models/govuk_publishing_components/audit_components.rb +139 -0
  18. data/app/views/govuk_publishing_components/audit/show.html.erb +221 -0
  19. data/app/views/govuk_publishing_components/component_guide/index.html.erb +7 -4
  20. data/app/views/govuk_publishing_components/components/_action_link.html.erb +2 -0
  21. data/app/views/govuk_publishing_components/components/_cookie_banner.html.erb +3 -1
  22. data/app/views/govuk_publishing_components/components/_input.html.erb +3 -4
  23. data/app/views/govuk_publishing_components/components/_list.html.erb +26 -0
  24. data/app/views/govuk_publishing_components/components/_print_link.html.erb +27 -0
  25. data/app/views/govuk_publishing_components/components/docs/action_link.yml +5 -0
  26. data/app/views/govuk_publishing_components/components/docs/input.yml +9 -1
  27. data/app/views/govuk_publishing_components/components/docs/list.yml +64 -0
  28. data/app/views/govuk_publishing_components/components/docs/print_link.yml +24 -0
  29. data/config/locales/en.yml +2 -0
  30. data/config/routes.rb +1 -0
  31. data/lib/govuk_publishing_components/version.rb +1 -1
  32. metadata +28 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3ae35a18ee87f9f8bdbc0b7f05b1874d04f3bcfbebed8eb0fd21dfb178bf1118
4
- data.tar.gz: e83b74f0187e3db2687dea59f3dc1f482b3400a7fe24f95d1ba5cb9b1377a94e
3
+ metadata.gz: 1d31d1f48a5d3491e568c0412fdbbcfaf2e1a98a71aaf84ff703556e83a19b6b
4
+ data.tar.gz: 45ecc8d0b068dd621f3a5a4fb2b4add39f542cfe14ba22f5a2e9828ae9638438
5
5
  SHA512:
6
- metadata.gz: 485ae5bca952be5d4bd237148436f7c165cf91aadafdc433cf1dec9a899cbcff4f78c9e9ede0509ffc79511902fcdeeff699ed73e918f2cbcbf08182e8d8da42
7
- data.tar.gz: fde1485cf2b9b1849993aa71fee949f39c3f4d08c996c1d9a61de520f3c44d0c25d3fd047d176032fd0c4e7c4862a0b4fe00b926b43e5898424c3e459355ada3
6
+ metadata.gz: 89fd3c928d07a3cda0079255ea980e7731bda3eb1b9033eeba53131f85f05c12a9073334b17a04b86c050ddd5329fcef28be3ced3373137b6c4385cefb1070aa
7
+ data.tar.gz: 82d9e99c1d65f4441404f8a76c18ccc11a3357250ac579bdd6844e8f0b57c63d41dfca449cb848b3f86e37576c7e5dcd6eb3e373860c5d1814882ac52a6d3052
data/Rakefile CHANGED
@@ -29,4 +29,9 @@ namespace :assets do
29
29
  end
30
30
  end
31
31
 
32
- task default: [:spec, "app:jasmine:ci"]
32
+ desc "Run RuboCop linting"
33
+ task lint: :environment do
34
+ sh "bundle exec rubocop --format clang"
35
+ end
36
+
37
+ task default: [:lint, :spec, "app:jasmine:ci"]
@@ -20,9 +20,11 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
20
20
  var detailsClick = detailsComponent.querySelector('[data-details-track-click]')
21
21
  var that = this
22
22
 
23
- $(detailsClick).click(function (e) {
24
- that.trackDefault(detailsComponent)
25
- })
23
+ if (detailsClick) {
24
+ detailsClick.addEventListener('click', function (event) {
25
+ that.trackDefault(detailsComponent)
26
+ })
27
+ }
26
28
  }
27
29
  }
28
30
 
@@ -37,7 +39,7 @@ window.GOVUK.Modules = window.GOVUK.Modules || {};
37
39
  trackOptions = {}
38
40
  }
39
41
 
40
- trackOptions['label'] = componentStatus
42
+ trackOptions.label = componentStatus
41
43
 
42
44
  if (trackAction && trackCategory) {
43
45
  window.GOVUK.analytics.trackEvent(trackCategory, trackAction, trackOptions)
@@ -0,0 +1,14 @@
1
+ window.GOVUK = window.GOVUK || {}
2
+ window.GOVUK.Modules = window.GOVUK.Modules || {};
3
+
4
+ (function (Modules) {
5
+ 'use strict'
6
+
7
+ Modules.PrintLink = function () {
8
+ this.start = function (element) {
9
+ element[0].addEventListener('click', function () {
10
+ window.print()
11
+ })
12
+ }
13
+ }
14
+ })(window.GOVUK.Modules)
@@ -53,6 +53,7 @@
53
53
  @import "components/panel";
54
54
  @import "components/phase-banner";
55
55
  @import "components/previous-and-next-navigation";
56
+ @import "components/print-link";
56
57
  @import "components/radio";
57
58
  @import "components/related-navigation";
58
59
  @import "components/search";
@@ -118,6 +118,16 @@
118
118
  }
119
119
 
120
120
  .gem-c-action-link--dark-icon {
121
+ &:before {
122
+ // sass-lint:disable no-duplicate-properties
123
+ background: image-url("govuk_publishing_components/action-link-arrow--dark.png");
124
+ background: image-url("govuk_publishing_components/action-link-arrow--dark.svg"), linear-gradient(transparent, transparent);
125
+ // sass-lint:enable no-duplicate-properties
126
+ }
127
+ }
128
+
129
+ .gem-c-action-link--dark-icon,
130
+ .gem-c-action-link--small-icon {
121
131
  max-width: none;
122
132
 
123
133
  @include govuk-media-query($until: tablet) {
@@ -125,12 +135,8 @@
125
135
  }
126
136
 
127
137
  &:before {
128
- width: 30px;
129
138
  height: 30px;
130
- // sass-lint:disable no-duplicate-properties
131
- background: image-url("govuk_publishing_components/action-link-arrow--dark.png");
132
- background: image-url("govuk_publishing_components/action-link-arrow--dark.svg"), linear-gradient(transparent, transparent);
133
- // sass-lint:enable no-duplicate-properties
139
+ width: 35px;
134
140
  background-repeat: no-repeat;
135
141
  background-size: 25px auto;
136
142
  background-position: 0 2px;
@@ -12,6 +12,10 @@ $govuk-cookie-banner-background: govuk-colour("light-grey", "grey-4");
12
12
  background-color: $govuk-cookie-banner-background;
13
13
  }
14
14
 
15
+ .gem-c-cookie-banner--services {
16
+ display: none;
17
+ }
18
+
15
19
  .gem-c-cookie-banner__message {
16
20
  display: inline-block;
17
21
  padding-bottom: govuk-spacing(2);
@@ -10,6 +10,7 @@
10
10
  // TODO: remove these styles once static is made less aggressive
11
11
  .gem-c-input.govuk-input {
12
12
  margin: 0;
13
+ min-width: 0;
13
14
  padding: govuk-spacing(1);
14
15
 
15
16
  &.gem-c-input--search-icon {
@@ -40,16 +41,19 @@
40
41
  box-sizing: border-box;
41
42
  cursor: default; // emphasise non-editable status of prefixes and suffixes
42
43
  display: inline-block;
43
- white-space: nowrap;
44
- width: auto;
45
- text-align: center;
44
+ flex: 0 0 auto;
46
45
  height: 40px;
47
- padding: govuk-spacing(1);
46
+ margin-top: 0;
48
47
  min-width: 40px;
48
+ padding: govuk-spacing(1);
49
+ text-align: center;
50
+ white-space: nowrap;
51
+ width: auto;
52
+
49
53
  @if $govuk-typography-use-rem {
54
+ height: govuk-px-to-rem(40px);
50
55
  min-width: govuk-px-to-rem(40px);
51
56
  }
52
- margin-top: 0;
53
57
  }
54
58
 
55
59
  .gem-c-input__prefix {
@@ -0,0 +1 @@
1
+ @import "govuk/components/list/list";
@@ -0,0 +1,52 @@
1
+ .gem-c-print-link {
2
+ display: none;
3
+ margin-bottom: 2em;
4
+ margin-top: 2em;
5
+ }
6
+
7
+ .gem-c-print-link.gem-c-print-link--show-without-js {
8
+ display: block;
9
+ }
10
+
11
+ .js-enabled {
12
+ .gem-c-print-link {
13
+ display: block;
14
+ }
15
+ }
16
+
17
+ .gem-c-print-link__link {
18
+ background: image-url("govuk_publishing_components/icon-print.png") no-repeat 10px 50%;
19
+
20
+ margin-left: -10px;
21
+ padding: .5em .5em .5em 38px;
22
+
23
+ @include govuk-device-pixel-ratio($ratio: 2) {
24
+ background-image: image-url("govuk_publishing_components/icon-print-2x.png");
25
+ background-size: 16px 18px;
26
+ }
27
+
28
+ &:focus {
29
+ @include govuk-focused-text;
30
+ }
31
+ }
32
+
33
+ .gem-c-print-link__button {
34
+ @extend %govuk-body-s;
35
+ background: image-url("govuk_publishing_components/icon-print.png") no-repeat 10px 50%;
36
+ border: 0;
37
+ color: $govuk-link-colour;
38
+ cursor: pointer;
39
+ margin: 0;
40
+ margin-left: -10px;
41
+ padding: .5em .5em .5em 38px;
42
+ text-decoration: underline;
43
+
44
+ @include govuk-device-pixel-ratio($ratio: 2) {
45
+ background-image: image-url("govuk_publishing_components/icon-print-2x.png");
46
+ background-size: 16px 18px;
47
+ }
48
+
49
+ &:focus {
50
+ @include govuk-focused-text;
51
+ }
52
+ }
@@ -9,6 +9,7 @@ $large-input-size: 50px;
9
9
  .gem-c-search__label {
10
10
  @include govuk-font($size: 19, $line-height: $input-size);
11
11
  display: block;
12
+ background: govuk-colour("white");
12
13
 
13
14
  h1 {
14
15
  @include govuk-font($size: 19, $line-height: $input-size);
@@ -17,8 +18,10 @@ $large-input-size: 50px;
17
18
 
18
19
  .js-enabled & {
19
20
  position: absolute;
20
- left: govuk-spacing(3);
21
- top: 1px;
21
+ left: 2px;
22
+ top: 2px;
23
+ bottom: 2px;
24
+ padding-left: govuk-spacing(3);
22
25
  z-index: 1;
23
26
  color: $govuk-secondary-text-colour;
24
27
  }
@@ -201,6 +204,8 @@ $large-input-size: 50px;
201
204
  .gem-c-search--separate-label {
202
205
  .gem-c-search__label {
203
206
  position: relative;
207
+ top: auto;
204
208
  left: auto;
209
+ padding-left: 0;
205
210
  }
206
211
  }
@@ -7,8 +7,12 @@
7
7
  .help-notice,
8
8
  .call-to-action {
9
9
  margin: govuk-spacing(3) 0;
10
- padding: 0 govuk-spacing(3);
10
+ }
11
+
12
+ .call-to-action {
13
+ background: none;
11
14
  border: 1pt solid $govuk-border-colour;
15
+ padding: govuk-spacing(3);
12
16
  }
13
17
 
14
18
  .help-notice p {
@@ -0,0 +1,52 @@
1
+ module GovukPublishingComponents
2
+ class AuditController < GovukPublishingComponents::ApplicationController
3
+ def show
4
+ path = Dir.pwd
5
+
6
+ components = AuditComponents.new(path)
7
+ applications = analyse_applications(File.expand_path("..", path))
8
+ compared_data = AuditComparer.new(components.data, applications)
9
+
10
+ @applications = compared_data.data
11
+ @components = compared_data.gem_data
12
+ end
13
+
14
+ private
15
+
16
+ def analyse_applications(path)
17
+ results = []
18
+ applications = %w[
19
+ calculators
20
+ collections
21
+ collections-publisher
22
+ content-data-admin
23
+ content-publisher
24
+ email-alert-frontend
25
+ feedback
26
+ finder-frontend
27
+ frontend
28
+ government-frontend
29
+ govspeak-preview
30
+ info-frontend
31
+ licence-finder
32
+ manuals-frontend
33
+ release
34
+ search-admin
35
+ service-manual-frontend
36
+ signon
37
+ smart-answers
38
+ static
39
+ travel-advice-publisher
40
+ whitehall
41
+ ].sort
42
+
43
+ applications.each do |application|
44
+ application_path = [path, application].join("/")
45
+ app = AuditApplications.new(application_path, application)
46
+ results << app.data
47
+ end
48
+
49
+ results
50
+ end
51
+ end
52
+ end
@@ -85,6 +85,7 @@ module GovukPublishingComponents
85
85
 
86
86
  files = Dir["#{@application_path}/app/views/**/*.html.erb"]
87
87
  files.concat Dir["#{@application_path}/app/**/*.rb"]
88
+ files.concat Dir["#{@application_path}/lib/**/*.rb"]
88
89
 
89
90
  files.each do |file|
90
91
  data = File.read(file)
@@ -0,0 +1,99 @@
1
+ module GovukPublishingComponents
2
+ class AuditApplications
3
+ attr_reader :data
4
+
5
+ def initialize(path, name)
6
+ templates = Dir["#{path}/app/views/**/*.html.erb"]
7
+ stylesheets = Dir["#{path}/app/assets/stylesheets/**/*.scss"]
8
+ javascripts = Dir["#{path}/app/assets/javascripts/**/*.js"]
9
+
10
+ find_templates = /(?<=govuk_publishing_components\/components\/)[\/a-zA-Z_-]+(?=['"])/
11
+
12
+ @find_all_stylesheets = /@import ["']{1}govuk_publishing_components\/all_components/
13
+ find_stylesheets = /(?<=@import ["']{1}govuk_publishing_components\/components\/)(?!print)+[a-zA-Z_-]+(?=['"])/
14
+
15
+ @find_all_print_stylesheets = /@import ["']{1}govuk_publishing_components\/all_components_print/
16
+ find_print_stylesheets = /(?<=@import ["']{1}govuk_publishing_components\/components\/print\/)[a-zA-Z_-]+(?=['"])/
17
+
18
+ @find_all_javascripts = /\/\/[ ]*= require govuk_publishing_components\/all_components/
19
+ find_javascripts = /(?<=require govuk_publishing_components\/components\/)[a-zA-Z_-]+/
20
+
21
+ components_in_templates = find_components(templates, find_templates, "templates") || []
22
+ components_in_stylesheets = find_components(stylesheets, find_stylesheets, "stylesheets") || []
23
+ components_in_print_stylesheets = find_components(stylesheets, find_print_stylesheets, "print_stylesheets") || []
24
+ components_in_javascripts = find_components(javascripts, find_javascripts, "javascripts") || []
25
+
26
+ find_ruby = /(?<=render\(["']{1}govuk_publishing_components\/components\/)[a-zA-Z_-]+/
27
+ ruby_paths = %w[/app/helpers/ /app/presenters/ /lib/]
28
+
29
+ components_in_ruby = []
30
+ ruby_paths.each do |ruby_path|
31
+ components_in_ruby << find_components(Dir["#{path}#{ruby_path}**/*.rb"], find_ruby, "ruby") || []
32
+ end
33
+
34
+ components_in_ruby = components_in_ruby.flatten.uniq
35
+
36
+ @data = {
37
+ name: name,
38
+ application_found: application_exists(path),
39
+ components_found: [
40
+ {
41
+ location: "templates",
42
+ components: components_in_templates,
43
+ },
44
+ {
45
+ location: "stylesheets",
46
+ components: components_in_stylesheets,
47
+ },
48
+ {
49
+ location: "print_stylesheets",
50
+ components: components_in_print_stylesheets,
51
+ },
52
+ {
53
+ location: "javascripts",
54
+ components: components_in_javascripts,
55
+ },
56
+ {
57
+ location: "ruby",
58
+ components: components_in_ruby,
59
+ },
60
+ ],
61
+ }
62
+ end
63
+
64
+ private
65
+
66
+ def find_components(files, find, type)
67
+ components_found = []
68
+
69
+ files.each do |file|
70
+ src = File.read(file)
71
+ components_found << find_match(find, src, type)
72
+ end
73
+
74
+ components_found.flatten.uniq.sort
75
+ end
76
+
77
+ def find_match(find, src, type)
78
+ return %w[all] if src.match(@find_all_stylesheets) && type == "stylesheets"
79
+ return %w[all] if src.match(@find_all_print_stylesheets) && type == "print_stylesheets"
80
+ return %w[all] if src.match(@find_all_javascripts) && type == "javascripts"
81
+
82
+ matches = src.scan(find)
83
+ all_matches = []
84
+ matches.each do |match|
85
+ all_matches << clean_file_name(match.tr('[])\'"', ""))
86
+ end
87
+
88
+ all_matches
89
+ end
90
+
91
+ def clean_file_name(name)
92
+ name.tr("_-", " ").strip
93
+ end
94
+
95
+ def application_exists(directory)
96
+ File.directory?(directory)
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,172 @@
1
+ module GovukPublishingComponents
2
+ class AuditComparer
3
+ attr_reader :data, :gem_data
4
+
5
+ def initialize(gem_data, results)
6
+ @gem_data = gem_data
7
+ @data = sort_results(results)
8
+ @gem_data[:components_by_application] = get_components_by_application
9
+ end
10
+
11
+ private
12
+
13
+ def prettify_key(key)
14
+ key.to_s.gsub("_", " ").capitalize
15
+ end
16
+
17
+ def sort_results(results)
18
+ data = []
19
+
20
+ results.each do |result|
21
+ templates = result[:components_found].find { |c| c[:location] == "templates" }
22
+ stylesheets = result[:components_found].find { |c| c[:location] == "stylesheets" }
23
+ print_stylesheets = result[:components_found].find { |c| c[:location] == "print_stylesheets" }
24
+ javascripts = result[:components_found].find { |c| c[:location] == "javascripts" }
25
+ ruby = result[:components_found].find { |c| c[:location] == "ruby" }
26
+
27
+ @all_stylesheets = true if stylesheets[:components].include?("all")
28
+ @all_print_stylesheets = true if print_stylesheets[:components].include?("all")
29
+ @all_javascripts = true if javascripts[:components].include?("all")
30
+
31
+ templates[:components] = include_any_components_within_components(templates[:components])
32
+
33
+ warnings = []
34
+ warnings << warn_about_missing_components(result[:components_found])
35
+ warnings << warn_about_missing_assets(result[:components_found])
36
+ warnings = warnings.flatten
37
+
38
+ data << {
39
+ name: result[:name],
40
+ application_found: result[:application_found],
41
+ summary: [
42
+ {
43
+ name: "Components in templates",
44
+ value: templates[:components].flatten.uniq.sort.join(", "),
45
+ },
46
+ {
47
+ name: "Components in stylesheets",
48
+ value: stylesheets[:components].join(", "),
49
+ },
50
+ {
51
+ name: "Components in print stylesheets",
52
+ value: print_stylesheets[:components].join(", "),
53
+ },
54
+ {
55
+ name: "Components in javascripts",
56
+ value: javascripts[:components].join(", "),
57
+ },
58
+ {
59
+ name: "Components in ruby",
60
+ value: ruby[:components].join(", "),
61
+ },
62
+ ],
63
+ warnings: warnings,
64
+ warning_count: warnings.length,
65
+ }
66
+ end
67
+
68
+ data
69
+ end
70
+
71
+ def include_any_components_within_components(components)
72
+ @gem_data[:components_containing_components].each do |component|
73
+ components << component[:sub_components] if components.include?(component[:component])
74
+ end
75
+
76
+ components.flatten.uniq.sort
77
+ end
78
+
79
+ def create_warning(component, message)
80
+ {
81
+ component: component,
82
+ message: message,
83
+ }
84
+ end
85
+
86
+ def find_missing_items(first_group, second_group)
87
+ warnings = []
88
+
89
+ first_group.each do |first|
90
+ first_location = first[:location]
91
+
92
+ second_group.each do |second|
93
+ second_location = second[:location]
94
+ second_location = "code" if %w[templates ruby].include?(second_location)
95
+ in_current = find_missing(second[:components].clone, first[:components].clone)
96
+
97
+ next if second[:components].include?("all")
98
+
99
+ in_current.each do |component|
100
+ if @gem_data.include?("component_#{second_location}".to_sym)
101
+ warnings << create_warning(component, "Included in #{first_location} but not #{second_location}") if @gem_data["component_#{second_location}".to_sym].include?(component)
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ warnings
108
+ end
109
+
110
+ def warn_about_missing_assets(components)
111
+ warnings = []
112
+
113
+ code = components.select { |c| c[:location] == "templates" || c[:location] == "ruby" }
114
+ code = [
115
+ {
116
+ location: "code",
117
+ components: code.map { |c| c[:components] }.flatten.uniq.sort,
118
+ },
119
+ ]
120
+ assets = components.select { |c| c[:location] == "stylesheets" || c[:location] == "print_stylesheets" || c[:location] == "javascripts" }
121
+
122
+ warnings << find_missing_items(code, assets)
123
+ warnings << find_missing_items(assets, code)
124
+ warnings.flatten
125
+ end
126
+
127
+ def warn_about_missing_components(results)
128
+ warnings = []
129
+
130
+ results.each do |result|
131
+ location = result[:location]
132
+ result[:components].each do |component|
133
+ warnings << create_warning(component, "Included in #{location} but component does not exist") if component_does_not_exist(component)
134
+ end
135
+ end
136
+
137
+ warnings
138
+ end
139
+
140
+ def component_does_not_exist(component)
141
+ !@gem_data[:component_code].include?(component) unless component == "all"
142
+ end
143
+
144
+ def find_missing(needle, haystack)
145
+ (haystack - needle).flatten.sort
146
+ end
147
+
148
+ def get_components_by_application
149
+ results = []
150
+
151
+ @gem_data[:component_listing].each do |component|
152
+ found_in_applications = []
153
+
154
+ @data.each do |application|
155
+ name = application[:name]
156
+
157
+ application[:summary].each do |item|
158
+ found_in_applications << name if item[:value].include?(component[:name])
159
+ end
160
+ end
161
+
162
+ results << {
163
+ component: component[:name],
164
+ count: found_in_applications.uniq.length,
165
+ list: found_in_applications.uniq.join(", "),
166
+ }
167
+ end
168
+
169
+ results
170
+ end
171
+ end
172
+ end