govuk_publishing_components 21.56.1 → 21.59.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 (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