slimmer 15.3.0 → 15.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5423f67907cfbc074dcc3ec3be3763ee1b4de7194746d3465e2bd8962f131589
4
- data.tar.gz: 9378a917a3a686ac18dda3d401596ff3c749f2c45897409cf9ca79af02d19005
3
+ metadata.gz: 6f9dab4037bbee9ec372a2d3093b8645d973ef8db63c8accd2d83bfb6a0f0e46
4
+ data.tar.gz: e8551a6f783608f5216ef2caa3ab23b7f15c6e8dca7ef27d1e7cad5b0f58fa2c
5
5
  SHA512:
6
- metadata.gz: 0e5d62fedf19a951a60d82df37a9b3ca5258b2f46bc8e521e44050e00ff4755681f07ef6b5a540ea72702d5a5ae86fdd4792b86b9feeff07c1dd47dd075ea085
7
- data.tar.gz: 79a18ae53ba25f1d3c3dacb186b1b7d239457b4a3201aad806aefad5547e55368021acdc94c46d35ad479686777c07ee88bf3a7a145237e7f64413b0bd13dd49
6
+ metadata.gz: 5644a0a8217c1774a288573c9c6953db43c9f8a7b9f6d629a5515a79b953f05f4013cd9e7d55405f6df7e536213569d3e400ec5ae751e5b4a46828a4c93e81f4
7
+ data.tar.gz: b5e5d006ad1c69f687efc1201a13b3da4dd5efcbe6620cebf181a4fee49d4bebfc18beb15f2e9b370835c955baa58fa9b79d992d8c4e89484cab2e49c8734733
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ # 15.6.0
2
+
3
+ * Add feedback url swapper (#271)
4
+
5
+ # 15.5.1
6
+ * Update gem_layout template support (#267)
7
+
8
+ # 15.5.0
9
+ * Add support for gem layout in static (#265)
10
+
11
+ # 15.4.1
12
+
13
+ * Add support for layout header component in static (#263)
14
+
15
+ # 15.4.0
16
+
17
+ * Hoist `<async>` and `<defer>` JS Script tags to `<head>`. (#261)
18
+
1
19
  # 15.3.0
2
20
 
3
21
  * Introduce separate, internal exception class for intermittent
data/lib/slimmer.rb CHANGED
@@ -32,12 +32,11 @@ module Slimmer
32
32
  autoload :BodyClassCopier, "slimmer/processors/body_class_copier"
33
33
  autoload :BodyInserter, "slimmer/processors/body_inserter"
34
34
  autoload :ConditionalCommentMover, "slimmer/processors/conditional_comment_mover"
35
- autoload :FooterRemover, "slimmer/processors/footer_remover"
35
+ autoload :FeedbackURLSwapper, "slimmer/processors/feedback_url_swapper"
36
36
  autoload :MetadataInserter, "slimmer/processors/metadata_inserter"
37
37
  autoload :HeaderContextInserter, "slimmer/processors/header_context_inserter"
38
38
  autoload :InsideHeaderInserter, "slimmer/processors/inside_header_inserter"
39
39
  autoload :NavigationMover, "slimmer/processors/navigation_mover"
40
- autoload :SearchIndexSetter, "slimmer/processors/search_index_setter"
41
40
  autoload :SearchPathSetter, "slimmer/processors/search_path_setter"
42
41
  autoload :SearchParameterInserter, "slimmer/processors/search_parameter_inserter"
43
42
  autoload :SearchRemover, "slimmer/processors/search_remover"
@@ -6,6 +6,15 @@ module Slimmer::Processors
6
6
 
7
7
  def filter(_src, dest)
8
8
  header_value = @headers[Slimmer::Headers::SHOW_ACCOUNTS_HEADER]
9
+ layout_header = dest.at_css(".gem-c-layout-header")
10
+ static_header = dest.at_css("#global-header")
11
+
12
+ if header_value && layout_header
13
+ static_header.remove if static_header
14
+ elsif !header_value && !is_gem_layout?
15
+ layout_header.remove if layout_header
16
+ end
17
+
9
18
  if header_value == "signed-in"
10
19
  remove_signed_out(dest)
11
20
  elsif header_value == "signed-out"
@@ -14,16 +23,41 @@ module Slimmer::Processors
14
23
  remove_signed_out(dest)
15
24
  remove_signed_in(dest)
16
25
  end
26
+
27
+ if is_navigation_empty?(dest)
28
+ header_content = dest.at_css(".govuk-header__content")
29
+ header_content.remove if header_content
30
+ end
17
31
  end
18
32
 
33
+ private
34
+
19
35
  def remove_signed_out(dest)
20
36
  signed_out = dest.at_css("#global-header #accounts-signed-out")
37
+ signed_out_link = dest.css(".gem-c-layout-header [data-link-for='accounts-signed-out']")
38
+
21
39
  signed_out.remove if signed_out
40
+ signed_out_link.each do |link|
41
+ link.parent.remove
42
+ end
22
43
  end
23
44
 
24
45
  def remove_signed_in(dest)
25
46
  signed_in = dest.at_css("#global-header #accounts-signed-in")
47
+ signed_in_link = dest.css(".gem-c-layout-header [data-link-for='accounts-signed-in']")
48
+
26
49
  signed_in.remove if signed_in
50
+ signed_in_link.each do |link|
51
+ link.parent.remove
52
+ end
53
+ end
54
+
55
+ def is_navigation_empty?(dest)
56
+ dest.at_css(".govuk-header__navigation a").nil?
57
+ end
58
+
59
+ def is_gem_layout?
60
+ @headers[Slimmer::Headers::TEMPLATE_HEADER]&.starts_with?("gem_layout")
27
61
  end
28
62
  end
29
63
  end
@@ -1,13 +1,28 @@
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", headers = {})
4
4
  @source_selector = "#" + source_id
5
5
  @destination_selector = "#" + destination_id
6
+ @headers = headers
6
7
  end
7
8
 
8
9
  def filter(src, dest)
9
- body = Nokogiri::HTML.fragment(src.at_css(@source_selector).to_html)
10
+ source_markup = src.at_css(@source_selector)
11
+ destination_markup = dest.at_css(@destination_selector)
12
+
13
+ css_classes = []
14
+ css_classes << source_markup.attributes["class"].to_s.split(/ +/) if source_markup.has_attribute?("class")
15
+ css_classes << destination_markup.attributes["class"].to_s.split(/ +/) if destination_markup.has_attribute?("class")
16
+
17
+ body = Nokogiri::HTML.fragment(source_markup.to_html)
10
18
  dest.at_css(@destination_selector).replace(body)
19
+ dest.at_css(@destination_selector).set_attribute("class", css_classes.flatten.uniq.join(" ")) if is_gem_layout? && css_classes.any?
20
+ end
21
+
22
+ private
23
+
24
+ def is_gem_layout?
25
+ @headers[Slimmer::Headers::TEMPLATE_HEADER]&.starts_with?("gem_layout")
11
26
  end
12
27
  end
13
28
  end
@@ -0,0 +1,34 @@
1
+ module Slimmer::Processors
2
+ class FeedbackURLSwapper
3
+ def initialize(request, headers)
4
+ @headers = headers
5
+ @request = request
6
+ end
7
+
8
+ def filter(_src, dest)
9
+ return dest unless is_gem_layout?
10
+
11
+ original_url_without_pii = remove_pii(@request.base_url + @request.fullpath)
12
+ dest.at_css(".gem-c-feedback input[name='url']").set_attribute("value", original_url_without_pii)
13
+
14
+ full_path_without_pii = remove_pii(@request.fullpath)
15
+ dest.at_css(".gem-c-feedback input[name='email_survey_signup[survey_source]']").set_attribute("value", full_path_without_pii)
16
+
17
+ dest
18
+ end
19
+
20
+ private
21
+
22
+ # This PII removal is also found in the [feedback component in the GOV.UK
23
+ # Publishing Components gem](https://git.io/JcCIE), and any changes made
24
+ # need to be kept in sync.
25
+ def remove_pii(string)
26
+ email_regex = /[^\s=\/?&]+(?:@|%40)[^\s=\/?&]+/
27
+ string.dup.force_encoding("UTF-8").gsub(email_regex, "[email]")
28
+ end
29
+
30
+ def is_gem_layout?
31
+ @headers[Slimmer::Headers::TEMPLATE_HEADER]&.starts_with?("gem_layout")
32
+ end
33
+ end
34
+ end
@@ -11,6 +11,9 @@ module Slimmer::Processors
11
11
 
12
12
  search_link = dest.at_css("#global-header .search-toggle")
13
13
  search_link.remove if search_link
14
+
15
+ gem_search = dest.at_css(".gem-c-layout-header__search")
16
+ gem_search.remove if gem_search
14
17
  end
15
18
  end
16
19
  end
@@ -1,11 +1,11 @@
1
1
  module Slimmer::Processors
2
2
  class TagMover
3
3
  def filter(src, dest)
4
- move_tags(src, dest, "script", dest_node: "body", keys: %w[src inner_html])
5
4
  move_tags(src, dest, "link", must_have: %w[href])
6
5
  move_tags(src, dest, "meta", must_have: %w[name content], keys: %w[name content http-equiv], insertion_location: :top)
7
6
  move_tags(src, dest, "meta", must_have: %w[property content], keys: %w[property content], insertion_location: :top)
8
7
  move_tags(src, dest, "base", must_have: %w[href])
8
+ move_tags(src, dest, "script", keys: %w[src inner_html], head_if_attributes: %w[async defer])
9
9
  end
10
10
 
11
11
  def include_tag?(node, min_attrs)
@@ -31,21 +31,34 @@ module Slimmer::Processors
31
31
  node
32
32
  end
33
33
 
34
+ def head_or_body(node, head_if_attributes)
35
+ if head_if_attributes.any? { |attribute| node.has_attribute?(attribute) }
36
+ "head"
37
+ else
38
+ "body"
39
+ end
40
+ end
41
+
34
42
  def move_tags(src, dest, type, opts)
35
43
  comparison_attrs = opts[:keys] || opts[:must_have]
36
44
  min_attrs = opts[:must_have] || []
45
+ head_if_attributes = opts[:head_if_attributes] || []
46
+ dest_node = "head"
37
47
  already_there = dest.css(type).map { |node|
38
48
  tag_fingerprint(node, comparison_attrs)
39
49
  }.compact
40
- dest_node = opts[:dest_node] || "head"
41
50
 
42
51
  src.css(type).each do |node|
43
52
  next unless include_tag?(node, min_attrs) && !already_there.include?(tag_fingerprint(node, comparison_attrs))
44
53
 
45
54
  node = wrap_node(src, node)
55
+ if head_if_attributes.any?
56
+ dest_node = head_or_body(node, head_if_attributes)
57
+ insert_at_top = true if dest_node == "head"
58
+ end
46
59
  node.remove
47
60
 
48
- if opts[:insertion_location] == :top
61
+ if opts[:insertion_location] == :top || insert_at_top
49
62
  dest.at_xpath("/html/#{dest_node}").prepend_child(node)
50
63
  else
51
64
  dest.at_xpath("/html/#{dest_node}") << node
data/lib/slimmer/skin.rb CHANGED
@@ -101,13 +101,15 @@ module Slimmer
101
101
 
102
102
  def success(source_request, response, body)
103
103
  wrapper_id = options[:wrapper_id] || "wrapper"
104
+ template_wrapper_id = "wrapper" # All templates in Static use `#wrapper`
104
105
 
105
106
  processors = [
106
107
  Processors::TitleInserter.new,
107
108
  Processors::TagMover.new,
108
109
  Processors::NavigationMover.new(self),
109
110
  Processors::ConditionalCommentMover.new,
110
- Processors::BodyInserter.new(wrapper_id),
111
+ Processors::BodyInserter.new(wrapper_id, template_wrapper_id, response.headers),
112
+ Processors::FeedbackURLSwapper.new(source_request, response.headers),
111
113
  Processors::BodyClassCopier.new,
112
114
  Processors::InsideHeaderInserter.new,
113
115
  Processors::HeaderContextInserter.new,
@@ -1,3 +1,3 @@
1
1
  module Slimmer
2
- VERSION = "15.3.0".freeze
2
+ VERSION = "15.6.0".freeze
3
3
  end
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: 15.3.0
4
+ version: 15.6.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: 2020-11-10 00:00:00.000000000 Z
11
+ date: 2021-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -256,7 +256,7 @@ files:
256
256
  - lib/slimmer/processors/body_class_copier.rb
257
257
  - lib/slimmer/processors/body_inserter.rb
258
258
  - lib/slimmer/processors/conditional_comment_mover.rb
259
- - lib/slimmer/processors/footer_remover.rb
259
+ - lib/slimmer/processors/feedback_url_swapper.rb
260
260
  - lib/slimmer/processors/header_context_inserter.rb
261
261
  - lib/slimmer/processors/inside_header_inserter.rb
262
262
  - lib/slimmer/processors/metadata_inserter.rb
@@ -1,8 +0,0 @@
1
- module Slimmer::Processors
2
- class FooterRemover
3
- def filter(src, _dest)
4
- footer = src.at_css("#footer")
5
- footer.remove if footer
6
- end
7
- end
8
- end