swedbank-pay-design-guide-jekyll-theme 1.6.1.pre.PullRequest0137.pre.0064 → 1.9.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 +4 -4
- data/_includes/sidebar.html +1 -2
- data/_layouts/default.html +4 -5
- data/_layouts/front-page.html +112 -0
- data/_plugins/sidebar.rb +2 -1
- data/lib/gem_version.rb +1 -1
- data/lib/safe_merge.rb +28 -0
- data/lib/sanitized_filename.rb +12 -0
- data/lib/sidebar.rb +27 -190
- data/lib/sidebar_html_builder.rb +141 -0
- data/lib/sidebar_page.rb +117 -0
- data/lib/sidebar_page_collection.rb +37 -0
- data/lib/sidebar_page_title.rb +29 -0
- data/lib/sidebar_parser.rb +62 -0
- data/lib/sidebar_path.rb +62 -0
- data/lib/sidebar_renderer.rb +51 -0
- data/lib/sidebar_text_builder.rb +46 -0
- data/lib/sidebar_tree_builder.rb +73 -0
- metadata +45 -6
- data/_includes/front-page.html +0 -240
@@ -0,0 +1,141 @@
|
|
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
|
+
current_path = current_path(current_page)
|
25
|
+
markup = ''
|
26
|
+
|
27
|
+
pages.each do |page|
|
28
|
+
next if page.ignore?
|
29
|
+
|
30
|
+
sub_items_markup = sub_items_markup(page, current_path)
|
31
|
+
markup << item_markup(page, current_path, page.level, sub_items_markup)
|
32
|
+
end
|
33
|
+
|
34
|
+
markup
|
35
|
+
end
|
36
|
+
|
37
|
+
def current_path(current_page)
|
38
|
+
if current_page.nil?
|
39
|
+
Jekyll.logger.warn(' Sidebar: Nil current_page')
|
40
|
+
return ''
|
41
|
+
end
|
42
|
+
|
43
|
+
return current_page if current_page.is_a? String
|
44
|
+
return current_page.path if current_page.respond_to?(:path)
|
45
|
+
|
46
|
+
Jekyll.logger.warn(" Sidebar: #{current_page.class} ('#{current_page}') does not respond to :path.")
|
47
|
+
|
48
|
+
''
|
49
|
+
end
|
50
|
+
|
51
|
+
def item_markup(page, current_path, level, sub_items_markup)
|
52
|
+
title_markup = title_markup(page, level)
|
53
|
+
item_class = item_class(page, current_path, level)
|
54
|
+
group_heading_class = group_heading_class(level)
|
55
|
+
|
56
|
+
"<li class=\"#{item_class}\">
|
57
|
+
<div class=\"#{group_heading_class}\">
|
58
|
+
<i class=\"material-icons\">arrow_right</i>
|
59
|
+
#{title_markup}
|
60
|
+
</div>
|
61
|
+
#{sub_items_markup}
|
62
|
+
</li>"
|
63
|
+
end
|
64
|
+
|
65
|
+
def item_class(page, current_path, level)
|
66
|
+
active = active?(page, current_path, level)
|
67
|
+
item_class = group_class(level)
|
68
|
+
item_class += ' active' if active
|
69
|
+
item_class
|
70
|
+
end
|
71
|
+
|
72
|
+
def group_class(level)
|
73
|
+
level.zero? ? 'nav-group' : 'nav-subgroup'
|
74
|
+
end
|
75
|
+
|
76
|
+
def group_heading_class(level)
|
77
|
+
group_class = group_class(level)
|
78
|
+
"#{group_class}-heading"
|
79
|
+
end
|
80
|
+
|
81
|
+
def title_markup(page, level)
|
82
|
+
section_title = section_title(page)
|
83
|
+
return "<span>#{section_title}</span>" if level.zero?
|
84
|
+
|
85
|
+
item_title = item_title(page)
|
86
|
+
"<a href=\"#{page.path}\">#{item_title}</a>"
|
87
|
+
end
|
88
|
+
|
89
|
+
def sub_items_markup(page, current_path)
|
90
|
+
headers_markup = headers_markup(page, current_path)
|
91
|
+
child_markup = build_markup(page.children, current_path)
|
92
|
+
|
93
|
+
return '' if headers_markup.empty? && child_markup.empty?
|
94
|
+
|
95
|
+
"<ul class=\"nav-ul\">
|
96
|
+
#{headers_markup}
|
97
|
+
#{child_markup}
|
98
|
+
</ul>"
|
99
|
+
end
|
100
|
+
|
101
|
+
def headers_markup(page, current_path)
|
102
|
+
# If there's no page headers, only return a leaf item for the page itself.
|
103
|
+
return leaf_markup(page.path, page.title.item, page.level) unless page.headers?
|
104
|
+
|
105
|
+
# If there's no children, only return the headers as leaf node items.
|
106
|
+
return page.headers.map { |h| header_markup(page, h) }.join('') if page.children.empty?
|
107
|
+
|
108
|
+
headers_markup = page.headers.map { |h| header_markup(page, h) }.join('')
|
109
|
+
headers_markup = "<ul class=\"nav-ul\">#{headers_markup}</ul>"
|
110
|
+
|
111
|
+
item_markup(page, current_path, page.level + 1, headers_markup)
|
112
|
+
end
|
113
|
+
|
114
|
+
def header_markup(page, header)
|
115
|
+
hash = header[:hash]
|
116
|
+
subtitle = header[:title]
|
117
|
+
href = "#{page.path}#{hash}"
|
118
|
+
leaf_markup(href, subtitle)
|
119
|
+
end
|
120
|
+
|
121
|
+
def leaf_markup(href, title, level = 0)
|
122
|
+
leaf_class = level.positive? ? 'nav-leaf nav-subgroup-leaf' : 'nav-leaf'
|
123
|
+
"<li class=\"#{leaf_class}\"><a href=\"#{href}\">#{title}</a></li>"
|
124
|
+
end
|
125
|
+
|
126
|
+
def active?(page, current_path, level)
|
127
|
+
level.zero? ? page.active?(current_path) : page.path == current_path
|
128
|
+
end
|
129
|
+
|
130
|
+
def section_title(page)
|
131
|
+
return page.title.section unless page.title.section.nil?
|
132
|
+
return page.parent.title.to_s unless page.parent.nil? || page.parent.title.nil?
|
133
|
+
|
134
|
+
''
|
135
|
+
end
|
136
|
+
|
137
|
+
def item_title(page)
|
138
|
+
page.title.item
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
data/lib/sidebar_page.rb
ADDED
@@ -0,0 +1,117 @@
|
|
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 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(page)
|
18
|
+
raise ArgumentError, 'Page must be a Jekyll::Page' unless page.is_a? Jekyll::Page
|
19
|
+
|
20
|
+
sidebar_path = SidebarPath.new(page['url'])
|
21
|
+
@path = sidebar_path.to_s
|
22
|
+
@parent = sidebar_path.parent
|
23
|
+
@level = sidebar_path.level
|
24
|
+
@name = sidebar_path.name
|
25
|
+
@hide_from_sidebar = page['hide_from_sidebar'].nil? ? false : page['hide_from_sidebar']
|
26
|
+
@title = page_title(page)
|
27
|
+
@order = menu_order(page)
|
28
|
+
@children = SidebarPageCollection.new(self)
|
29
|
+
end
|
30
|
+
|
31
|
+
def active?(current_path)
|
32
|
+
return true if @path == current_path
|
33
|
+
|
34
|
+
@children.each do |child|
|
35
|
+
return true if child.active?(current_path)
|
36
|
+
end
|
37
|
+
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def ignore?
|
42
|
+
return true if @title.nil?
|
43
|
+
return true if @hide_from_sidebar
|
44
|
+
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
48
|
+
def children=(children)
|
49
|
+
@children = SidebarPageCollection.new(self, children)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
SidebarTextBuilder.new(self).to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
def inspect
|
57
|
+
to_s
|
58
|
+
end
|
59
|
+
|
60
|
+
def <=>(other)
|
61
|
+
return -1 if other.nil?
|
62
|
+
|
63
|
+
if @order == FIXNUM_MAX && other.order == FIXNUM_MAX
|
64
|
+
return 0 if @title.nil? && other.title.nil?
|
65
|
+
return -1 if other.title.nil?
|
66
|
+
return 1 if title.nil?
|
67
|
+
|
68
|
+
return @title <=> other.title
|
69
|
+
end
|
70
|
+
|
71
|
+
@order <=> other.order
|
72
|
+
end
|
73
|
+
|
74
|
+
def save
|
75
|
+
Jekyll.logger.debug(" Writing Sidebar: #{filename}")
|
76
|
+
|
77
|
+
File.open(@filename, 'w') do |file|
|
78
|
+
html = @doc.to_html(encoding: 'UTF-8')
|
79
|
+
file.write(html)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def headers?
|
84
|
+
!headers.nil? && headers.any?
|
85
|
+
end
|
86
|
+
|
87
|
+
def coordinate
|
88
|
+
return @number.to_s if @parent.nil?
|
89
|
+
|
90
|
+
"#{@parent.coordinate}.#{@number}"
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def page_title(page)
|
96
|
+
title = page['title']
|
97
|
+
return nil if title.nil?
|
98
|
+
|
99
|
+
SidebarPageTitle.new(title)
|
100
|
+
end
|
101
|
+
|
102
|
+
def menu_order(page)
|
103
|
+
order = page['menu_order']
|
104
|
+
return FIXNUM_MAX if order.nil? || order.to_s.empty?
|
105
|
+
|
106
|
+
order.to_i
|
107
|
+
end
|
108
|
+
|
109
|
+
def eq?(path)
|
110
|
+
@path == path
|
111
|
+
end
|
112
|
+
|
113
|
+
def child_of?(path)
|
114
|
+
@path.split('/').length > @level && path.start_with?(@path)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module SwedbankPay
|
6
|
+
# Arranges Sidebar pages into a tree
|
7
|
+
class SidebarPageCollection
|
8
|
+
include Enumerable
|
9
|
+
extend Forwardable
|
10
|
+
def_delegators :@pages, :each, :length, :empty?, :[]
|
11
|
+
|
12
|
+
def initialize(parent, pages = [])
|
13
|
+
raise ArgumentError, 'Pages must be an array' unless pages.is_a? Array
|
14
|
+
|
15
|
+
@pages = []
|
16
|
+
|
17
|
+
pages.each_with_index do |page, index|
|
18
|
+
page.number = index
|
19
|
+
page.parent = parent
|
20
|
+
page.freeze
|
21
|
+
@pages.push(page)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def count
|
26
|
+
return 0 if @pages.empty?
|
27
|
+
|
28
|
+
count = @pages.length
|
29
|
+
|
30
|
+
@pages.each do |page|
|
31
|
+
count += page.children.count
|
32
|
+
end
|
33
|
+
|
34
|
+
count
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SwedbankPay
|
4
|
+
# Represents the title of a SidebarPage
|
5
|
+
class SidebarPageTitle
|
6
|
+
attr_reader :section, :item
|
7
|
+
|
8
|
+
def initialize(title)
|
9
|
+
@title = title
|
10
|
+
parts = title.split('–')
|
11
|
+
@section = parts.first.strip
|
12
|
+
@item = parts.last.strip
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
@title
|
17
|
+
end
|
18
|
+
|
19
|
+
def inspect
|
20
|
+
@title
|
21
|
+
end
|
22
|
+
|
23
|
+
def <=>(other)
|
24
|
+
return -1 if other.nil?
|
25
|
+
|
26
|
+
@title <=> other.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'sidebar_path'
|
4
|
+
|
5
|
+
module SwedbankPay
|
6
|
+
# The Sidebar renderer
|
7
|
+
class SidebarParser
|
8
|
+
def initialize(site)
|
9
|
+
@site = site
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse(pages)
|
13
|
+
destination = @site.config['destination']
|
14
|
+
|
15
|
+
Dir.glob("#{destination}/**/*.html") do |filename|
|
16
|
+
doc = File.open(filename) { |f| Nokogiri::HTML(f) }
|
17
|
+
path = SidebarPath.new(filename).to_s
|
18
|
+
page = pages[path]
|
19
|
+
|
20
|
+
raise ArgumentError, "No page found for '#{path}'." if page.nil?
|
21
|
+
|
22
|
+
page.doc = doc
|
23
|
+
page.filename = filename
|
24
|
+
page.headers = find_headers(doc)
|
25
|
+
page.sidebar_container = find_sidebar_container(filename, doc)
|
26
|
+
end
|
27
|
+
|
28
|
+
pages
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def find_headers(doc)
|
34
|
+
headers = []
|
35
|
+
|
36
|
+
doc.xpath('//h2').each do |header|
|
37
|
+
next unless header['id']
|
38
|
+
|
39
|
+
child_markup = header.last_element_child
|
40
|
+
header = {
|
41
|
+
id: header['id'],
|
42
|
+
title: header.content.strip,
|
43
|
+
hash: (child_markup['href']).to_s
|
44
|
+
}
|
45
|
+
headers.push(header)
|
46
|
+
end
|
47
|
+
|
48
|
+
headers
|
49
|
+
end
|
50
|
+
|
51
|
+
def find_sidebar_container(filename, doc)
|
52
|
+
sidebar_containers = doc.xpath('//*[@id="dx-sidebar-main-nav-ul"]')
|
53
|
+
|
54
|
+
unless sidebar_containers.any?
|
55
|
+
Jekyll.logger.debug(" Sidebar: No sidebar container found in #{filename}")
|
56
|
+
return nil
|
57
|
+
end
|
58
|
+
|
59
|
+
sidebar_containers.first
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/sidebar_path.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'sanitized_filename'
|
4
|
+
require_relative 'sidebar_page_title'
|
5
|
+
|
6
|
+
module SwedbankPay
|
7
|
+
# Represents a page in the Sidebar
|
8
|
+
class SidebarPath
|
9
|
+
attr_reader :parent, :level, :name
|
10
|
+
|
11
|
+
def initialize(path)
|
12
|
+
@segments = segment(path)
|
13
|
+
@path = normalized(path)
|
14
|
+
@name = construct_name
|
15
|
+
@parent = find_parent
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
@path
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def segment(path)
|
29
|
+
segments = path.sanitized.split('/').reject(&:empty?)
|
30
|
+
@level = segments.length.zero? ? 0 : segments.length - 1
|
31
|
+
segments
|
32
|
+
end
|
33
|
+
|
34
|
+
def normalized(path)
|
35
|
+
return '/' if @segments.empty?
|
36
|
+
|
37
|
+
joined = "/#{@segments.join('/')}"
|
38
|
+
|
39
|
+
# Directory paths should end with '/'.
|
40
|
+
directory?(path) ? "#{joined}/" : joined
|
41
|
+
end
|
42
|
+
|
43
|
+
def directory?(path)
|
44
|
+
path.end_with?('/') || path.end_with?('/index.html')
|
45
|
+
end
|
46
|
+
|
47
|
+
def construct_name
|
48
|
+
return '/' if @path == '/'
|
49
|
+
|
50
|
+
@segments.last
|
51
|
+
end
|
52
|
+
|
53
|
+
def find_parent
|
54
|
+
# If there's no or only one path segment, this is a root page
|
55
|
+
return nil if @segments.empty? || (@segments.length == 1)
|
56
|
+
|
57
|
+
# Return the path minus the last segment as the parent path
|
58
|
+
last = @path.sub(%r{(/#{@segments.last}/?)$}, '')
|
59
|
+
"#{last}/"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|