jazzy 0.13.1 → 0.13.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +6 -3
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +135 -1
  5. data/CONTRIBUTING.md +1 -1
  6. data/Gemfile.lock +62 -52
  7. data/README.md +86 -3
  8. data/Rakefile +30 -0
  9. data/bin/sourcekitten +0 -0
  10. data/images/math.png +0 -0
  11. data/jazzy.gemspec +1 -1
  12. data/js/package-lock.json +39 -0
  13. data/js/package.json +17 -0
  14. data/lib/jazzy/config.rb +33 -7
  15. data/lib/jazzy/doc.rb +4 -0
  16. data/lib/jazzy/doc_builder.rb +25 -2
  17. data/lib/jazzy/docset_builder.rb +2 -0
  18. data/lib/jazzy/docset_builder/info_plist.mustache +8 -0
  19. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_AMS-Regular.ttf +0 -0
  20. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_AMS-Regular.woff +0 -0
  21. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  22. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  23. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  24. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  25. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  26. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  27. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  28. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  29. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  30. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  31. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  32. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  33. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  34. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Bold.ttf +0 -0
  35. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Bold.woff +0 -0
  36. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Bold.woff2 +0 -0
  37. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  38. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  39. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  40. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Italic.ttf +0 -0
  41. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Italic.woff +0 -0
  42. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Italic.woff2 +0 -0
  43. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Regular.ttf +0 -0
  44. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Regular.woff +0 -0
  45. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Main-Regular.woff2 +0 -0
  46. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  47. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  48. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  49. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-Italic.ttf +0 -0
  50. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-Italic.woff +0 -0
  51. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Math-Italic.woff2 +0 -0
  52. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  53. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  54. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  55. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  56. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  57. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  58. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  59. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  60. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  61. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Script-Regular.ttf +0 -0
  62. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Script-Regular.woff +0 -0
  63. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Script-Regular.woff2 +0 -0
  64. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size1-Regular.ttf +0 -0
  65. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size1-Regular.woff +0 -0
  66. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  67. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size2-Regular.ttf +0 -0
  68. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size2-Regular.woff +0 -0
  69. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  70. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size3-Regular.ttf +0 -0
  71. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size3-Regular.woff +0 -0
  72. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  73. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size4-Regular.ttf +0 -0
  74. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size4-Regular.woff +0 -0
  75. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  76. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  77. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  78. data/lib/jazzy/extensions/katex/css/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  79. data/lib/jazzy/extensions/katex/css/katex.min.css +1 -0
  80. data/lib/jazzy/extensions/katex/js/katex.min.js +1 -0
  81. data/lib/jazzy/gem_version.rb +1 -1
  82. data/lib/jazzy/jazzy_markdown.rb +17 -0
  83. data/lib/jazzy/podspec_documenter.rb +15 -3
  84. data/lib/jazzy/source_declaration.rb +15 -2
  85. data/lib/jazzy/source_declaration/access_control_level.rb +1 -1
  86. data/lib/jazzy/source_declaration/type.rb +34 -0
  87. data/lib/jazzy/source_module.rb +2 -1
  88. data/lib/jazzy/sourcekitten.rb +55 -28
  89. data/lib/jazzy/symbol_graph.rb +95 -0
  90. data/lib/jazzy/symbol_graph/constraint.rb +94 -0
  91. data/lib/jazzy/symbol_graph/ext_node.rb +114 -0
  92. data/lib/jazzy/symbol_graph/graph.rb +193 -0
  93. data/lib/jazzy/symbol_graph/relationship.rb +39 -0
  94. data/lib/jazzy/symbol_graph/sym_node.rb +154 -0
  95. data/lib/jazzy/symbol_graph/symbol.rb +208 -0
  96. data/lib/jazzy/themes/apple/assets/css/jazzy.css.scss +79 -4
  97. data/lib/jazzy/themes/apple/assets/img/spinner.gif +0 -0
  98. data/lib/jazzy/themes/apple/assets/js/jazzy.js +12 -1
  99. data/lib/jazzy/themes/apple/assets/js/jazzy.search.js +70 -0
  100. data/lib/jazzy/themes/apple/assets/js/jquery.min.js +2 -2
  101. data/lib/jazzy/themes/apple/assets/js/lunr.min.js +6 -0
  102. data/lib/jazzy/themes/apple/assets/js/typeahead.jquery.js +1694 -0
  103. data/lib/jazzy/themes/apple/templates/doc.mustache +41 -0
  104. data/lib/jazzy/themes/apple/templates/header.mustache +7 -0
  105. data/lib/jazzy/themes/apple/templates/task.mustache +3 -3
  106. data/lib/jazzy/themes/fullwidth/assets/css/jazzy.css.scss +3 -1
  107. data/lib/jazzy/themes/fullwidth/assets/js/jazzy.js +12 -1
  108. data/lib/jazzy/themes/fullwidth/assets/js/jquery.min.js +2 -2
  109. data/lib/jazzy/themes/fullwidth/assets/js/lunr.min.js +6 -1
  110. data/lib/jazzy/themes/fullwidth/assets/js/typeahead.jquery.js +34 -14
  111. data/lib/jazzy/themes/fullwidth/templates/doc.mustache +36 -0
  112. data/lib/jazzy/themes/fullwidth/templates/task.mustache +3 -3
  113. data/lib/jazzy/themes/jony/assets/css/jazzy.css.scss +12 -2
  114. data/lib/jazzy/themes/jony/assets/js/jazzy.js +12 -1
  115. data/lib/jazzy/themes/jony/assets/js/jquery.min.js +2 -2
  116. data/lib/jazzy/themes/jony/templates/doc.mustache +36 -0
  117. data/lib/jazzy/themes/jony/templates/task.mustache +3 -3
  118. data/spec/integration_spec.rb +17 -8
  119. metadata +84 -8
@@ -0,0 +1,39 @@
1
+ module Jazzy
2
+ module SymbolGraph
3
+ # A Relationship is a tidied-up SymbolGraph JSON object
4
+ class Relationship
5
+ attr_accessor :kind
6
+ attr_accessor :source_usr
7
+ attr_accessor :target_usr
8
+ attr_accessor :target_fallback # can be nil
9
+ attr_accessor :constraints # array, can be empty
10
+
11
+ KINDS = %w[memberOf conformsTo defaultImplementationOf
12
+ overrides inheritsFrom requirementOf
13
+ optionalRequirementOf].freeze
14
+
15
+ def protocol_requirement?
16
+ %i[requirementOf optionalRequirementOf].include? kind
17
+ end
18
+
19
+ def default_implementation?
20
+ kind == :defaultImplementationOf
21
+ end
22
+
23
+ def initialize(hash)
24
+ kind = hash[:kind]
25
+ unless KINDS.include?(kind)
26
+ raise "Unknown relationship kind '#{kind}'"
27
+ end
28
+ self.kind = kind.to_sym
29
+ self.source_usr = hash[:source]
30
+ self.target_usr = hash[:target]
31
+ if fallback = hash[:targetFallback]
32
+ # Strip the leading module name
33
+ self.target_fallback = fallback.sub(/^.*?\./, '')
34
+ end
35
+ self.constraints = Constraint.new_list(hash[:swiftConstraints] || [])
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,154 @@
1
+ module Jazzy
2
+ module SymbolGraph
3
+ # The rebuilt syntax tree is made of nodes that either match
4
+ # symbols or that we fabricate for extensions. This is the common
5
+ # treeishness.
6
+ class BaseNode
7
+ attr_accessor :children # array, can be empty
8
+ attr_accessor :parent # can be nil
9
+
10
+ def initialize
11
+ self.children = []
12
+ end
13
+
14
+ def add_child(child)
15
+ child.parent = self
16
+ children.append(child)
17
+ end
18
+
19
+ def children_to_sourcekit
20
+ children.sort.map(&:to_sourcekit)
21
+ end
22
+ end
23
+
24
+ # A SymNode is a node of the reconstructed syntax tree holding a symbol.
25
+ # It can turn itself into SourceKit and helps decode extensions.
26
+ class SymNode < BaseNode
27
+ attr_accessor :symbol
28
+ attr_writer :override
29
+ attr_writer :protocol_requirement
30
+ attr_writer :unlisted
31
+ attr_accessor :superclass_name
32
+
33
+ def override?
34
+ @override
35
+ end
36
+
37
+ def protocol_requirement?
38
+ @protocol_requirement
39
+ end
40
+
41
+ def top_level_decl?
42
+ !@unlisted && parent.nil?
43
+ end
44
+
45
+ def initialize(symbol)
46
+ self.symbol = symbol
47
+ super()
48
+ end
49
+
50
+ def qualified_name
51
+ symbol.path_components.join('.')
52
+ end
53
+
54
+ def parent_qualified_name
55
+ symbol.path_components[0...-1].join('.')
56
+ end
57
+
58
+ def protocol?
59
+ symbol.kind.end_with?('protocol')
60
+ end
61
+
62
+ def constraints
63
+ symbol.constraints
64
+ end
65
+
66
+ # Add another SymNode as a member if possible.
67
+ # It must go in an extension if either:
68
+ # - it has different generic constraints to us; or
69
+ # - we're a protocol and it's a default impl / ext method
70
+ def try_add_child(node, unique_context_constraints)
71
+ unless unique_context_constraints.empty? &&
72
+ (!protocol? || node.protocol_requirement?)
73
+ return false
74
+ end
75
+ add_child(node)
76
+ true
77
+ end
78
+
79
+ # The `Constraint`s on this decl that are both:
80
+ # 1. Unique, ie. not just inherited from its context; and
81
+ # 2. Constraining the *context's* gen params rather than our own.
82
+ def unique_context_constraints(context)
83
+ return symbol.constraints unless context
84
+
85
+ new_generic_type_params =
86
+ symbol.generic_type_params - context.symbol.generic_type_params
87
+
88
+ (symbol.constraints - context.symbol.constraints)
89
+ .select { |con| con.type_names.disjoint?(new_generic_type_params) }
90
+ end
91
+
92
+ # Messy check whether we need to fabricate an extension for a protocol
93
+ # conformance: don't bother if it's already in the type declaration.
94
+ def conformance?(protocol)
95
+ return false unless symbol.declaration =~ /(?<=:).*?(?=(where|$))/
96
+ Regexp.last_match[0] =~ /\b#{protocol}\b/
97
+ end
98
+
99
+ # Generate the 'where' clause for the declaration
100
+ def where_clause
101
+ parent_constraints = (parent && parent.constraints) || []
102
+ (constraints - parent_constraints).to_where_clause
103
+ end
104
+
105
+ def inherits_clause
106
+ return '' unless superclass_name
107
+ " : #{superclass_name}"
108
+ end
109
+
110
+ def full_declaration
111
+ symbol.availability
112
+ .append(symbol.declaration + inherits_clause + where_clause)
113
+ .join("\n")
114
+ end
115
+
116
+ # rubocop:disable Metrics/MethodLength
117
+ def to_sourcekit
118
+ declaration = full_declaration
119
+ xml_declaration = "<swift>#{CGI.escapeHTML(declaration)}</swift>"
120
+
121
+ hash = {
122
+ 'key.kind' => symbol.kind,
123
+ 'key.usr' => symbol.usr,
124
+ 'key.name' => symbol.name,
125
+ 'key.accessibility' => symbol.acl,
126
+ 'key.parsed_decl' => declaration,
127
+ 'key.annotated_decl' => xml_declaration,
128
+ }
129
+ if docs = symbol.doc_comments
130
+ hash['key.doc.comment'] = docs
131
+ hash['key.doc.full_as_xml'] = ''
132
+ end
133
+ if location = symbol.location
134
+ hash['key.filepath'] = location[:filename]
135
+ hash['key.doc.line'] = location[:line]
136
+ hash['key.doc.column'] = location[:character]
137
+ end
138
+ unless children.empty?
139
+ hash['key.substructure'] = children_to_sourcekit
140
+ end
141
+
142
+ hash
143
+ end
144
+ # rubocop:enable Metrics/MethodLength
145
+
146
+ # Sort order - by symbol
147
+ include Comparable
148
+
149
+ def <=>(other)
150
+ symbol <=> other.symbol
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,208 @@
1
+ # rubocop:disable Metrics/ClassLength
2
+ module Jazzy
3
+ module SymbolGraph
4
+ # A Symbol is a tidied-up SymbolGraph JSON object
5
+ class Symbol
6
+ attr_accessor :usr
7
+ attr_accessor :path_components
8
+ attr_accessor :declaration
9
+ attr_accessor :kind
10
+ attr_accessor :acl
11
+ attr_accessor :location # can be nil, keys :filename :line :character
12
+ attr_accessor :constraints # array, can be empty
13
+ attr_accessor :doc_comments # can be nil
14
+ attr_accessor :availability # array, can be empty
15
+ attr_accessor :generic_type_params # set, can be empty
16
+
17
+ def name
18
+ path_components[-1] || '??'
19
+ end
20
+
21
+ def initialize(hash)
22
+ self.usr = hash[:identifier][:precise]
23
+ self.path_components = hash[:pathComponents]
24
+ raw_decl = hash[:declarationFragments].map { |f| f[:spelling] }.join
25
+ init_kind(hash[:kind][:identifier])
26
+ init_declaration(raw_decl)
27
+ init_acl(hash[:accessLevel])
28
+ if location = hash[:location]
29
+ init_location(location)
30
+ end
31
+ init_constraints(hash, raw_decl)
32
+ if comments_hash = hash[:docComment]
33
+ init_doc_comments(comments_hash)
34
+ end
35
+ init_availability(hash[:availability] || [])
36
+ init_generic_type_params(hash)
37
+ end
38
+
39
+ # Repair problems with SymbolGraph's declprinter
40
+
41
+ def init_declaration(raw_decl)
42
+ # Too much 'Self.TypeName'; omitted arg labels look odd;
43
+ # duplicated constraints; swift 5.3 vs. master workaround
44
+ self.declaration =
45
+ raw_decl.gsub(/\bSelf\./, '')
46
+ .gsub(/(?<=\(|, )_: /, '_ arg: ')
47
+ .gsub(/ where.*$/, '')
48
+ if kind == 'source.lang.swift.decl.class'
49
+ declaration.sub!(/\s*:.*$/, '')
50
+ end
51
+ end
52
+
53
+ # Mapping SymbolGraph's declkinds to SourceKit
54
+
55
+ KIND_MAP = {
56
+ 'class' => 'class',
57
+ 'struct' => 'struct',
58
+ 'enum' => 'enum',
59
+ 'enum.case' => 'enumelement', # intentional
60
+ 'protocol' => 'protocol',
61
+ 'init' => 'function.constructor',
62
+ 'deinit' => 'function.destructor',
63
+ 'func.op' => 'function.operator',
64
+ 'type.method' => 'function.method.class',
65
+ 'static.method' => 'function.method.static',
66
+ 'method' => 'function.method.instance',
67
+ 'func' => 'function.free',
68
+ 'type.property' => 'var.class',
69
+ 'static.property' => 'var.static',
70
+ 'property' => 'var.instance',
71
+ 'var' => 'var.global',
72
+ 'subscript' => 'function.subscript',
73
+ 'type.subscript' => 'function.subscript',
74
+ 'static.subscript' => 'function.subscript',
75
+ 'typealias' => 'typealias',
76
+ 'associatedtype' => 'associatedtype',
77
+ }.freeze
78
+
79
+ # We treat 'static var' differently to 'class var'
80
+ def adjust_kind_for_declaration(kind)
81
+ return kind unless declaration =~ /\bstatic\b/
82
+ kind.gsub(/type/, 'static')
83
+ end
84
+
85
+ def init_kind(kind)
86
+ adjusted = adjust_kind_for_declaration(kind)
87
+ sourcekit_kind = KIND_MAP[adjusted.sub('swift.', '')]
88
+ raise "Unknown symbol kind '#{kind}'" unless sourcekit_kind
89
+ self.kind = 'source.lang.swift.decl.' + sourcekit_kind
90
+ end
91
+
92
+ # Mapping SymbolGraph's ACL to SourceKit
93
+
94
+ def init_acl(acl)
95
+ self.acl = 'source.lang.swift.accessibility.' + acl
96
+ end
97
+
98
+ # Symbol location - only available for public+ decls
99
+
100
+ def init_location(loc_hash)
101
+ self.location = {}
102
+ location[:filename] = loc_hash[:uri].sub(%r{^file://}, '')
103
+ location[:line] = loc_hash[:position][:line]
104
+ location[:character] = loc_hash[:position][:character]
105
+ end
106
+
107
+ # Generic constraints: in one or both of two places.
108
+ # There can be duplicates; these are removed by `Constraint`.
109
+ def init_constraints(hash, raw_decl)
110
+ raw_constraints = %i[swiftGenerics swiftExtension].flat_map do |key|
111
+ next [] unless container = hash[key]
112
+ container[:constraints] || []
113
+ end
114
+
115
+ constraints =
116
+ Constraint.new_list_for_symbol(raw_constraints, path_components)
117
+ if raw_decl =~ / where (.*)$/
118
+ constraints +=
119
+ Constraint.new_list_from_declaration(Regexp.last_match[1])
120
+ end
121
+
122
+ self.constraints = constraints.sort.uniq
123
+ end
124
+
125
+ # Generic type params
126
+ def init_generic_type_params(hash)
127
+ self.generic_type_params = Set.new(
128
+ if (generics = hash[:swiftGenerics]) &&
129
+ (parameters = generics[:parameters])
130
+ parameters.map { |p| p[:name] }
131
+ else
132
+ []
133
+ end,
134
+ )
135
+ end
136
+
137
+ def init_doc_comments(comments_hash)
138
+ self.doc_comments =
139
+ comments_hash[:lines].map { |l| l[:text] }
140
+ .join("\n")
141
+ end
142
+
143
+ # Availability
144
+ # Re-encode this as Swift. Should really teach Jazzy about these,
145
+ # could maybe then do something smarter here.
146
+ def init_availability(avail_hash_list)
147
+ self.availability = avail_hash_list.map do |avail|
148
+ str = '@available('
149
+ if avail[:isUnconditionallyDeprecated]
150
+ str += '*, deprecated'
151
+ elsif domain = avail[:domain]
152
+ str += domain
153
+ %i[introduced deprecated obsoleted].each do |event|
154
+ if version = avail[event]
155
+ str += ", #{event}: #{decode_version(version)}"
156
+ end
157
+ end
158
+ else
159
+ warn "Found confusing availability: #{avail}"
160
+ next nil
161
+ end
162
+
163
+ str += ', message: "' + avail[:message] + '"' if avail[:message]
164
+ str += ', renamed: "' + avail[:renamed] + '"' if avail[:renamed]
165
+
166
+ str + ')'
167
+ end.compact
168
+ end
169
+
170
+ def decode_version(hash)
171
+ str = hash[:major].to_s
172
+ str += ".#{hash[:minor]}" if hash[:minor]
173
+ str += ".#{hash[:patch]}" if hash[:patch]
174
+ str
175
+ end
176
+
177
+ # Sort order
178
+ include Comparable
179
+
180
+ # rubocop:disable Metrics/CyclomaticComplexity
181
+ # rubocop:disable Metrics/PerceivedComplexity
182
+ def <=>(other)
183
+ # Things with location: order by file/line/column
184
+ # (pls tell what wheel i am reinventing :/)
185
+ if location && other_loc = other.location
186
+ if location[:filename] == other_loc[:filename]
187
+ if location[:line] == other_loc[:line]
188
+ return location[:character] <=> other_loc[:character]
189
+ end
190
+ return location[:line] <=> other_loc[:line]
191
+ end
192
+ return location[:filename] <=> other_loc[:filename]
193
+ end
194
+
195
+ # Things with a location before things without a location
196
+ return +1 if location.nil? && other.location
197
+ return -1 if location && other.location.nil?
198
+
199
+ # Things without a location: by name and then USR
200
+ return usr <=> other.usr if name == other.name
201
+ name <=> other.name
202
+ end
203
+ # rubocop:enable Metrics/PerceivedComplexity
204
+ # rubocop:enable Metrics/CyclomaticComplexity
205
+ end
206
+ end
207
+ end
208
+ # rubocop:enable Metrics/ClassLength
@@ -18,7 +18,7 @@ $content_wrapper_width: 980px;
18
18
  $content_top_offset: 70px;
19
19
  $content_body_margin: 16px;
20
20
  $content_body_left_offset: $sidebar_width + $content_body_margin;
21
- $header_height: 26px;
21
+ $header_height: 32px;
22
22
  $breadcrumb_padding_top: 17px;
23
23
 
24
24
  $code_font: 0.95em Menlo, monospace;
@@ -104,12 +104,18 @@ p code, li code {
104
104
  padding: 2px 4px;
105
105
  border-radius: 4px;
106
106
  }
107
+ pre > code {
108
+ padding: 0;
109
+ }
107
110
 
108
111
  // Links
109
112
 
110
113
  a {
111
114
  color: $link_color;
112
115
  text-decoration: none;
116
+ code {
117
+ color: inherit;
118
+ }
113
119
  }
114
120
 
115
121
  // Lists
@@ -152,7 +158,7 @@ header {
152
158
  background-color: $bg_color;
153
159
  position: fixed;
154
160
  width: 100%;
155
- z-index: 2;
161
+ z-index: 3;
156
162
  img {
157
163
  padding-right: 6px;
158
164
  vertical-align: -4px;
@@ -309,6 +315,7 @@ header {
309
315
  }
310
316
 
311
317
  .task-group-section {
318
+ margin-top: 10px;
312
319
  padding-left: 6px;
313
320
  border-top: $gray_border;
314
321
  }
@@ -368,13 +375,15 @@ header {
368
375
  padding: 0;
369
376
  }
370
377
  .token, .direct-link {
378
+ display: inline-block;
379
+ text-indent: -20px;
371
380
  padding-left: 3px;
372
- margin-left: 15px;
381
+ margin-left: 35px;
373
382
  font-size: 11.9px;
374
383
  transition: all 300ms;
375
384
  }
376
385
  .token-open {
377
- margin-left: 0px;
386
+ margin-left: 20px;
378
387
  }
379
388
  .discouraged {
380
389
  text-decoration: line-through;
@@ -527,3 +536,69 @@ html.dash {
527
536
  position: static;
528
537
  }
529
538
  }
539
+
540
+ // ===========================================================================
541
+ //
542
+ // Search
543
+ //
544
+ // ===========================================================================
545
+ form[role=search] {
546
+ float: right;
547
+
548
+ input {
549
+ font: Helvetica, freesans, Arial, sans-serif;
550
+ margin-top: 6px;
551
+ font-size: 13px;
552
+ line-height: 20px;
553
+ padding: 0px 10px;
554
+ border: none;
555
+ border-radius: 1em;
556
+ .loading & {
557
+ background: white url(../img/spinner.gif) center right 4px no-repeat;
558
+ }
559
+ }
560
+
561
+ // Typeahead elements
562
+
563
+ .tt-menu {
564
+ margin: 0;
565
+ min-width: 300px;
566
+ background: $white_color;
567
+ color: #333;
568
+ border: $gray_border;
569
+ z-index: 4;
570
+ }
571
+
572
+ .tt-highlight {
573
+ font-weight: bold;
574
+ }
575
+
576
+ .tt-suggestion {
577
+ font: Helvetica, freesans, Arial, sans-serif;
578
+ font-size: 14px;
579
+ padding: 0 8px;
580
+ span {
581
+ display: table-cell;
582
+ white-space: nowrap;
583
+ }
584
+ .doc-parent-name {
585
+ width: 100%;
586
+ text-align: right;
587
+ font-weight: normal;
588
+ font-size: 0.9em;
589
+ padding-left: 16px;
590
+ }
591
+ }
592
+
593
+ .tt-suggestion:hover,
594
+ .tt-suggestion.tt-cursor {
595
+ cursor: pointer;
596
+ background-color: #4183c4;
597
+ color: #fff;
598
+ }
599
+
600
+ .tt-suggestion:hover .doc-parent-name,
601
+ .tt-suggestion.tt-cursor .doc-parent-name {
602
+ color: #fff;
603
+ }
604
+ }