swedbank-pay-design-guide-jekyll-theme 1.7 → 1.9.1

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.
@@ -1,6 +1,7 @@
1
1
  @import 'colors.scss';
2
2
  @import 'fonts.scss';
3
3
  @import 'variables.scss';
4
+ @import 'breakpoints.scss';
4
5
 
5
6
  @import 'card.scss';
6
7
  @import 'code-view.scss';
@@ -17,6 +18,10 @@ img {
17
18
  max-width: 100%;
18
19
  }
19
20
 
21
+ body {
22
+ font-size: 1.125rem;
23
+ }
24
+
20
25
  .table {
21
26
 
22
27
  th,
@@ -1 +1 @@
1
- $max-width: 704px;
1
+ $max-width: 880px;
@@ -4,7 +4,7 @@ module Gem
4
4
  # Gem Specification
5
5
  class Specification
6
6
  def self.gem_version
7
- '1.7'
7
+ '1.9.1'
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The Hash class
4
+ class Hash
5
+ # Safely merges the current Hash with an 'other' Hash.
6
+ def safe_merge(other)
7
+ all_keys = keys | other.keys
8
+ result_hash = {}
9
+
10
+ all_keys.each do |key|
11
+ hash_value = {}
12
+
13
+ if key? key
14
+ value = self[key]
15
+ hash_value = value unless value.nil?
16
+ end
17
+
18
+ if other.key? key
19
+ value = other[key]
20
+ hash_value = hash_value.merge(value) unless value.nil?
21
+ end
22
+
23
+ result_hash[key] = hash_value
24
+ end
25
+
26
+ result_hash
27
+ end
28
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The String class
4
+ class String
5
+ # Sanitizes a filename
6
+ def sanitized
7
+ match = match(/(?m)(?<=\b_site).*$/)
8
+ sanitized_filename = match ? match[0] : self
9
+ sanitized_filename = sanitized_filename.gsub('index.html', '')
10
+ sanitized_filename.gsub('.html', '')
11
+ end
12
+ end
@@ -3,209 +3,37 @@
3
3
  require 'jekyll'
4
4
  require 'nokogiri'
5
5
  require 'json'
6
-
7
- module Jekyll
8
- class Sidebar
9
- attr_accessor :hash_pre_render
10
- attr_accessor :filename_with_headers
11
-
12
- def initialize
13
- @hash_pre_render = {}
14
- @filename_with_headers = {}
15
- end
16
-
17
- def pre_render(page)
18
- menu_order = page['menu-order'].nil? ? 0 : page['menu-order']
19
- hide_from_sidebar = page['hide_from_sidebar'].nil? ? false : page['hide_from_sidebar']
20
- url = page['url'].gsub('index.html', '').gsub('.html', '')
21
- @hash_pre_render[url] = {
22
- title: page['title'],
23
- url: page['url'].gsub('.html', ''),
24
- name: page['name'],
25
- menu_order: menu_order,
26
- hide_from_sidebar: hide_from_sidebar
27
- }
28
- end
29
-
30
- def post_write(site)
31
- files = []
32
- Dir.glob("#{site.config['destination']}/**/*.html") do |filename|
33
- doc = File.open(filename) { |f| Nokogiri::HTML(f) }
34
- files.push(doc)
35
-
36
- headers = []
37
- doc.xpath('//h2 ').each do |header|
38
- next unless header['id']
39
-
40
- child = header.last_element_child
41
- header = {
42
- id: header['id'],
43
- title: header.content.strip,
44
- hash: (child['href']).to_s
45
- }
46
- headers.push(header)
47
- end
48
- sanitized_filename = sanitize_filename(filename)
49
- @filename_with_headers[sanitized_filename] = { headers: headers }
50
- end
51
-
52
- Dir.glob("#{site.config['destination']}/**/*.html") do |filename|
53
- sanitized_filename = sanitize_filename(filename)
54
- sidebar = render(sanitized_filename)
55
- file = File.open(filename) { |f| Nokogiri::HTML(f) }
56
- file.xpath('//*[@id="dx-sidebar-main-nav-ul"]').each do |location|
57
- location.inner_html = sidebar
58
- end
59
- File.open(filename, 'w') { |f| f.write(file.to_html(encoding: 'UTF-8')) }
60
- end
61
-
62
- # File.open('_site/sidebar.html', 'w') { |f| f.write(sidebar) }
63
- end
64
-
65
- private
66
-
67
- def sanitize_filename(filename)
68
- sanitized_filename = filename.match(/(?m)(?<=\b_site).*$/)[0]
69
- sanitized_filename = sanitized_filename.gsub('index.html', '')
70
- sanitized_filename.gsub('.html', '')
71
- end
72
-
73
- def generateSubgroup(filename, key, value, all_subgroups, level)
74
- title = value[:title].split('–').last
75
- subsubgroup_list = all_subgroups.select do |subsubgroup_key, _subsubgroup_value|
76
- subsubgroup_key.include? key and subsubgroup_key != key and \
77
- key.split('/').length > level
78
- end
79
-
80
- subgroup = ''
81
- has_subgroups = !all_subgroups.empty?
82
- if value[:headers].any? || !subsubgroup_list.empty?
83
- if has_subgroups
84
- url = value[:url]
85
- active = active?(filename, url, true)
86
- # puts "#{url}, #{filename}, #{key}" if active
87
- item_class = active || (url.split('/').length > level && filename.start_with?(url)) ? 'nav-subgroup active' : 'nav-subgroup'
88
- subgroup << "<li class=\"#{item_class}\">"
89
- subgroup << "<div class=\"nav-subgroup-heading\"><i class=\"material-icons\">arrow_right</i><a href=\"#{url}\">#{title}</a></div>"
90
- subgroup << '<ul class="nav-ul">'
91
-
92
- if subsubgroup_list.empty?
93
- value[:headers].each do |header|
94
- subgroup << "<li class=\"nav-leaf\"><a href=\"#{value[:url]}#{header[:hash]}\">#{header[:title]}</a></li>"
95
- end
96
- else
97
- subgroup_leaf_class = active ? 'nav-leaf nav-subgroup-leaf active' : 'nav-leaf nav-subgroup-leaf'
98
- subgroup << "<li class=\"#{subgroup_leaf_class}\"><a href=\"#{value[:url]}\">#{title} overview</a></li>"
99
-
100
- subsubgroup_list.each do |subsubgroup_key, subsubgroup_value|
101
- subgroup << generateSubgroup(filename, subsubgroup_key, subsubgroup_value, subsubgroup_list, 3)
102
- end
103
- end
104
-
105
- subgroup << '</ul>'
106
- subgroup << '</li>'
107
- else
108
- value[:headers].each do |header|
109
- subgroup << "<li class=\"nav-leaf\"><a href=\"#{value[:url]}#{header[:hash]}\">#{header[:title]}</a></li>"
110
- end
111
- end
112
- else
113
- subgroup << if has_subgroups
114
- "<li class=\"nav-leaf nav-subgroup-leaf\"><a href=\"#{value[:url]}\">#{title}</a></li>"
115
- else
116
- "<li class=\"nav-leaf\"><a href=\"#{value[:url]}\">#{title}</a></li>"
117
- end
118
- end
119
-
120
- subgroup
121
- end
122
-
123
- def render(filename)
124
- sidebar = ''
125
-
126
- merged = merge(@hash_pre_render, @filename_with_headers).sort_by { |_key, value| value[:menu_order] }
127
- merged.select { |key, _value| key.split('/').length <= 2 }.each do |key, value|
128
- next if value[:title].nil?
129
- next if value[:hide_from_sidebar]
130
-
131
- subgroups = merged.select { |subgroup_key, _subgroup_value| subgroup_key.include? key and subgroup_key != key and key != '/' }
132
-
133
- active = active?(filename, key)
134
- # puts "#{filename}, #{key}" if active
135
- item_class = active ? 'nav-group active' : 'nav-group'
136
-
137
- child = "<li class=\"#{item_class}\">"
138
- child << "<div class=\"nav-group-heading\"><i class=\"material-icons\">arrow_right</i><span>#{value[:title].split('–').first}</span></div>"
139
-
140
- child << '<ul class="nav-ul">'
141
-
142
- subgroup = generateSubgroup(filename, key, value, subgroups, 2)
143
-
144
- child << subgroup
145
-
146
- if subgroups.any?
147
- subgroups.select { |subgroup_key, _subgroup_value| subgroup_key.split('/').length <= 3 }.each do |subgroup_key, subgroup_value|
148
- subgroup = generateSubgroup(filename, subgroup_key, subgroup_value, subgroups, 2)
149
- child << subgroup
150
- end
151
- end
152
-
153
- child << '</ul>'
154
- child << '</li>'
155
- sidebar << child
6
+ require_relative 'sidebar_page'
7
+ require_relative 'sidebar_parser'
8
+ require_relative 'sidebar_renderer'
9
+ require_relative 'sidebar_tree_builder'
10
+
11
+ module SwedbankPay
12
+ # A nice sidebar
13
+ module Sidebar
14
+ class << self
15
+ attr_reader :pages
16
+
17
+ def pre_render(site)
18
+ parser = SidebarParser.new(site)
19
+ pages = parser.parse
20
+ @pages = SidebarTreeBuilder.new(pages)
21
+ Jekyll.logger.debug(" Sidebar: #{@pages.inspect}")
22
+ @sidebar_renderer = SidebarRenderer.new(@pages)
23
+ @sidebar_renderer.enrich_jekyll
156
24
  end
157
25
 
158
- File.open('_site/sidebar.html', 'w') { |f| f.write(sidebar) }
159
- sidebar
160
- end
161
-
162
- def active?(filename, url, exact = false)
163
- if filename == '/' || url == '/'
164
- if filename == '/' && url == '/'
165
- return true
166
- else
167
- return false
168
- end
26
+ def post_write
27
+ @sidebar_renderer.render
169
28
  end
170
-
171
- exact ? filename == url : filename.start_with?(url)
172
- end
173
-
174
- def merge(hash1, hash2)
175
- all_keys = hash1.keys | hash2.keys
176
- result_hash = {}
177
-
178
- all_keys.each do |key|
179
- hash_value = {}
180
-
181
- if hash1.key? key
182
- value = hash1[key]
183
-
184
- hash_value = value unless value.nil?
185
- end
186
-
187
- if hash2.key? key
188
- value = hash2[key]
189
-
190
- hash_value = hash_value.merge(value) unless value.nil?
191
- end
192
-
193
- result_hash[key] = hash_value
194
- end
195
-
196
- result_hash
197
29
  end
198
30
  end
199
31
  end
200
32
 
201
- sidebar = Jekyll::Sidebar.new
202
-
203
- Jekyll::Hooks.register :site, :pre_render do |site, _payload|
204
- site.pages.each do |page|
205
- sidebar.pre_render page
206
- end
33
+ Jekyll::Hooks.register :site, :pre_render do |site, _|
34
+ SwedbankPay::Sidebar.pre_render site
207
35
  end
208
36
 
209
- Jekyll::Hooks.register :site, :post_write do |site|
210
- sidebar.post_write site
37
+ Jekyll::Hooks.register :site, :post_write do |_|
38
+ SwedbankPay::Sidebar.post_write
211
39
  end
@@ -0,0 +1,136 @@
1
+ # frozen_string_literal: false
2
+
3
+ require_relative 'sidebar_page'
4
+
5
+ module SwedbankPay
6
+ # The builder of HTML for the Sidebar
7
+ class SidebarHTMLBuilder
8
+ def initialize(tree)
9
+ @tree = tree
10
+ end
11
+
12
+ def build(current_page)
13
+ raise ArgumentError, 'current_page cannot be nil' if current_page.nil?
14
+ raise ArgumentError, "#{current_page.class} is not a #{SidebarPage}" unless current_page.is_a? SidebarPage
15
+
16
+ build_markup(@tree, current_page)
17
+ end
18
+
19
+ private
20
+
21
+ def build_markup(pages, current_page)
22
+ return '' if pages.empty?
23
+
24
+ markup = ''
25
+
26
+ pages.each do |page|
27
+ if page.hidden_for?(current_page)
28
+ name = current_page.respond_to?(:name) ? current_page.name : current_page.to_s
29
+ Jekyll.logger.debug(" Sidebar: #{page.name} is hidden for #{name}")
30
+ next
31
+ end
32
+
33
+ sub_items_markup = sub_items_markup(page, current_page)
34
+ markup << item_markup(page, current_page, sub_items_markup, false)
35
+ end
36
+
37
+ markup
38
+ end
39
+
40
+ def item_markup(page, current_page, sub_items_markup, is_leaf)
41
+ # If we're rendering a leaf node, just set the level to a non-zero value
42
+ # to get the 'nav-subgroup' class and such.
43
+ level = is_leaf ? -1 : page.level
44
+ title_markup = title_markup(page, level)
45
+ item_class = item_class(page, current_page, level, is_leaf)
46
+ group_heading_class = group_heading_class(level)
47
+
48
+ "<li class=\"#{item_class}\">
49
+ <div class=\"#{group_heading_class}\">
50
+ <i class=\"material-icons\">arrow_right</i>
51
+ #{title_markup}
52
+ </div>
53
+ #{sub_items_markup}
54
+ </li>"
55
+ end
56
+
57
+ def item_class(page, current_page, level, is_leaf)
58
+ active = page.active?(current_page, is_leaf: is_leaf)
59
+ item_class = group_class(level)
60
+ item_class += ' active' if active
61
+ item_class
62
+ end
63
+
64
+ def group_class(level)
65
+ level.zero? ? 'nav-group' : 'nav-subgroup'
66
+ end
67
+
68
+ def group_heading_class(level)
69
+ group_class = group_class(level)
70
+ "#{group_class}-heading"
71
+ end
72
+
73
+ def title_markup(page, level)
74
+ lead_title = lead_title(page)
75
+ return "<span>#{lead_title}</span>" if level.zero?
76
+
77
+ main_title = main_title(page)
78
+ "<a href=\"#{page.path}\">#{main_title}</a>"
79
+ end
80
+
81
+ def sub_items_markup(page, current_page)
82
+ headers_markup = headers_markup(page, current_page)
83
+ child_markup = build_markup(page.children, current_page)
84
+
85
+ return '' if headers_markup.empty? && child_markup.empty?
86
+
87
+ "<ul class=\"nav-ul\">
88
+ #{headers_markup}
89
+ #{child_markup}
90
+ </ul>"
91
+ end
92
+
93
+ def headers_markup(page, current_page)
94
+ # If there's no page headers, only return a leaf item for the page itself.
95
+ main_title = page.title.nil? ? nil : page.title.main
96
+ return leaf_markup(page.path, main_title, page.level) unless page.headers?
97
+
98
+ # If there's no children, only return the headers as leaf node items.
99
+ return page.headers.map { |h| header_markup(page, h) }.join('') if page.children.empty?
100
+
101
+ headers_markup = page.headers.map { |h| header_markup(page, h) }.join('')
102
+ headers_markup = "<ul class=\"nav-ul\">#{headers_markup}</ul>"
103
+
104
+ item_markup(page, current_page, headers_markup, true)
105
+ end
106
+
107
+ def header_markup(page, header)
108
+ hash = header[:hash]
109
+ subtitle = header[:title]
110
+ href = "#{page.path}#{hash}"
111
+ leaf_markup(href, subtitle)
112
+ end
113
+
114
+ def leaf_markup(href, title, level = 0)
115
+ leaf_class = level.positive? ? 'nav-leaf nav-subgroup-leaf' : 'nav-leaf'
116
+ "<li class=\"#{leaf_class}\"><a href=\"#{href}\">#{title}</a></li>"
117
+ end
118
+
119
+ def lead_title(page)
120
+ return page.title.lead unless page.title.nil? || page.title.lead.nil?
121
+ return page.parent.title.to_s unless page.parent.nil? || page.parent.title.nil?
122
+
123
+ ''
124
+ end
125
+
126
+ def main_title(page)
127
+ unless page.nil? || page.title.nil?
128
+ main = page.title.main
129
+
130
+ return main || page.title.to_s
131
+ end
132
+
133
+ ''
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,164 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'jekyll'
4
+ require_relative 'sidebar_path'
5
+ require_relative 'sidebar_page_title'
6
+ require_relative 'sidebar_page_collection'
7
+ require_relative 'sidebar_text_builder'
8
+
9
+ module SwedbankPay
10
+ # Represents a jekyll_page in the Sidebar
11
+ class SidebarPage
12
+ FIXNUM_MAX = (2**(0.size * 8 - 2) - 1)
13
+
14
+ attr_reader :path, :title, :level, :order, :children, :name
15
+ attr_accessor :headers, :filename, :doc, :sidebar_container, :number, :parent
16
+
17
+ def initialize(jekyll_page)
18
+ raise ArgumentError, 'jekyll_page cannot be nil' if jekyll_page.nil?
19
+ raise ArgumentError, 'jekyll_page must be a Jekyll::Page' unless jekyll_page.is_a? Jekyll::Page
20
+
21
+ @jekyll_page = jekyll_page
22
+ sidebar_path = SidebarPath.new(jekyll_page['url'])
23
+ @path = sidebar_path.to_s
24
+ @parent = sidebar_path.parent
25
+ @level = sidebar_path.level
26
+ @name = sidebar_path.name
27
+ @hide_from_sidebar = jekyll_page['hide_from_sidebar'].nil? ? false : jekyll_page['hide_from_sidebar']
28
+ @title = SidebarPageTitle.parse(jekyll_page, self)
29
+ @order = menu_order(jekyll_page)
30
+ @children = SidebarPageCollection.new(self)
31
+ end
32
+
33
+ def active?(current, is_leaf: false)
34
+ current_path = find_path(current)
35
+
36
+ return true if @path == current_path
37
+
38
+ # If we're on a leaf node item, such as when rendering the first header
39
+ # item of a sub-group, its children's active state must be disregarded.
40
+ unless is_leaf
41
+ @children.each do |child|
42
+ return true if child.active?(current_path, is_leaf: is_leaf)
43
+ end
44
+ end
45
+
46
+ false
47
+ end
48
+
49
+ def hidden?
50
+ return true if @title.nil?
51
+ return true if @hide_from_sidebar
52
+
53
+ false
54
+ end
55
+
56
+ def hidden_for?(other_page)
57
+ # The current page should be hidden for the other page unless the
58
+ # other page is also hidden.
59
+ #
60
+ # TODO: Make it so that hiddden pages within a section are visible
61
+ # for each other, but not for other sections, regardless if
62
+ # they are hidden or not.
63
+ hidden = hidden?
64
+
65
+ if other_page.nil? || !other_page.is_a?(SidebarPage)
66
+ Jekyll.logger.debug(" Sidebar: Other page '#{other_page}' is nil or not a SidebarPage")
67
+ return hidden
68
+ end
69
+
70
+ return false if other_page.hidden?
71
+
72
+ hidden
73
+ end
74
+
75
+ def children=(children)
76
+ @children = SidebarPageCollection.new(self, children)
77
+ end
78
+
79
+ def to_s
80
+ SidebarTextBuilder.new(self).to_s
81
+ end
82
+
83
+ def inspect
84
+ to_s
85
+ end
86
+
87
+ def <=>(other)
88
+ return -1 if other.nil?
89
+
90
+ if @order == FIXNUM_MAX && other.order == FIXNUM_MAX
91
+ return 0 if @title.nil? && other.title.nil?
92
+ return -1 if other.title.nil?
93
+ return 1 if title.nil?
94
+
95
+ return @title <=> other.title
96
+ end
97
+
98
+ @order <=> other.order
99
+ end
100
+
101
+ def enrich_jekyll
102
+ if @title.nil?
103
+ Jekyll.logger.debug(" Sidebar: No title for #{@name}")
104
+ return
105
+ end
106
+
107
+ Jekyll.logger.debug(" Sidebar: #{@name}.lead_title '#{@title.lead}'")
108
+ Jekyll.logger.debug(" Sidebar: #{@name}.main_title '#{@title.main}'")
109
+
110
+ @jekyll_page.data['lead_title'] = @title.lead
111
+ @jekyll_page.data['main_title'] = @title.main
112
+ end
113
+
114
+ def save
115
+ Jekyll.logger.debug(" Writing Sidebar: #{filename}")
116
+
117
+ File.open(@filename, 'w') do |file|
118
+ html = @doc.to_html(encoding: 'UTF-8')
119
+ file.write(html)
120
+ end
121
+ end
122
+
123
+ def headers?
124
+ !headers.nil? && headers.any?
125
+ end
126
+
127
+ def coordinate
128
+ return @number.to_s if @parent.nil?
129
+
130
+ "#{@parent.coordinate}.#{@number}"
131
+ end
132
+
133
+ private
134
+
135
+ def menu_order(jekyll_page)
136
+ order = jekyll_page['menu_order']
137
+ return FIXNUM_MAX if order.nil? || order.to_s.empty?
138
+
139
+ order.to_i
140
+ end
141
+
142
+ def eq?(path)
143
+ @path == path
144
+ end
145
+
146
+ def child_of?(path)
147
+ @path.split('/').length > @level && path.start_with?(@path)
148
+ end
149
+
150
+ def find_path(current)
151
+ if current.nil?
152
+ Jekyll.logger.warn(' Sidebar: Nil current_page')
153
+ return ''
154
+ end
155
+
156
+ return current if current.is_a? String
157
+ return current.path if current.respond_to?(:path)
158
+
159
+ Jekyll.logger.warn(" Sidebar: #{current.class} ('#{current}') does not respond to :path.")
160
+
161
+ ''
162
+ end
163
+ end
164
+ end