yard 0.9.36 → 0.9.38

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/README.md +17 -10
  4. data/docs/Templates.md +5 -4
  5. data/lib/yard/autoload.rb +1 -0
  6. data/lib/yard/code_objects/base.rb +1 -1
  7. data/lib/yard/code_objects/extra_file_object.rb +1 -0
  8. data/lib/yard/code_objects/macro_object.rb +0 -1
  9. data/lib/yard/docstring_parser.rb +0 -1
  10. data/lib/yard/handlers/base.rb +23 -1
  11. data/lib/yard/handlers/processor.rb +0 -1
  12. data/lib/yard/handlers/ruby/constant_handler.rb +23 -6
  13. data/lib/yard/handlers/ruby/legacy/visibility_handler.rb +2 -1
  14. data/lib/yard/handlers/ruby/visibility_handler.rb +14 -1
  15. data/lib/yard/logging.rb +116 -61
  16. data/lib/yard/open_struct.rb +67 -0
  17. data/lib/yard/parser/ruby/ast_node.rb +5 -4
  18. data/lib/yard/parser/ruby/legacy/ruby_lex.rb +20 -5
  19. data/lib/yard/parser/ruby/ruby_parser.rb +54 -21
  20. data/lib/yard/parser/source_parser.rb +2 -2
  21. data/lib/yard/tags/default_factory.rb +1 -0
  22. data/lib/yard/tags/directives.rb +0 -1
  23. data/lib/yard/tags/overload_tag.rb +2 -1
  24. data/lib/yard/tags/tag.rb +2 -1
  25. data/lib/yard/tags/types_explainer.rb +3 -3
  26. data/lib/yard/templates/engine.rb +0 -1
  27. data/lib/yard/templates/helpers/html_helper.rb +5 -1
  28. data/lib/yard/templates/helpers/markup/rdoc_markup.rb +2 -0
  29. data/lib/yard/templates/template_options.rb +0 -1
  30. data/lib/yard/version.rb +1 -1
  31. data/templates/default/fulldoc/html/css/full_list.css +3 -3
  32. data/templates/default/fulldoc/html/css/style.css +8 -15
  33. data/templates/default/fulldoc/html/full_list.erb +5 -2
  34. data/templates/default/fulldoc/html/js/app.js +348 -267
  35. data/templates/default/fulldoc/html/js/full_list.js +52 -24
  36. data/templates/default/fulldoc/html/setup.rb +10 -2
  37. data/templates/default/onefile/html/headers.erb +2 -0
  38. data/templates/default/tags/html/example.erb +2 -2
  39. metadata +7 -6
@@ -271,7 +271,7 @@ module YARD
271
271
 
272
272
  # @return [Fixnum] the starting line number of the node
273
273
  def line
274
- line_range && line_range.first
274
+ line_range && (line_range.begin || line_range.end)
275
275
  end
276
276
 
277
277
  # @return [String] the first line of source represented by the node.
@@ -345,8 +345,8 @@ module YARD
345
345
  elsif !children.empty?
346
346
  f = children.first
347
347
  l = children.last
348
- self.line_range = Range.new(f.line_range.first, l.line_range.last)
349
- self.source_range = Range.new(f.source_range.first, l.source_range.last)
348
+ self.line_range = Range.new(f.line_range.begin, l.line_range.end)
349
+ self.source_range = Range.new(f.source_range.begin, l.source_range.end)
350
350
  elsif @fallback_line || @fallback_source
351
351
  self.line_range = @fallback_line
352
352
  self.source_range = @fallback_source
@@ -431,7 +431,8 @@ module YARD
431
431
  # shape is (required, optional, rest, more, keyword, keyword_rest, block)
432
432
  # Ruby 3.1 moves :args_forward from rest to keyword_rest
433
433
  args_index = YARD.ruby31? ? -2 : 2
434
- self[args_index].type == :args_forward if self[args_index]
434
+ node = self[args_index]
435
+ node.is_a?(AstNode) && node.type == :args_forward
435
436
  end
436
437
  end
437
438
 
@@ -656,7 +656,7 @@ module YARD
656
656
  if @lex_state != EXPR_END && @lex_state != EXPR_CLASS &&
657
657
  (@lex_state != EXPR_ARG || @space_seen)
658
658
  c = peek(0)
659
- tk = identify_here_document if /[-\w\"\'\`]/ =~ c
659
+ tk = identify_here_document if /[-~\w\"\'\`]/ =~ c
660
660
  end
661
661
  if !tk
662
662
  @lex_state = EXPR_BEG
@@ -978,7 +978,7 @@ module YARD
978
978
  end
979
979
 
980
980
  def identify_identifier
981
- token = ""
981
+ token = String.new
982
982
  token.concat getc if peek(0) =~ /[$@]/
983
983
  token.concat getc if peek(0) == "@"
984
984
 
@@ -1063,6 +1063,8 @@ module YARD
1063
1063
  ch = getc
1064
1064
  if ch == "-"
1065
1065
  ch = getc
1066
+ elsif ch == "~"
1067
+ ch = getc
1066
1068
  indent = true
1067
1069
  end
1068
1070
  if /['"`]/ =~ ch # '
@@ -1096,9 +1098,12 @@ module YARD
1096
1098
  str = String.new
1097
1099
  while (l = gets)
1098
1100
  l.chomp!
1099
- l.strip! if indent
1100
- break if l == quoted
1101
- str << l.chomp << "\n"
1101
+ if l == quoted
1102
+ str = dedent(str) if indent
1103
+ break
1104
+ else
1105
+ str << l.chomp << "\n"
1106
+ end
1102
1107
  end
1103
1108
 
1104
1109
  @reader.divert_read_from(reserve)
@@ -1108,6 +1113,16 @@ module YARD
1108
1113
  Token(Ltype2Token[lt], str).set_text(str.dump)
1109
1114
  end
1110
1115
 
1116
+ def dedent(str)
1117
+ lines = str.split("\n", -1)
1118
+ dedent_amt = lines.map do |line|
1119
+ line =~ /\S/ ? line.match(/^ */).offset(0)[1] : nil
1120
+ end.compact.min || 0
1121
+ return str if dedent_amt.zero?
1122
+
1123
+ lines.map { |line| line =~ /\S/ ? line.gsub(/^ {#{dedent_amt}}/, "") : line }.join("\n")
1124
+ end
1125
+
1111
1126
  def identify_quotation(initial_char)
1112
1127
  ch = getc
1113
1128
  if lt = PERCENT_LTYPE[ch]
@@ -236,14 +236,25 @@ module YARD
236
236
 
237
237
  def visit_event(node)
238
238
  map = @map[MAPPINGS[node.type]]
239
- lstart, sstart = *(map ? map.pop : [lineno, @ns_charno - 1])
239
+
240
+ # Pattern matching and `in` syntax creates :case nodes without 'case' tokens,
241
+ # fall back to the first child node.
242
+ if node.type == :case && (!map || map.empty?) && (child_node = node[0])
243
+ lstart = child_node.line_range.first
244
+ sstart = child_node.source_range.first
245
+ else
246
+ lstart, sstart = *(map ? map.pop : [lineno, @ns_charno - 1])
247
+ end
248
+
249
+ raise "Cannot determine start of node #{node} around #{file}:#{lineno}" if lstart.nil? || sstart.nil?
250
+
240
251
  node.source_range = Range.new(sstart, @ns_charno - 1)
241
252
  node.line_range = Range.new(lstart, lineno)
242
253
  if node.respond_to?(:block)
243
254
  sr = node.block.source_range
244
255
  lr = node.block.line_range
245
- node.block.source_range = Range.new(sr.first, @tokens.last[2][1] - 1)
246
- node.block.line_range = Range.new(lr.first, @tokens.last[2][0])
256
+ node.block.source_range = Range.new(sr.begin, @tokens.last[2][1] - 1)
257
+ node.block.line_range = Range.new(lr.begin, @tokens.last[2][0])
247
258
  end
248
259
  node
249
260
  end
@@ -259,7 +270,10 @@ module YARD
259
270
  def visit_ns_token(token, data, ast_token = false)
260
271
  add_token(token, data)
261
272
  ch = charno
262
- @last_ns_token = [token, data]
273
+
274
+ # For purposes of tracking parsing state, don't treat keywords as such
275
+ # where used as a symbol identifier.
276
+ @last_ns_token = [@last_ns_token && @last_ns_token.first == :symbeg ? :symbol : token, data]
263
277
  @charno += data.length
264
278
  @ns_charno = charno
265
279
  @newline = [:semicolon, :comment, :kw, :op, :lparen, :lbrace].include?(token)
@@ -272,14 +286,14 @@ module YARD
272
286
  if @percent_ary
273
287
  if token == :words_sep && data !~ /\s\z/
274
288
  rng = @percent_ary.source_range
275
- rng = Range.new(rng.first, rng.last + data.length)
289
+ rng = Range.new(rng.begin, rng.end.to_i + data.length)
276
290
  @percent_ary.source_range = rng
277
291
  @tokens << [token, data, [lineno, charno]]
278
292
  @percent_ary = nil
279
293
  return
280
294
  elsif token == :tstring_end && data =~ /\A\s/
281
295
  rng = @percent_ary.source_range
282
- rng = Range.new(rng.first, rng.last + data.length)
296
+ rng = Range.new(rng.begin, rng.end.to_i + data.length)
283
297
  @percent_ary.source_range = rng
284
298
  @tokens << [token, data, [lineno, charno]]
285
299
  @percent_ary = nil
@@ -377,8 +391,8 @@ module YARD
377
391
  def on_aref(*args)
378
392
  @map[:lbracket].pop
379
393
  ll, lc = *@map[:aref].shift
380
- sr = args.first.source_range.first..lc
381
- lr = args.first.line_range.first..ll
394
+ sr = args.first.source_range.begin..lc
395
+ lr = args.first.line_range.begin..ll
382
396
  AstNode.new(:aref, args, :char => sr, :line => lr)
383
397
  end
384
398
 
@@ -390,7 +404,7 @@ module YARD
390
404
 
391
405
  def on_array(other)
392
406
  node = AstNode.node_class_for(:array).new(:array, [other])
393
- map = @map[MAPPINGS[node.type]]
407
+ map = @map[MAPPINGS[node.type]] if other.nil? || other.type == :list
394
408
  if map && !map.empty?
395
409
  lstart, sstart = *map.pop
396
410
  node.source_range = Range.new(sstart, @ns_charno - 1)
@@ -449,8 +463,8 @@ module YARD
449
463
  def on_#{kw}(*args)
450
464
  mapping = @map[#{kw.to_s.sub(/_mod$/, '').inspect}]
451
465
  mapping.pop if mapping
452
- sr = args.last.source_range.first..args.first.source_range.last
453
- lr = args.last.line_range.first..args.first.line_range.last
466
+ sr = args.last.source_range.begin..args.first.source_range.end
467
+ lr = args.last.line_range.begin..args.first.line_range.end
454
468
  #{node_class}.new(:#{kw}, args, :line => lr, :char => sr)
455
469
  end
456
470
  eof
@@ -473,8 +487,8 @@ module YARD
473
487
  begin; undef on_#{kw}_add; rescue NameError; end
474
488
  def on_#{kw}_add(list, item)
475
489
  last = @source[@ns_charno,1] == "\n" ? @ns_charno - 1 : @ns_charno
476
- list.source_range = (list.source_range.first..last)
477
- list.line_range = (list.line_range.first..lineno)
490
+ list.source_range = (list.source_range.begin..last)
491
+ list.line_range = (list.line_range.begin..lineno)
478
492
  list.push(item)
479
493
  list
480
494
  end
@@ -485,9 +499,9 @@ module YARD
485
499
  node = visit_event_arr(LiteralNode.new(:string_literal, args))
486
500
  if args.size == 1
487
501
  r = args[0].source_range
488
- if node.source_range != Range.new(r.first - 1, r.last + 1)
502
+ if node.source_range != Range.new(r.begin - 1, r.end + 1)
489
503
  klass = AstNode.node_class_for(node[0].type)
490
- r = Range.new(node.source_range.first + 1, node.source_range.last - 1)
504
+ r = Range.new(node.source_range.begin + 1, node.source_range.end - 1)
491
505
  node[0] = klass.new(node[0].type, [@source[r]], :line => node.line_range, :char => r)
492
506
  end
493
507
  end
@@ -573,7 +587,7 @@ module YARD
573
587
  @comments_flags[lineno] = @comments_flags[lineno - 1]
574
588
  @comments_flags.delete(lineno - 1)
575
589
  range = @comments_range.delete(lineno - 1)
576
- source_range = range.first..source_range.last
590
+ source_range = range.begin..source_range.end
577
591
  comment = append_comment + "\n" + comment
578
592
  end
579
593
 
@@ -627,11 +641,13 @@ module YARD
627
641
  end
628
642
 
629
643
  # check upwards from line before node; check node's line at the end
630
- ((node.line - 1).downto(node.line - 2).to_a + [node.line]).each do |line|
631
- comment = @comments[line]
632
- if comment && !comment.empty?
633
- add_comment(line, node)
634
- break
644
+ if (n_l = node.line)
645
+ ((n_l - 1).downto(n_l - 2).to_a + [n_l]).each do |line|
646
+ comment = @comments[line]
647
+ if comment && !comment.empty?
648
+ add_comment(line, node)
649
+ break
650
+ end
635
651
  end
636
652
  end
637
653
 
@@ -656,6 +672,23 @@ module YARD
656
672
  end
657
673
  end unless @comments.empty?
658
674
 
675
+ # Attach comments that fall within an otherwise empty
676
+ # class or module body. Without this step, a comment used
677
+ # solely for directives (like @!method) would be treated as
678
+ # a top-level comment and its directives would not be scoped
679
+ # to the namespace.
680
+ unless @comments.empty?
681
+ root.traverse do |node|
682
+ next unless [:class, :module, :sclass].include?(node.type)
683
+ body = node.children.last
684
+ next unless body && body.type == :list && body.empty?
685
+ @comments.keys.each do |line|
686
+ next unless node.line_range.include?(line)
687
+ add_comment(line, nil, body, true)
688
+ end
689
+ end
690
+ end
691
+
659
692
  # insert all remaining comments
660
693
  @comments.each do |line, _comment|
661
694
  add_comment(line, nil, root, true)
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  require 'stringio'
3
- require 'ostruct'
4
3
 
5
4
  module YARD
6
5
  module Parser
@@ -108,7 +107,8 @@ module YARD
108
107
  files = [paths].flatten.
109
108
  map {|p| File.directory?(p) ? "#{p}/**/*.{rb,c,cc,cxx,cpp}" : p }.
110
109
  map {|p| p.include?("*") ? Dir[p].sort_by {|d| [d.length, d] } : p }.flatten.
111
- reject {|p| !File.file?(p) || excluded.any? {|re| p =~ re } }
110
+ reject {|p| !File.file?(p) || excluded.any? {|re| p =~ re } }.
111
+ map {|p| p.encoding == Encoding.default_external ? p : p.dup.force_encoding(Encoding.default_external) }
112
112
 
113
113
  log.enter_level(level) do
114
114
  parse_in_order(*files.uniq)
@@ -143,6 +143,7 @@ module YARD
143
143
  seen_space = false
144
144
  i = 0
145
145
  last_seen = ''
146
+ text ||= ''
146
147
  while i < text.length
147
148
  c = text[i, 1]
148
149
 
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'ostruct'
3
2
 
4
3
  module YARD
5
4
  module Tags
@@ -60,7 +60,8 @@ module YARD
60
60
  args = YARD::Handlers::Ruby::Legacy::Base.new(nil, nil).send(:tokval_list, toks, :all)
61
61
  args = args.map do |a|
62
62
  k, v = *a.split(/:|=/, 2)
63
- [k.strip.to_s + (a[k.size, 1] == ':' ? ':' : ''), (v ? v.strip : nil)]
63
+ v.strip! if v
64
+ [k.strip.to_s + (a[k.size, 1] == ':' ? ':' : ''), (v && v.empty? ? nil : v)]
64
65
  end if args
65
66
  @name = meth.to_sym
66
67
  @parameters = args
data/lib/yard/tags/tag.rb CHANGED
@@ -23,6 +23,7 @@ module YARD
23
23
  attr_accessor :types
24
24
 
25
25
  # @return [String] a name associated with the tag
26
+ # @return [nil] if no tag name is supplied
26
27
  attr_accessor :name
27
28
 
28
29
  # @return [CodeObjects::Base] the associated object
@@ -37,7 +38,7 @@ module YARD
37
38
  # +raise+, etc.
38
39
  #
39
40
  # @param [#to_s] tag_name the tag name to create the tag for
40
- # @param [String] text the descriptive text for this tag
41
+ # @param [String, nil] text the descriptive text for this tag, or nil if none provided
41
42
  # @param [Array<String>] types optional type list of formally declared types
42
43
  # for the tag
43
44
  # @param [String] name optional key name which the tag refers to
@@ -32,7 +32,7 @@ module YARD
32
32
 
33
33
  def to_s(singular = true)
34
34
  if name[0, 1] == "#"
35
- singular ? "an object that responds to #{name}" : "objects that respond to #{name}"
35
+ (singular ? "an object that responds to " : "objects that respond to ") + list_join(name.split(/ *& */), with: "and")
36
36
  elsif name[0, 1] =~ /[A-Z]/
37
37
  singular ? "a#{name[0, 1] =~ /[aeiou]/i ? 'n' : ''} " + name : "#{name}#{name[-1, 1] =~ /[A-Z]/ ? "'" : ''}s"
38
38
  else
@@ -42,12 +42,12 @@ module YARD
42
42
 
43
43
  private
44
44
 
45
- def list_join(list)
45
+ def list_join(list, with: "or")
46
46
  index = 0
47
47
  list.inject(String.new) do |acc, el|
48
48
  acc << el.to_s
49
49
  acc << ", " if index < list.size - 2
50
- acc << " or " if index == list.size - 2
50
+ acc << " #{with} " if index == list.size - 2
51
51
  index += 1
52
52
  acc
53
53
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'ostruct'
3
2
 
4
3
  module YARD
5
4
  module Templates
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
- require 'cgi'
2
+ if RUBY_VERSION < '3.5'
3
+ require 'cgi/util'
4
+ else
5
+ require 'cgi/escape'
6
+ end
3
7
 
4
8
  module YARD
5
9
  module Templates::Helpers
@@ -38,6 +38,7 @@ module YARD
38
38
  @@formatter = nil
39
39
  @@markup = nil
40
40
 
41
+ # @param text [String]
41
42
  def initialize(text)
42
43
  @text = text
43
44
 
@@ -47,6 +48,7 @@ module YARD
47
48
  end
48
49
  end
49
50
 
51
+ # @return [String]
50
52
  def to_html
51
53
  html = nil
52
54
  @@mutex.synchronize do
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require 'ostruct'
3
2
 
4
3
  module YARD
5
4
  module Templates
data/lib/yard/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module YARD
5
- VERSION = '0.9.36'
5
+ VERSION = '0.9.38'
6
6
  end
@@ -20,8 +20,8 @@ h1 { padding: 12px 10px; padding-bottom: 0; margin: 0; font-size: 1.4em; }
20
20
  #content.insearch #noresults { margin-left: 7px; }
21
21
  li.collapsed ul { display: none; }
22
22
  li a.toggle { cursor: default; position: relative; left: -5px; top: 4px; text-indent: -999px; width: 10px; height: 9px; margin-left: -10px; display: block; float: left; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK8AAACvABQqw0mAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTM5jWRgMAAAAVdEVYdENyZWF0aW9uIFRpbWUAMy8xNC8wOeNZPpQAAAE2SURBVDiNrZTBccIwEEXfelIAHUA6CZ24BGaWO+FuzZAK4k6gg5QAdGAq+Bxs2Yqx7BzyL7Llp/VfzZeQhCTc/ezuGzKKnKSzpCxXJM8fwNXda3df5RZETlIt6YUzSQDs93sl8w3wBZxCCE10GM1OcWbWjB2mWgEH4Mfdyxm3PSepBHibgQE2wLe7r4HjEidpnXMYdQPKEMJcsZ4zs2POYQOcaPfwMVOo58zsAdMt18BuoVDPxUJRacELbXv3hUIX2vYmOUvi8C8ydz/ThjXrqKqqLbDIAdsCKBd+Wo7GWa7o9qzOQHVVVXeAbs+yHHCH4aTsaCOQqunmUy1yBUAXkdMIfMlgF5EXLo2OpV/c/Up7jG4hhHcYLgWzAZXUc2b2ixsfvc/RmNNfOXD3Q/oeL9axJE1yT9IOoUu6MGUkAAAAAElFTkSuQmCC) no-repeat bottom left; }
23
- li.collapsed a.toggle { opacity: 0.5; cursor: default; background-position: top left; }
24
- li { color: #888; cursor: pointer; }
23
+ li.collapsed a.toggle { cursor: default; background-position: top left; }
24
+ li { color: #666; cursor: pointer; }
25
25
  li.deprecated { text-decoration: line-through; font-style: italic; }
26
26
  li.odd { background: #f0f0f0; }
27
27
  li.even { background: #fafafa; }
@@ -47,7 +47,7 @@ li small { display: block; font-size: 0.8em; }
47
47
  li small:before { content: ""; }
48
48
  li small:after { content: ""; }
49
49
  li small.search_info { display: none; }
50
- #search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #888; padding-left: 0; padding-right: 24px; }
50
+ #search { width: 170px; position: static; margin: 3px; margin-left: 10px; font-size: 0.9em; color: #666; padding-left: 0; padding-right: 24px; }
51
51
  #content.insearch #search { background-position: center right; }
52
52
  #search input { width: 110px; }
53
53
 
@@ -9,8 +9,6 @@ body {
9
9
  margin: 0;
10
10
  padding: 0;
11
11
  display: flex;
12
- display: -webkit-flex;
13
- display: -ms-flexbox;
14
12
  }
15
13
 
16
14
  #nav {
@@ -28,11 +26,7 @@ body {
28
26
  height: 100%;
29
27
  position: relative;
30
28
  display: flex;
31
- display: -webkit-flex;
32
- display: -ms-flexbox;
33
29
  flex-shrink: 0;
34
- -webkit-flex-shrink: 0;
35
- -ms-flex: 1 0;
36
30
  }
37
31
  #resizer {
38
32
  position: absolute;
@@ -45,8 +39,6 @@ body {
45
39
  }
46
40
  #main {
47
41
  flex: 5 1;
48
- -webkit-flex: 5 1;
49
- -ms-flex: 5 1;
50
42
  outline: none;
51
43
  position: relative;
52
44
  background: #fff;
@@ -56,7 +48,8 @@ body {
56
48
  }
57
49
 
58
50
  @media (max-width: 920px) {
59
- .nav_wrap { width: 100%; top: 0; right: 0; overflow: visible; position: absolute; }
51
+ body { display: block; }
52
+ .nav_wrap { width: 80vw !important; top: 0; right: 0; overflow: visible; position: absolute; }
60
53
  #resizer { display: none; }
61
54
  #nav {
62
55
  z-index: 9999;
@@ -82,6 +75,11 @@ body {
82
75
  #search { display: none; }
83
76
  }
84
77
 
78
+ @media (max-width: 320px) {
79
+ body { height: 100%; overflow: hidden; overflow-wrap: break-word; }
80
+ #main { height: 100%; overflow: auto; }
81
+ }
82
+
85
83
  #main img { max-width: 100%; }
86
84
  h1 { font-size: 25px; margin: 1em 0 0.5em; padding-top: 4px; border-top: 1px dotted #d5d5d5; }
87
85
  h1.noborder { border-top: 0px; margin-top: 0; padding-top: 4px; }
@@ -106,6 +104,7 @@ h2 small a {
106
104
  position: relative;
107
105
  padding: 2px 7px;
108
106
  }
107
+ a { font-weight: 550; }
109
108
  .clear { clear: both; }
110
109
  .inline { display: inline; }
111
110
  .inline p:first-child { display: inline; }
@@ -199,13 +198,9 @@ p.inherited {
199
198
  width: 100%;
200
199
  font-size: 1em;
201
200
  display: flex;
202
- display: -webkit-flex;
203
- display: -ms-flexbox;
204
201
  }
205
202
  .box_info dl dt {
206
203
  flex-shrink: 0;
207
- -webkit-flex-shrink: 1;
208
- -ms-flex-shrink: 1;
209
204
  width: 100px;
210
205
  text-align: right;
211
206
  font-weight: bold;
@@ -216,8 +211,6 @@ p.inherited {
216
211
  }
217
212
  .box_info dl dd {
218
213
  flex-grow: 1;
219
- -webkit-flex-grow: 1;
220
- -ms-flex: 1;
221
214
  max-width: 420px;
222
215
  padding: 6px 0;
223
216
  padding-right: 20px;
@@ -1,5 +1,5 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html <%= "lang=\"#{html_lang}\"" unless html_lang.nil? %>>
3
3
  <head>
4
4
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
5
  <meta charset="<%= charset %>" />
@@ -26,7 +26,10 @@
26
26
  <% end %>
27
27
  </div>
28
28
 
29
- <div id="search">Search: <input type="text" /></div>
29
+ <div id="search">
30
+ <label for="search-class">Search:</label>
31
+ <input id="search-class" type="text" />
32
+ </div>
30
33
  </div>
31
34
 
32
35
  <ul id="full_list" class="<%= @list_class || @list_type %>">