| @@ -1,6 +1,18 @@ |
| 1 | 1 | module Docs |
| 2 | 2 | class Css |
| 3 | 3 | class EntriesFilter < Docs::EntriesFilter |
| 4 | + TYPE_BY_PATH = { |
| 5 | + 'CSS_Animations' => 'Animations & Transitions', |
| 6 | + 'CSS_Background_and_Borders' => 'Backgrounds & Borders', |
| 7 | + 'CSS_Columns' => 'Multi-column Layout', |
| 8 | + 'CSS_Flexible_Box_Layout' => 'Flexible Box Layout', |
| 9 | + 'CSS_Images' => 'Image Values', |
| 10 | + 'CSS_Lists_and_Counters' => 'Lists & Counters', |
| 11 | + 'CSS_Transforms' => 'Transforms', |
| 12 | + 'Media_Queries' => 'Media Queries', |
| 13 | + 'transform-function' => 'Transforms' |
| 14 | + } |
| 15 | + |
| 4 | 16 | DATA_TYPE_SLUGS = %w(angle basic-shape color_value counter frequency |
| 5 | 17 | gradient image integer length number percentage position_value ratio |
| 6 | 18 | resolution shape string time timing-function uri user-ident) |
| @@ -9,84 +21,95 @@ module Docs · 2 unmodified lines |
| 9 | 21 | linear-gradient radial-gradient repeating-linear-gradient |
| 10 | 22 | repeating-radial-gradient var) |
| 11 | 23 | |
| 12 | | − VALUE_SLUGS = %w(auto inherit initial none normal unset) |
| 13 | | − |
| 14 | | − ADDITIONAL_ENTRIES = { |
| 15 | | − 'shape' => [ |
| 16 | | − %w(rect() Syntax Functions) ], |
| 17 | | − 'uri' => [ |
| 18 | | − %w(url() The_url()_functional_notation Functions) ], |
| 19 | | − 'timing-function' => [ |
| 20 | | − %w(cubic-bezier() The_cubic-bezier()_class_of_timing-functions Functions), |
| 21 | | − %w(steps() The_steps()_class_of_timing-functions Functions), |
| 22 | | − %w(linear linear Values), |
| 23 | | − %w(ease ease Values), |
| 24 | | − %w(ease-in ease-in Values), |
| 25 | | − %w(ease-in-out ease-in-out Values), |
| 26 | | − %w(ease-out ease-out Values), |
| 27 | | − %w(step-start step-start Values), |
| 28 | | − %w(step-end step-end Values) ], |
| 29 | | − 'color_value' => [ |
| 30 | | − %w(transparent transparent_keyword Values), |
| 31 | | − %w(currentColor currentColor_keyword Values), |
| 32 | | − %w(rgb() rgb() Functions), |
| 33 | | − %w(hsl() hsl() Functions), |
| 34 | | − %w(rgba() rgba() Functions), |
| 35 | | − %w(hsla() hsla() Functions) ], |
| 36 | | − 'transform-function' => [ |
| 37 | | − %w(matrix() matrix() Functions), |
| 38 | | − %w(matrix3d() matrix3d() Functions), |
| 39 | | − %w(perspective() perspective() Functions), |
| 40 | | − %w(rotate() rotate() Functions), |
| 41 | | − %w(rotate3d() rotate3d() Functions), |
| 42 | | − %w(rotateX() rotateX() Functions), |
| 43 | | − %w(rotateY() rotateY() Functions), |
| 44 | | − %w(rotateZ() rotateZ() Functions), |
| 45 | | − %w(scale() scale() Functions), |
| 46 | | − %w(scale3d() scale3d() Functions), |
| 47 | | − %w(scaleX() scaleX() Functions), |
| 48 | | − %w(scaleY() scaleY() Functions), |
| 49 | | − %w(scaleZ() scaleZ() Functions), |
| 50 | | − %w(skew() skew() Functions), |
| 51 | | − %w(skewX() skewX() Functions), |
| 52 | | − %w(skewY() skewY() Functions), |
| 53 | | − %w(translate() translate() Functions), |
| 54 | | − %w(translate3d() translate3d() Functions), |
| 55 | | − %w(translateX() translateX() Functions), |
| 56 | | − %w(translateY() translateY() Functions), |
| 57 | | − %w(translateZ() translate(Z) Functions) ]} |
| 58 | | − |
| 59 | 24 | def get_name |
| 60 | | − case type |
| 61 | | − when 'Data Types' then "<#{super.remove ' value'}>" |
| 62 | | − when 'Functions' then "#{super}()" |
| 63 | | − when 'Miscellaneous' then slug.to_s.gsub('_', ' ').gsub('/', ': ') |
| 64 | | − else super |
| 25 | + if DATA_TYPE_SLUGS.include?(slug) |
| 26 | + "<#{super.remove ' value'}>" |
| 27 | + elsif FUNCTION_SLUGS.include?(slug) |
| 28 | + "#{super}()" |
| 29 | + elsif slug =~ /\A[a-z]+_/i |
| 30 | + slug.to_s.gsub('_', ' ').gsub('/', ': ') |
| 31 | + elsif slug.start_with?('transform-function') |
| 32 | + slug.split('/').last + '()' |
| 33 | + else |
| 34 | + super |
| 65 | 35 | end |
| 66 | 36 | end |
| 67 | 37 | |
| 68 | 38 | def get_type |
| 69 | | − if slug.end_with?('selectors') |
| 70 | | − 'Selectors' |
| 71 | | − elsif slug.start_with?('::') |
| 72 | | − 'Pseudo-elements' |
| 73 | | − elsif slug.start_with?(':') |
| 74 | | − 'Pseudo-classes' |
| 75 | | − elsif slug.start_with?('@') |
| 76 | | − 'At-rules' |
| 77 | | − elsif DATA_TYPE_SLUGS.include?(slug) |
| 78 | | − 'Data Types' |
| 79 | | − elsif FUNCTION_SLUGS.include?(slug) |
| 80 | | − 'Functions' |
| 81 | | − elsif VALUE_SLUGS.include?(slug) |
| 82 | | − 'Values' |
| 83 | | − elsif slug =~ /\A[a-z]+_/i |
| 84 | | − 'Miscellaneous' |
| 39 | + if type = get_spec |
| 40 | + type.remove! 'CSS ' |
| 41 | + type.remove! ' Module' |
| 42 | + type.remove! %r{ Level \d\z} |
| 43 | + type.remove! %r{\(.*\)} |
| 44 | + type.sub! 'and', '&' |
| 45 | + type.strip! |
| 46 | + type = 'Animations & Transitions' if type.in?(%w(Animations Transitions)) |
| 47 | + type = 'Image Values' if type == 'Image Values & Replaced Content' |
| 48 | + type = 'Variables' if type == 'Custom Properties for Cascading Variables' |
| 49 | + type.prepend 'Miscellaneous ' if type =~ /\ALevel \d\z/ |
| 50 | + type |
| 51 | + elsif type = TYPE_BY_PATH[slug.split('/').first] |
| 52 | + type |
| 85 | 53 | else |
| 86 | | − 'Properties' |
| 54 | + 'Miscellaneous' |
| 87 | 55 | end |
| 88 | 56 | end |
| 89 | 57 | |
| 58 | + STATUSES = { |
| 59 | + 'spec-Living' => 0, |
| 60 | + 'spec-REC' => 1, |
| 61 | + 'spec-CR' => 2, |
| 62 | + 'spec-LC' => 3, |
| 63 | + 'spec-WD' => 4, |
| 64 | + 'spec-ED' => 5 |
| 65 | + } |
| 66 | + |
| 67 | + PRIORITY_STATUSES = %w(spec-REC spec-CR) |
| 68 | + PRIORITY_SPECS = ['CSS Basic Box Model', 'CSS Lists and Counters', 'CSS Paged Media'] |
| 69 | + |
| 70 | + def get_spec |
| 71 | + return unless table = at_css('#Specifications + table') || css('.standard-table').last |
| 72 | + specs = table.css('tbody tr').to_a |
| 73 | + # [link, span] |
| 74 | + specs.map! { |node| [node.at_css('> td:nth-child(1) > a'), node.at_css('> td:nth-child(2) > span')] } |
| 75 | + # ignore non-CSS specs |
| 76 | + specs.select! { |pair| pair.first && pair.first['href'] =~ /css|fxtf|fullscreen|svg/i && !pair.first['href'].include?('compat.spec') } |
| 77 | + # ["Spec", "spec-REC"] |
| 78 | + specs.map! { |pair| [pair.first.child.content, pair.second['class']] } |
| 79 | + # sort by status |
| 80 | + specs.sort_by! { |pair| [STATUSES[pair.second], pair.first] } |
| 81 | + |
| 82 | + spec = specs.find { |pair| PRIORITY_SPECS.any? { |s| pair.first.start_with?(s) } && name != 'display' } |
| 83 | + spec ||= specs.find { |pair| !pair.first.start_with?('CSS Level') && pair.second.in?(PRIORITY_STATUSES) } |
| 84 | + spec ||= specs.find { |pair| pair.second == 'spec-WD' } if specs.count { |pair| pair.second == 'spec-WD' } == 1 |
| 85 | + spec ||= specs.first |
| 86 | + |
| 87 | + spec.try(:first) |
| 88 | + end |
| 89 | + |
| 90 | + ADDITIONAL_ENTRIES = { |
| 91 | + 'shape' => [ |
| 92 | + %w(rect() Syntax) ], |
| 93 | + 'uri' => [ |
| 94 | + %w(url() The_url()_functional_notation) ], |
| 95 | + 'timing-function' => [ |
| 96 | + %w(cubic-bezier() The_cubic-bezier()_class_of_timing-functions), |
| 97 | + %w(steps() The_steps()_class_of_timing-functions), |
| 98 | + %w(linear linear), |
| 99 | + %w(ease ease), |
| 100 | + %w(ease-in ease-in), |
| 101 | + %w(ease-in-out ease-in-out), |
| 102 | + %w(ease-out ease-out), |
| 103 | + %w(step-start step-start), |
| 104 | + %w(step-end step-end) ], |
| 105 | + 'color_value' => [ |
| 106 | + %w(transparent transparent_keyword), |
| 107 | + %w(currentColor currentColor_keyword), |
| 108 | + %w(rgb() rgb()), |
| 109 | + %w(hsl() hsl()), |
| 110 | + %w(rgba() rgba()), |
| 111 | + %w(hsla() hsla()) ]} |
| 112 | + |
| 90 | 113 | def additional_entries |
| 91 | 114 | ADDITIONAL_ENTRIES[slug] || [] |
| 92 | 115 | end |