slimmer 11.1.1 → 13.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +25 -0
  3. data/README.md +1 -50
  4. data/Rakefile +1 -1
  5. data/lib/slimmer.rb +1 -9
  6. data/lib/slimmer/app.rb +19 -17
  7. data/lib/slimmer/cucumber.rb +0 -7
  8. data/lib/slimmer/headers.rb +14 -18
  9. data/lib/slimmer/processors/body_inserter.rb +2 -2
  10. data/lib/slimmer/processors/conditional_comment_mover.rb +0 -2
  11. data/lib/slimmer/processors/footer_remover.rb +1 -1
  12. data/lib/slimmer/processors/header_context_inserter.rb +3 -3
  13. data/lib/slimmer/processors/metadata_inserter.rb +1 -1
  14. data/lib/slimmer/processors/navigation_mover.rb +0 -1
  15. data/lib/slimmer/processors/search_parameter_inserter.rb +1 -1
  16. data/lib/slimmer/processors/search_path_setter.rb +1 -1
  17. data/lib/slimmer/processors/search_remover.rb +1 -1
  18. data/lib/slimmer/processors/tag_mover.rb +16 -9
  19. data/lib/slimmer/processors/title_inserter.rb +2 -2
  20. data/lib/slimmer/rspec.rb +0 -7
  21. data/lib/slimmer/skin.rb +11 -20
  22. data/lib/slimmer/test_templates/header_footer_only.html +2 -0
  23. data/lib/slimmer/test_templates/wrapper.html +2 -0
  24. data/lib/slimmer/version.rb +1 -1
  25. data/lib/tasks/slimmer.rake +1 -1
  26. metadata +7 -16
  27. data/lib/slimmer/component_resolver.rb +0 -26
  28. data/lib/slimmer/govuk_components.rb +0 -57
  29. data/lib/slimmer/i18n_backend.rb +0 -56
  30. data/lib/slimmer/local_component_resolver.rb +0 -19
  31. data/lib/slimmer/local_govuk_components.rb +0 -49
  32. data/lib/slimmer/network_component_resolver.rb +0 -45
  33. data/lib/slimmer/processors/report_a_problem_inserter.rb +0 -32
  34. data/lib/slimmer/test_helpers/govuk_components.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 882c71d5e22c37f0dfe1f0598975f4c19e27ceb9
4
- data.tar.gz: 6c115e9e40c73fa7216316ffe727663eb26f2b8c
2
+ SHA256:
3
+ metadata.gz: 966481420a36ac4cbaf811706d2ae142b9ce1556c6b8be10ca682766cbe8e2e6
4
+ data.tar.gz: 79cb54e5f8d0db751cbc40ff3acd6c573395fec2e13e4bb9e43021b93c69a3a4
5
5
  SHA512:
6
- metadata.gz: 25ec33d5397c26d2392389bf173619c617ad41c8c54f64d7028c575b217f58f9c4104659c4eee671630412c2d367303c442f502d22bd204eed68cb1bbb4d380e
7
- data.tar.gz: aa90a515cae94a8d23d530cf4543be9dba85955ca0421bd59848805803dd7d40d20b9362e2bcb1b009e985ccd898d6bb74b6a6e2b0aa2e07ddcf1e7d98415094
6
+ metadata.gz: cd9b2d065c5cc805cc92f84728fb4990352030ac25ad5f8ad024b5794e90bc52b82c04f08eb1a7adfbd45abef17849e2ae977d95f579f3d184d290af5a9a4d3b
7
+ data.tar.gz: d846dd0e2ce3edcb9503708e0c162e5899530e988abf6513a785bef995cc2193df948718892e3200d4408e3ee79b34aead7a9ccec4af042b6214a98f480444b7
@@ -1,3 +1,28 @@
1
+ # 13.2.0
2
+
3
+ * Upgrade Ruby version to 2.6.5. (#234)
4
+ * Fix linting issues. (#234)
5
+
6
+ # 13.1.0
7
+
8
+ * Add `js-enabled` to body tag of test templates. (#226)
9
+
10
+ # 13.0.0
11
+
12
+ * Drop cache TTL to 60 seconds.
13
+ * BREAKING: Remove the component system, components are now consumed via the [govuk_publishing_components gem](https://github.com/alphagov/govuk_publishing_components)
14
+
15
+ # 12.1.0
16
+
17
+ * Make sure that the metatags defined in the application are inserted at the
18
+ top of the page. This means that third parties will see the custom metatags
19
+ like `og:image` first, and template tags like the default sharing image second (#218)
20
+
21
+ # 12.0.0
22
+
23
+ * Remove the "report a problem" feature. This is now being covered by the
24
+ feedback component (#213)
25
+
1
26
  # 11.1.1
2
27
 
3
28
  * Make the 'Inside Header Inserter' more resillient so that it doesn't throw
data/README.md CHANGED
@@ -15,8 +15,7 @@ Slimmer provides a Railtie so no configuration is necessary.
15
15
 
16
16
  ## Caching
17
17
 
18
- Slimmer makes HTTP requests to `static` for templates, components and locales. These
19
- are cached for 15 minutes. Slimmer uses `Rails.cache` for this.
18
+ Slimmer makes HTTP requests to `static` for templates. These are cached using `Rails.cache`.
20
19
 
21
20
  ## Asset tag helpers
22
21
 
@@ -82,54 +81,6 @@ YourApp::Application.configure do
82
81
  end
83
82
  ```
84
83
 
85
- ## GOV.UK Components
86
-
87
- To use [shared template components](https://govuk-static.herokuapp.com/component-guide) you need to include the GOV.UK component module:
88
-
89
- ```rb
90
- class ApplicationController < ActionController::Base
91
- include Slimmer::GovukComponents
92
- end
93
- ```
94
-
95
- This will make calls out to static when you try and render a partial prefixed with `govuk_component`:
96
-
97
- ```erb
98
- <%= render partial: 'govuk_component/example_component' %>
99
- ```
100
-
101
- You will need a copy of static running for the templates to be loaded from.
102
-
103
- ### Testing components
104
-
105
- In test mode (when `Rails.env.test?` returns `true`), shared components are not
106
- fetched from Static. Instead they are rendered as a dummy tag which contains a
107
- JSON dump of the `locals` - the arguments passed to the component.
108
-
109
- A test helper is included which returns a CSS selector for finding a given
110
- component to assert that it was used. You can make it available in your tests
111
- with:
112
-
113
- ```rb
114
- require 'slimmer/test_helpers/govuk_components'
115
- include Slimmer::TestHelpers::GovukComponents
116
- ```
117
-
118
- And then assert that the component has been used:
119
-
120
- ```rb
121
- page.should have_css(shared_component_selector('metadata'))
122
- ```
123
-
124
- Or look for one of the arguments to the component which will have been
125
- `JSON.dump`ed inside the tag:
126
-
127
- ```rb
128
- within(shared_component_selector('title')) do
129
- expect(page).to have_content(expected_title_text)
130
- end
131
- ```
132
-
133
84
  ### Cucumber
134
85
 
135
86
  Add the following code to features/support:
data/Rakefile CHANGED
@@ -12,7 +12,7 @@ RDoc::Task.new do |rd|
12
12
  end
13
13
 
14
14
  Rake::TestTask.new("test") do |t|
15
- t.ruby_opts << "-rubygems"
15
+ t.ruby_opts << "-rrubygems"
16
16
  t.libs << "test"
17
17
  t.test_files = FileList["test/**/*_test.rb"]
18
18
  t.verbose = true
@@ -7,7 +7,7 @@ require 'slimmer/version'
7
7
  require 'slimmer/railtie' if defined? Rails
8
8
 
9
9
  module Slimmer
10
- CACHE_TTL = 900
10
+ CACHE_TTL = 60
11
11
 
12
12
  def self.cache
13
13
  @cache ||= defined?(Rails) ? Rails.cache : NoCache.new
@@ -27,13 +27,6 @@ module Slimmer
27
27
  autoload :Headers, 'slimmer/headers'
28
28
  autoload :HTTPClient, 'slimmer/http_client'
29
29
 
30
- autoload :GovukComponents, 'slimmer/govuk_components'
31
- autoload :LocalGovukComponents, 'slimmer/local_govuk_components'
32
- autoload :ComponentResolver, 'slimmer/component_resolver'
33
- autoload :NetworkComponentResolver, 'slimmer/network_component_resolver'
34
- autoload :LocalComponentResolver, 'slimmer/local_component_resolver'
35
- autoload :I18nBackend, 'slimmer/i18n_backend'
36
-
37
30
  module Processors
38
31
  autoload :BodyClassCopier, 'slimmer/processors/body_class_copier'
39
32
  autoload :BodyInserter, 'slimmer/processors/body_inserter'
@@ -43,7 +36,6 @@ module Slimmer
43
36
  autoload :HeaderContextInserter, 'slimmer/processors/header_context_inserter'
44
37
  autoload :InsideHeaderInserter, 'slimmer/processors/inside_header_inserter'
45
38
  autoload :NavigationMover, 'slimmer/processors/navigation_mover'
46
- autoload :ReportAProblemInserter, 'slimmer/processors/report_a_problem_inserter'
47
39
  autoload :SearchIndexSetter, 'slimmer/processors/search_index_setter'
48
40
  autoload :SearchPathSetter, 'slimmer/processors/search_path_setter'
49
41
  autoload :SearchParameterInserter, 'slimmer/processors/search_parameter_inserter'
@@ -4,20 +4,21 @@ module Slimmer
4
4
  class App
5
5
  attr_accessor :logger
6
6
 
7
- def initialize(app, *args, &block)
7
+ def initialize(app, *args)
8
8
  options = args.first || {}
9
9
  @app = app
10
10
 
11
11
  logger = options[:logger] || NullLogger.instance
12
12
  self.logger = logger
13
13
  begin
14
- if logger.level == 0 # Log set to debug level
14
+ if logger.level.zero? # Log set to debug level
15
15
  unless options[:enable_debugging]
16
16
  self.logger = logger.dup
17
17
  self.logger.level = 1 # info
18
18
  end
19
19
  end
20
- rescue NoMethodError # In case logger doesn't respond_to? :level
20
+ rescue NoMethodError # rubocop:disable Lint/HandleExceptions
21
+ # In case logger doesn't respond_to? :level
21
22
  end
22
23
 
23
24
  if options.key? :template_path
@@ -60,7 +61,7 @@ module Slimmer
60
61
 
61
62
  def skip_slimmer_param?(env)
62
63
  skip = Rack::Request.new(env).params['skip_slimmer']
63
- skip and skip.to_i > 0
64
+ skip && skip.to_i.positive?
64
65
  end
65
66
 
66
67
  def skip_slimmer_header?(response)
@@ -69,8 +70,9 @@ module Slimmer
69
70
 
70
71
  def s(body)
71
72
  return body.to_s unless body.respond_to?(:each)
73
+
72
74
  b = ""
73
- body.each {|a| b << a }
75
+ body.each { |a| b << a }
74
76
  b
75
77
  end
76
78
 
@@ -87,17 +89,17 @@ module Slimmer
87
89
  GovukRequestId.value = env['HTTP_GOVUK_REQUEST_ID']
88
90
 
89
91
  rewritten_body = case response.status
90
- when 200
91
- @skin.success request, response, s(response.body)
92
- when 403
93
- @skin.error '403', s(response.body), request.env
94
- when 404
95
- @skin.error '404', s(response.body), request.env
96
- when 410
97
- @skin.error '410', s(response.body), request.env
98
- else
99
- @skin.error '500', s(response.body), request.env
100
- end
92
+ when 200
93
+ @skin.success request, response, s(response.body)
94
+ when 403
95
+ @skin.error '403', s(response.body), request.env
96
+ when 404
97
+ @skin.error '404', s(response.body), request.env
98
+ when 410
99
+ @skin.error '410', s(response.body), request.env
100
+ else
101
+ @skin.error '500', s(response.body), request.env
102
+ end
101
103
 
102
104
  rewritten_body = [rewritten_body] unless rewritten_body.respond_to?(:each)
103
105
  response.body = rewritten_body
@@ -107,7 +109,7 @@ module Slimmer
107
109
  end
108
110
 
109
111
  def strip_slimmer_headers(headers)
110
- headers.reject {|k, v| k =~ /\A#{Headers::HEADER_PREFIX}/ }
112
+ headers.reject { |k, _v| k =~ /\A#{Headers::HEADER_PREFIX}/ }
111
113
  end
112
114
  end
113
115
  end
@@ -1,10 +1,3 @@
1
1
  require 'cucumber'
2
2
 
3
3
  require 'slimmer/test'
4
- require 'slimmer/test_helpers/govuk_components'
5
-
6
- World(Slimmer::TestHelpers::GovukComponents)
7
-
8
- Before do
9
- stub_shared_component_locales
10
- end
@@ -5,7 +5,7 @@ module Slimmer
5
5
  InvalidHeader = Class.new(RuntimeError)
6
6
 
7
7
  # @private
8
- HEADER_PREFIX = "X-Slimmer"
8
+ HEADER_PREFIX = "X-Slimmer".freeze
9
9
 
10
10
  # @private
11
11
  SLIMMER_HEADER_MAPPING = {
@@ -13,7 +13,6 @@ module Slimmer
13
13
  format: "Format",
14
14
  page_owner: "Page-Owner",
15
15
  organisations: "Organisations",
16
- report_a_problem: "Report-a-Problem",
17
16
  world_locations: "World-Locations",
18
17
  result_count: "Result-Count",
19
18
  search_parameters: "Search-Parameters",
@@ -21,43 +20,40 @@ module Slimmer
21
20
  skip: "Skip",
22
21
  template: "Template",
23
22
  remove_search: "Remove-Search",
24
- }
23
+ }.freeze
25
24
 
26
25
  # @private
27
- APPLICATION_NAME_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:application_name]}"
26
+ APPLICATION_NAME_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:application_name]}".freeze
28
27
 
29
28
  # @private
30
- FORMAT_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:format]}"
29
+ FORMAT_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:format]}".freeze
31
30
 
32
31
  # @private
33
- ORGANISATIONS_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:organisations]}"
32
+ ORGANISATIONS_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:organisations]}".freeze
34
33
 
35
34
  # @private
36
- REPORT_A_PROBLEM_FORM = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:report_a_problem]}"
35
+ WORLD_LOCATIONS_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:world_locations]}".freeze
37
36
 
38
37
  # @private
39
- WORLD_LOCATIONS_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:world_locations]}"
38
+ PAGE_OWNER_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:page_owner]}".freeze
40
39
 
41
40
  # @private
42
- PAGE_OWNER_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:page_owner]}"
41
+ RESULT_COUNT_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:result_count]}".freeze
43
42
 
44
43
  # @private
45
- RESULT_COUNT_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:result_count]}"
44
+ SEARCH_PATH_HEADER = "#{HEADER_PREFIX}-Search-Path".freeze
46
45
 
47
46
  # @private
48
- SEARCH_PATH_HEADER = "#{HEADER_PREFIX}-Search-Path"
47
+ SEARCH_PARAMETERS_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:search_parameters]}".freeze
49
48
 
50
49
  # @private
51
- SEARCH_PARAMETERS_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:search_parameters]}"
50
+ SKIP_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:skip]}".freeze
52
51
 
53
52
  # @private
54
- SKIP_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:skip]}"
53
+ TEMPLATE_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:template]}".freeze
55
54
 
56
55
  # @private
57
- TEMPLATE_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:template]}"
58
-
59
- # @private
60
- REMOVE_SEARCH_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:remove_search]}"
56
+ REMOVE_SEARCH_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:remove_search]}".freeze
61
57
 
62
58
  # Set the "slimmer headers" to configure the page
63
59
  #
@@ -67,7 +63,6 @@ module Slimmer
67
63
  # @option hash [String] organisations
68
64
  # @option hash [String] page_owner
69
65
  # @option hash [String] remove_search
70
- # @option hash [String] report_a_problem
71
66
  # @option hash [String] result_count
72
67
  # @option hash [String] search_parameters
73
68
  # @option hash [String] section
@@ -76,6 +71,7 @@ module Slimmer
76
71
  # @option hash [String] world_locations
77
72
  def set_slimmer_headers(hash)
78
73
  raise InvalidHeader if (hash.keys - SLIMMER_HEADER_MAPPING.keys).any?
74
+
79
75
  SLIMMER_HEADER_MAPPING.each do |hash_key, header_suffix|
80
76
  value = hash[hash_key]
81
77
  headers["#{HEADER_PREFIX}-#{header_suffix}"] = value.to_s if value
@@ -1,11 +1,11 @@
1
1
  module Slimmer::Processors
2
2
  class BodyInserter
3
- def initialize(source_id='wrapper', destination_id='wrapper')
3
+ def initialize(source_id = 'wrapper', destination_id = 'wrapper')
4
4
  @source_selector = '#' + source_id
5
5
  @destination_selector = '#' + destination_id
6
6
  end
7
7
 
8
- def filter(src,dest)
8
+ def filter(src, dest)
9
9
  body = Nokogiri::HTML.fragment(src.at_css(@source_selector).to_html)
10
10
  dest.at_css(@destination_selector).replace(body)
11
11
  end
@@ -13,5 +13,3 @@ module Slimmer::Processors
13
13
  end
14
14
  end
15
15
  end
16
-
17
-
@@ -1,6 +1,6 @@
1
1
  module Slimmer::Processors
2
2
  class FooterRemover
3
- def filter(src,dest)
3
+ def filter(src, _dest)
4
4
  footer = src.at_css("#footer")
5
5
  footer.remove if footer
6
6
  end
@@ -1,11 +1,11 @@
1
1
  module Slimmer::Processors
2
2
  class HeaderContextInserter
3
- def initialize(path='.header-context')
3
+ def initialize(path = '.header-context')
4
4
  @path = path
5
5
  end
6
6
 
7
- def filter(src,dest)
8
- if dest.at_css(@path) && replacement = src.at_css(@path)
7
+ def filter(src, dest)
8
+ if dest.at_css(@path) && (replacement = src.at_css(@path))
9
9
  header_context = src.fragment(replacement)
10
10
  dest.at_css(@path).replace(header_context)
11
11
  end
@@ -5,7 +5,7 @@ module Slimmer::Processors
5
5
  @app_name = app_name
6
6
  end
7
7
 
8
- def filter(src, dest)
8
+ def filter(_src, dest)
9
9
  head = dest.at_css('head')
10
10
 
11
11
  add_meta_tag('analytics:organisations', @headers[Slimmer::Headers::ORGANISATIONS_HEADER], head)
@@ -1,5 +1,4 @@
1
1
  class Slimmer::Processors::NavigationMover
2
-
3
2
  def initialize(skin)
4
3
  @skin = skin
5
4
  end
@@ -6,7 +6,7 @@ module Slimmer::Processors
6
6
  @response = response
7
7
  end
8
8
 
9
- def filter(content_document, page_template)
9
+ def filter(_content_document, page_template)
10
10
  search_form = page_template.at_css('form#search')
11
11
  if search_parameters && search_form
12
12
  search_parameters.each_pair do |name, value|
@@ -4,7 +4,7 @@ module Slimmer::Processors
4
4
  @response = response
5
5
  end
6
6
 
7
- def filter(content_document, page_template)
7
+ def filter(_content_document, page_template)
8
8
  if search_scope && page_template.at_css('form#search')
9
9
  page_template.at_css('form#search').attributes["action"].value = search_scope
10
10
  end
@@ -4,7 +4,7 @@ module Slimmer::Processors
4
4
  @headers = headers
5
5
  end
6
6
 
7
- def filter(src,dest)
7
+ def filter(_src, dest)
8
8
  if @headers.include?(Slimmer::Headers::REMOVE_SEARCH_HEADER)
9
9
  search = dest.at_css("#global-header #search")
10
10
  search.remove if search
@@ -1,10 +1,10 @@
1
1
  module Slimmer::Processors
2
2
  class TagMover
3
- def filter(src,dest)
4
- move_tags(src, dest, 'script', :dest_node => 'body', :keys => ['src', 'inner_html'])
5
- move_tags(src, dest, 'link', :must_have => ['href'])
6
- move_tags(src, dest, 'meta', :must_have => ['name', 'content'], :keys => ['name', 'content', 'http-equiv'])
7
- move_tags(src, dest, 'meta', :must_have => ['property', 'content'], :keys => ['property', 'content'])
3
+ def filter(src, dest)
4
+ move_tags(src, dest, 'script', dest_node: 'body', keys: %w(src inner_html))
5
+ move_tags(src, dest, 'link', must_have: %w[href])
6
+ move_tags(src, dest, 'meta', must_have: %w(name content), keys: %w[name content http-equiv], insertion_location: :top)
7
+ move_tags(src, dest, 'meta', must_have: %w(property content), keys: %w(property content), insertion_location: :top)
8
8
  end
9
9
 
10
10
  def include_tag?(node, min_attrs)
@@ -12,17 +12,19 @@ module Slimmer::Processors
12
12
  end
13
13
 
14
14
  def tag_fingerprint(node, attrs)
15
- attrs.collect do |attr_name|
15
+ collected_attrs = attrs.collect do |attr_name|
16
16
  if attr_name == 'inner_html'
17
17
  node.content
18
18
  else
19
19
  node.has_attribute?(attr_name) ? node.attr(attr_name) : nil
20
20
  end
21
- end.compact.sort
21
+ end
22
+
23
+ collected_attrs.compact.sort
22
24
  end
23
25
 
24
26
  def wrap_node(src, node)
25
- if node.previous_sibling.to_s =~ /<!--\[if[^\]]+\]><!-->/ and node.next_sibling.to_s == '<!--<![endif]-->'
27
+ if node.previous_sibling.to_s =~ /<!--\[if[^\]]+\]><!-->/ && node.next_sibling.to_s == '<!--<![endif]-->'
26
28
  node = Nokogiri::XML::NodeSet.new(src, [node.previous_sibling, node, node.next_sibling])
27
29
  end
28
30
  node
@@ -40,7 +42,12 @@ module Slimmer::Processors
40
42
  if include_tag?(node, min_attrs) && !already_there.include?(tag_fingerprint(node, comparison_attrs))
41
43
  node = wrap_node(src, node)
42
44
  node.remove
43
- dest.at_xpath("/html/#{dest_node}") << node
45
+
46
+ if opts[:insertion_location] == :top
47
+ dest.at_xpath("/html/#{dest_node}").prepend_child(node)
48
+ else
49
+ dest.at_xpath("/html/#{dest_node}") << node
50
+ end
44
51
  end
45
52
  end
46
53
  end
@@ -1,10 +1,10 @@
1
1
  module Slimmer::Processors
2
2
  class TitleInserter
3
- def filter(src,dest)
3
+ def filter(src, dest)
4
4
  title = src.at_css('head title')
5
5
  head = dest.at_xpath('/html/head')
6
6
  if head && title
7
- insert_title(title,head)
7
+ insert_title(title, head)
8
8
  end
9
9
  end
10
10
 
@@ -2,10 +2,3 @@ require 'rspec/core'
2
2
 
3
3
  require 'slimmer'
4
4
  require 'slimmer/test'
5
- require 'slimmer/test_helpers/govuk_components'
6
-
7
- RSpec.configure do |config|
8
- config.include Slimmer::TestHelpers::GovukComponents
9
-
10
- config.before { stub_shared_component_locales }
11
- end
@@ -10,7 +10,7 @@ module Slimmer
10
10
  @asset_host = options[:asset_host]
11
11
 
12
12
  @logger = options[:logger] || NullLogger.instance
13
- @strict = options[:strict] || (%w{development test}.include?(ENV['RACK_ENV']))
13
+ @strict = options[:strict] || %w{development test}.include?(ENV['RACK_ENV'])
14
14
  end
15
15
 
16
16
  def template(template_name)
@@ -34,15 +34,15 @@ module Slimmer
34
34
  "#{host}templates/#{template_name}.html.erb"
35
35
  end
36
36
 
37
- def report_parse_errors_if_strict!(nokogiri_doc, description_for_error_message)
37
+ def report_parse_errors_if_strict!(nokogiri_doc, _description_for_error_message)
38
38
  nokogiri_doc
39
39
  end
40
40
 
41
41
  def parse_html(html, description_for_error_message)
42
42
  doc = Nokogiri::HTML.parse(html)
43
43
  if strict
44
- errors = doc.errors.select {|e| e.error?}.reject {|e| ignorable?(e)}
45
- if errors.size > 0
44
+ errors = doc.errors.select(&:error?).reject { |e| ignorable?(e) }
45
+ if !errors.empty?
46
46
  error = errors.first
47
47
  message = "In #{description_for_error_message}: '#{error.message}' at line #{error.line} col #{error.column} (code #{error.code}).\n"
48
48
  message << "Add ?skip_slimmer=1 to the url to show the raw backend request.\n\n"
@@ -59,7 +59,7 @@ module Slimmer
59
59
  lines = [""] + html.split("\n")
60
60
  from = [1, error.line - context_size].max
61
61
  to = [lines.size - 1, error.line + context_size].min
62
- context = (from..to).zip(lines[from..to]).map {|lineno, line| "%4d: %s" % [lineno, line] }
62
+ context = (from..to).zip(lines[from..to]).map { |lineno, line| "%4d: %s" % [lineno, line] } # rubocop:disable Style/FormatStringToken
63
63
  marker = " " * (error.column - 1) + "-----v"
64
64
  context.insert(context_size, marker)
65
65
  context.join("\n")
@@ -70,7 +70,7 @@ module Slimmer
70
70
  ignorable_codes.include?(error.code) || error.message.match(/Element script embeds close tag/) || error.message.match(/Unexpected end tag : noscript/)
71
71
  end
72
72
 
73
- def process(processors,body,template, rack_env)
73
+ def process(processors, body, template, _rack_env)
74
74
  logger.debug "Slimmer: starting skinning process"
75
75
  src = parse_html(body.to_s, "backend response")
76
76
  dest = parse_html(template, "template")
@@ -94,27 +94,18 @@ module Slimmer
94
94
  def success(source_request, response, body)
95
95
  wrapper_id = options[:wrapper_id] || 'wrapper'
96
96
 
97
- # The variables set in the source request might not be encoded as UTF-8,
98
- # Unicorn, for instance, will set them to be ASCII. This shouldn't matter
99
- # normally because URI's should have UTF-8 characters percent encoded,
100
- # but not all agents follow this.
101
- request_url = source_request.url.force_encoding(Encoding::UTF_8)
102
97
  processors = [
103
- Processors::TitleInserter.new(),
104
- Processors::TagMover.new(),
98
+ Processors::TitleInserter.new,
99
+ Processors::TagMover.new,
105
100
  Processors::NavigationMover.new(self),
106
- Processors::ConditionalCommentMover.new(),
101
+ Processors::ConditionalCommentMover.new,
107
102
  Processors::BodyInserter.new(wrapper_id),
108
103
  Processors::BodyClassCopier.new,
109
104
  Processors::InsideHeaderInserter.new,
110
- Processors::HeaderContextInserter.new(),
105
+ Processors::HeaderContextInserter.new,
111
106
  Processors::MetadataInserter.new(response, options[:app_name]),
112
107
  Processors::SearchParameterInserter.new(response),
113
108
  Processors::SearchPathSetter.new(response),
114
- Processors::ReportAProblemInserter.new(self,
115
- request_url,
116
- response.headers,
117
- wrapper_id),
118
109
  Processors::SearchRemover.new(response.headers),
119
110
  ]
120
111
 
@@ -124,7 +115,7 @@ module Slimmer
124
115
 
125
116
  def error(template_name, body, rack_env)
126
117
  processors = [
127
- Processors::TitleInserter.new()
118
+ Processors::TitleInserter.new
128
119
  ]
129
120
  process(processors, body, template(template_name), rack_env)
130
121
  end
@@ -3,6 +3,8 @@
3
3
  <title>Test Template</title>
4
4
  </head>
5
5
  <body>
6
+ <script>document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');</script>
7
+
6
8
  <header id="global-header">
7
9
  <div class="header-wrapper"></div>
8
10
  </header>
@@ -3,6 +3,8 @@
3
3
  <title>Test Template</title>
4
4
  </head>
5
5
  <body>
6
+ <script>document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');</script>
7
+
6
8
  <header id="global-header">
7
9
  <div class="header-wrapper"></div>
8
10
  </header>
@@ -1,3 +1,3 @@
1
1
  module Slimmer
2
- VERSION = '11.1.1'
2
+ VERSION = '13.2.0'.freeze
3
3
  end
@@ -6,7 +6,7 @@ namespace :slimmer do
6
6
  path_to_static = "../static/public"
7
7
  path_to_public = "public"
8
8
  commands = ["cd #{path_to_public}"]
9
- dirs_to_link = Dir.glob("../static/public/*") {|f|
9
+ Dir.glob("../static/public/*") { |f|
10
10
  commands << "ln -s #{path_to_static}/#{f}"
11
11
  }
12
12
  commands << ["cd .."]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: slimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.1.1
4
+ version: 13.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GOV.UK Dev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-19 00:00:00.000000000 Z
11
+ date: 2019-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - '='
186
186
  - !ruby/object:Gem::Version
187
- version: 1.18.0
187
+ version: 3.5.0
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - '='
193
193
  - !ruby/object:Gem::Version
194
- version: 1.18.0
194
+ version: 3.5.0
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: timecop
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -212,14 +212,14 @@ dependencies:
212
212
  requirements:
213
213
  - - "~>"
214
214
  - !ruby/object:Gem::Version
215
- version: 0.5.1
215
+ version: 3.11.5
216
216
  type: :development
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
- version: 0.5.1
222
+ version: 3.11.5
223
223
  description: Rack middleware for skinning pages using a specific template
224
224
  email:
225
225
  - govuk-dev@digital.cabinet-office.gov.uk
@@ -234,16 +234,10 @@ files:
234
234
  - bin/render_slimmer_error
235
235
  - lib/slimmer.rb
236
236
  - lib/slimmer/app.rb
237
- - lib/slimmer/component_resolver.rb
238
237
  - lib/slimmer/cucumber.rb
239
- - lib/slimmer/govuk_components.rb
240
238
  - lib/slimmer/govuk_request_id.rb
241
239
  - lib/slimmer/headers.rb
242
240
  - lib/slimmer/http_client.rb
243
- - lib/slimmer/i18n_backend.rb
244
- - lib/slimmer/local_component_resolver.rb
245
- - lib/slimmer/local_govuk_components.rb
246
- - lib/slimmer/network_component_resolver.rb
247
241
  - lib/slimmer/processors/body_class_copier.rb
248
242
  - lib/slimmer/processors/body_inserter.rb
249
243
  - lib/slimmer/processors/conditional_comment_mover.rb
@@ -252,7 +246,6 @@ files:
252
246
  - lib/slimmer/processors/inside_header_inserter.rb
253
247
  - lib/slimmer/processors/metadata_inserter.rb
254
248
  - lib/slimmer/processors/navigation_mover.rb
255
- - lib/slimmer/processors/report_a_problem_inserter.rb
256
249
  - lib/slimmer/processors/search_parameter_inserter.rb
257
250
  - lib/slimmer/processors/search_path_setter.rb
258
251
  - lib/slimmer/processors/search_remover.rb
@@ -263,7 +256,6 @@ files:
263
256
  - lib/slimmer/skin.rb
264
257
  - lib/slimmer/template.rb
265
258
  - lib/slimmer/test.rb
266
- - lib/slimmer/test_helpers/govuk_components.rb
267
259
  - lib/slimmer/test_templates/header_footer_only.html
268
260
  - lib/slimmer/test_templates/proposition_menu.html
269
261
  - lib/slimmer/test_templates/wrapper.html
@@ -289,8 +281,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
289
281
  - !ruby/object:Gem::Version
290
282
  version: '0'
291
283
  requirements: []
292
- rubyforge_project: slimmer
293
- rubygems_version: 2.5.1
284
+ rubygems_version: 3.0.3
294
285
  signing_key:
295
286
  specification_version: 4
296
287
  summary: Thinner than the skinner
@@ -1,26 +0,0 @@
1
- module Slimmer
2
- class ComponentResolver < ::ActionView::Resolver
3
- TEST_TAG_NAME = 'test-govuk-component'
4
-
5
- def find_templates(name, prefix, partial, details, outside_app_allowed = false)
6
- return [] unless prefix == 'govuk_component'
7
- template_path = [prefix, name].join('/')
8
- details = {
9
- :format => 'text/html',
10
- :updated_at => Time.now,
11
- :virtual_path => template_path
12
- }
13
-
14
- [ActionView::Template.new(template_body(template_path), template_path, erb_handler, details)]
15
- end
16
-
17
- private
18
- def erb_handler
19
- @erb_handler ||= ActionView::Template.registered_template_handler(:erb)
20
- end
21
-
22
- def template_body(_template_path)
23
- raise NotImplementedError, "Use NetworkComponentResolver or LocalComponentResolver"
24
- end
25
- end
26
- end
@@ -1,57 +0,0 @@
1
- module Slimmer
2
- # @api public
3
- #
4
- # Include this module to add the GOV.UK Components to your app.
5
- # @example
6
- # class ApplicationController < ActionController::Base
7
- # include Slimmer::GovukComponents
8
- # end
9
- #
10
- # # In your views:
11
- #
12
- # <%= render partial: 'govuk_component/example_component' %>
13
- module GovukComponents
14
- def self.included into
15
- into.before_action :add_govuk_components
16
- end
17
-
18
- # @private
19
- def add_govuk_components
20
- append_view_path GovukComponents.expiring_resolver_cache.resolver
21
-
22
- return if slimmer_backend_included?
23
- I18n.backend = I18n::Backend::Chain.new(I18n.backend, Slimmer::I18nBackend.new)
24
- end
25
-
26
- # @private
27
- def self.expiring_resolver_cache
28
- @expiring_resolver_cache ||= TimedExpirationResolverCache.new
29
- end
30
-
31
- private
32
-
33
- def slimmer_backend_included?
34
- I18n.backend.is_a?(I18n::Backend::Chain) &&
35
- I18n.backend.backends.any? { |b| b.is_a? Slimmer::I18nBackend }
36
- end
37
-
38
- # Slimmer::ComponentResolver instantiates a lot of large objects and leaks
39
- # memory. This class will cache the resolver so that it doesn't have to
40
- # create new ActionView::Template objects for each request. The cache is
41
- # timed to allow frontends to pick up changes made to components in `static`.
42
- class TimedExpirationResolverCache
43
- def initialize
44
- @cache_last_reset = Time.now
45
- end
46
-
47
- def resolver
48
- if (@cache_last_reset + Slimmer::CACHE_TTL) < Time.now
49
- @resolver = nil
50
- @cache_last_reset = Time.now
51
- end
52
-
53
- @resolver ||= Slimmer::NetworkComponentResolver.new
54
- end
55
- end
56
- end
57
- end
@@ -1,56 +0,0 @@
1
- require 'json'
2
- require 'i18n'
3
-
4
- module Slimmer
5
- class I18nBackend
6
- include I18n::Backend::Base, I18n::Backend::Flatten
7
-
8
- def available_locales
9
- Slimmer.cache.fetch("available_locales", expires_in: Slimmer::CACHE_TTL) do
10
- locale_json = fetch(static_locales_url)
11
- JSON.parse(locale_json).map(&:to_sym)
12
- end
13
- end
14
-
15
- def lookup(locale, key, scope = [], options = {})
16
- key = normalize_flat_keys(locale, key, scope, options[:separator])
17
- translations = translations(locale)
18
- translations["#{locale}.#{key}".to_sym]
19
- end
20
-
21
- private
22
-
23
- def translations(locale)
24
- Slimmer.cache.fetch("translations/#{locale}", expires_in: Slimmer::CACHE_TTL) do
25
- fetch_translations(locale)
26
- end
27
- end
28
-
29
- def static_locales_url(locale=nil)
30
- [static_host, "templates", "locales", locale].compact.join('/')
31
- end
32
-
33
- def static_host
34
- @static_host ||= Plek.new.find('static')
35
- end
36
-
37
- def fetch_translations(locale)
38
- url = static_locales_url(locale)
39
- json_data = fetch(url)
40
- translations = JSON.parse(json_data)
41
- flatten_translations(locale, translations, false, false)
42
- rescue TemplateNotFoundException
43
- {}
44
- end
45
-
46
- def fetch(url)
47
- HTTPClient.get(url)
48
- rescue RestClient::Exception => e
49
- raise TemplateNotFoundException, "Unable to fetch: '#{url}' because #{e}", caller
50
- rescue Errno::ECONNREFUSED => e
51
- raise CouldNotRetrieveTemplate, "Unable to fetch: '#{url}' because #{e}", caller
52
- rescue SocketError => e
53
- raise CouldNotRetrieveTemplate, "Unable to fetch: '#{url}' because #{e}", caller
54
- end
55
- end
56
- end
@@ -1,19 +0,0 @@
1
- module Slimmer
2
- class LocalComponentResolver < ComponentResolver
3
- private
4
-
5
- def template_body(template_path)
6
- File.read(template_file(template_path))
7
- end
8
-
9
- def template_file(template_path)
10
- path = template_path.sub(/\.raw(\.html\.erb)?$/, '')
11
-
12
- if defined?(Rails)
13
- Rails.root.join("app", "views", "#{path}.raw.html.erb")
14
- else
15
- "#{path}.raw.html.erb"
16
- end
17
- end
18
- end
19
- end
@@ -1,49 +0,0 @@
1
- module Slimmer
2
- # @api public
3
- #
4
- # Include this module to avoid loading components over the network
5
- # @example
6
- # class ApplicationController < ActionController::Base
7
- # include Slimmer::LocalGovukComponents
8
- # end
9
- #
10
- # # In your views:
11
- #
12
- # <%= render partial: 'govuk_component/example_component' %>
13
- module LocalGovukComponents
14
- def self.included into
15
- into.before_action :add_govuk_components
16
- end
17
-
18
- # @private
19
- def add_govuk_components
20
- append_view_path LocalGovukComponents.expiring_resolver_cache.resolver
21
- end
22
-
23
- # @private
24
- def self.expiring_resolver_cache
25
- @expiring_resolver_cache ||= TimedExpirationResolverCache.new
26
- end
27
-
28
- private
29
-
30
- # Slimmer::ComponentResolver instantiates a lot of large objects and leaks
31
- # memory. This class will cache the resolver so that it doesn't have to
32
- # create new ActionView::Template objects for each request. The cache is
33
- # timed to allow frontends to pick up changes made to components in `static`.
34
- class TimedExpirationResolverCache
35
- def initialize
36
- @cache_last_reset = Time.now
37
- end
38
-
39
- def resolver
40
- if (@cache_last_reset + Slimmer::CACHE_TTL) < Time.now
41
- @resolver = nil
42
- @cache_last_reset = Time.now
43
- end
44
-
45
- @resolver ||= Slimmer::LocalComponentResolver.new
46
- end
47
- end
48
- end
49
- end
@@ -1,45 +0,0 @@
1
- require 'slimmer/govuk_request_id'
2
- require 'active_support/core_ext/string/inflections'
3
-
4
- module Slimmer
5
- class NetworkComponentResolver < ComponentResolver
6
- private
7
-
8
- def template_body(template_path)
9
- if test?
10
- test_body(template_path)
11
- else
12
- Slimmer.cache.fetch(template_path, expires_in: Slimmer::CACHE_TTL) do
13
- fetch(template_url(template_path))
14
- end
15
- end
16
- end
17
-
18
- def test?
19
- defined?(Rails) && Rails.env.test?
20
- end
21
-
22
- def fetch(template_url)
23
- HTTPClient.get(template_url)
24
- rescue RestClient::Exception => e
25
- raise TemplateNotFoundException, "Unable to fetch: '#{template_url}' because #{e}", caller
26
- rescue Errno::ECONNREFUSED => e
27
- raise CouldNotRetrieveTemplate, "Unable to fetch: '#{template_url}' because #{e}", caller
28
- rescue SocketError => e
29
- raise CouldNotRetrieveTemplate, "Unable to fetch: '#{template_url}' because #{e}", caller
30
- end
31
-
32
- def template_url(template_path)
33
- path = template_path.sub(/\.raw(\.html\.erb)?$/, '')
34
- [static_host, "templates", "#{path}.raw.html.erb"].join('/')
35
- end
36
-
37
- def static_host
38
- @static_host ||= Plek.new.find('static')
39
- end
40
-
41
- def test_body(path)
42
- %{<#{TEST_TAG_NAME} data-template="#{path.parameterize}"><%= JSON.dump(local_assigns) %></#{TEST_TAG_NAME}>}
43
- end
44
- end
45
- end
@@ -1,32 +0,0 @@
1
- module Slimmer::Processors
2
- class ReportAProblemInserter
3
- include ERB::Util
4
-
5
- def initialize(skin, url, headers, wrapper_id)
6
- @skin = skin
7
- @request_url = url
8
- @headers = headers
9
- @wrapper_id = wrapper_id
10
- end
11
-
12
- def filter(content_document, page_template)
13
- if enabled? && container = page_template.at_css('#' + @wrapper_id)
14
- container.add_child(report_a_problem_block)
15
- end
16
- end
17
-
18
- def report_a_problem_block
19
- request_url = @request_url
20
- source = @headers[Slimmer::Headers::APPLICATION_NAME_HEADER]
21
- page_owner = @headers[Slimmer::Headers::PAGE_OWNER_HEADER]
22
- report_a_problem_template = @skin.template('report_a_problem.raw')
23
- html = ERB.new(report_a_problem_template).result(binding)
24
- Nokogiri::HTML.fragment(html)
25
- end
26
-
27
- private
28
- def enabled?
29
- @headers[Slimmer::Headers::REPORT_A_PROBLEM_FORM] != 'false'
30
- end
31
- end
32
- end
@@ -1,18 +0,0 @@
1
- require 'webmock'
2
-
3
- module Slimmer
4
- module TestHelpers
5
- module GovukComponents
6
- def stub_shared_component_locales
7
- stub_request(:get, /https?:\/\/\S+.gov.uk\/templates\/locales\/.+/).
8
- to_return(status: 400, headers: {})
9
- stub_request(:get, /https?:\/\/\S+.gov.uk\/templates\/locales/).
10
- to_return(status: 200, body: '{}', headers: {})
11
- end
12
-
13
- def shared_component_selector(name)
14
- "#{Slimmer::ComponentResolver::TEST_TAG_NAME}[data-template='govuk_component-#{name}']"
15
- end
16
- end
17
- end
18
- end