| @@ -0,0 +1,212 @@ |
| | 1 | module Docs |
| | 2 | class Mdn |
| | 3 | class CompatTablesFilter < Filter |
| | 4 | |
| | 5 | def call |
| | 6 | if at_css('#browser_compatibility') \ |
| | 7 | and not at_css('#browser_compatibility').next_sibling.classes.include?('warning') \ |
| | 8 | and not at_css('#browser_compatibility').next_sibling.content.match?('Supported') |
| | 9 | |
| | 10 | at_css('#browser_compatibility').next_sibling.remove |
| | 11 | |
| | 12 | compatibility_tables = generate_compatibility_table() |
| | 13 | compatibility_tables.each do |table| |
| | 14 | at_css('#browser_compatibility').add_next_sibling(table) |
| | 15 | end |
| | 16 | end |
| | 17 | |
| | 18 | doc |
| | 19 | end |
| | 20 | |
| | 21 | BROWSERS = { |
| | 22 | 'chrome' => 'Chrome', |
| | 23 | 'edge' => 'Edge', |
| | 24 | 'firefox' => 'Firefox', |
| | 25 | 'ie' => 'Internet Explorer', |
| | 26 | 'opera' => 'Opera', |
| | 27 | 'safari' => 'Safari', |
| | 28 | 'webview_android' => 'WebView Android', |
| | 29 | 'chrome_android' => 'Chrome Android', |
| | 30 | 'firefox_android' => 'Firefox for Android', |
| | 31 | 'opera_android' => 'Opera Android', |
| | 32 | 'safari_ios' => 'Safari on IOS', |
| | 33 | 'samsunginternet_android' => 'Samsung Internet' |
| | 34 | } |
| | 35 | |
| | 36 | def generate_compatibility_table() |
| | 37 | json_files_uri = request_bcd_uris() |
| | 38 | |
| | 39 | compat_tables = [] |
| | 40 | |
| | 41 | json_files_uri.each do |uri| |
| | 42 | compat_tables.push(generate_compatibility_table_wrapper(uri)) |
| | 43 | end |
| | 44 | |
| | 45 | return compat_tables |
| | 46 | end |
| | 47 | |
| | 48 | def request_bcd_uris |
| | 49 | index_json = JSON.load(Net::HTTP.get(URI(current_url.to_s + '/index.json'))) |
| | 50 | |
| | 51 | uris = [] |
| | 52 | |
| | 53 | index_json['doc']['body'].each do |element| |
| | 54 | uris.push(element['value']['dataURL']) if element['type'] == 'browser_compatibility' and element['value']['dataURL'] |
| | 55 | end |
| | 56 | |
| | 57 | uris.map! do |uri| |
| | 58 | tmp_uri = URI.parse(base_url.to_s) |
| | 59 | tmp_uri.path = uri |
| | 60 | uri = tmp_uri.to_s |
| | 61 | end |
| | 62 | |
| | 63 | return uris |
| | 64 | end |
| | 65 | |
| | 66 | def generate_compatibility_table_wrapper(uri) |
| | 67 | |
| | 68 | @json_data = JSON.load(Net::HTTP.get(URI(uri)))['data'] |
| | 69 | |
| | 70 | html_table = generate_basic_html_table() |
| | 71 | |
| | 72 | @json_data.keys.each do |key| |
| | 73 | if key == '__compat' or @json_data[key]['__compat'] |
| | 74 | add_entry_to_table(html_table, key) |
| | 75 | else |
| | 76 | end |
| | 77 | end |
| | 78 | |
| | 79 | return html_table |
| | 80 | end |
| | 81 | |
| | 82 | def generate_basic_html_table |
| | 83 | table = Nokogiri::XML::Node.new('table', doc) |
| | 84 | |
| | 85 | table.add_child('<thead><tr id=bct-browser-type><tr id=bct-browsers><tbody>') |
| | 86 | |
| | 87 | table.css('#bct-browser-type').each do |node| |
| | 88 | node.add_child('<th>') |
| | 89 | %w(Desktop Mobile).each do |browser_type| |
| | 90 | node.add_child("<th colspan=6>#{browser_type}") |
| | 91 | end |
| | 92 | end |
| | 93 | |
| | 94 | table.css('#bct-browsers').each do |node| |
| | 95 | node.add_child('<th>') |
| | 96 | |
| | 97 | BROWSERS.values.each do |browser| |
| | 98 | node.add_child("<th>#{browser}") |
| | 99 | end |
| | 100 | end |
| | 101 | |
| | 102 | return table |
| | 103 | end |
| | 104 | |
| | 105 | def add_entry_to_table(html_table, key) |
| | 106 | json = @json_data[key] |
| | 107 | |
| | 108 | html_table.at_css('tbody').add_child('<tr>') |
| | 109 | |
| | 110 | last_table_entry = html_table.at_css('tbody').last_element_child |
| | 111 | |
| | 112 | if key == '__compat' |
| | 113 | tmp = slug.split('/') |
| | 114 | last_table_entry.add_child("<th><code>#{tmp.last}") |
| | 115 | else |
| | 116 | last_table_entry.add_child("<th><code>#{key}") |
| | 117 | end |
| | 118 | |
| | 119 | |
| | 120 | BROWSERS.keys.each do |browser_key| |
| | 121 | if key == '__compat' |
| | 122 | add_data_to_entry(json['support'][browser_key], last_table_entry) |
| | 123 | else |
| | 124 | add_data_to_entry(json['__compat']['support'][browser_key], last_table_entry) |
| | 125 | end |
| | 126 | |
| | 127 | end |
| | 128 | end |
| | 129 | |
| | 130 | def add_data_to_entry(json, entry) |
| | 131 | version_added = [] |
| | 132 | version_removed = [] |
| | 133 | notes = [] |
| | 134 | |
| | 135 | if json |
| | 136 | if json.is_a?(Array) |
| | 137 | json.each do |element| |
| | 138 | |
| | 139 | if element['version_added'] |
| | 140 | version_added.push(element['version_added']) |
| | 141 | else |
| | 142 | version_added.push(false) |
| | 143 | end |
| | 144 | |
| | 145 | if element['version_removed'] |
| | 146 | version_removed.push(element['version_removed']) |
| | 147 | else |
| | 148 | version_removed.push(false) |
| | 149 | end |
| | 150 | |
| | 151 | if element['notes'] |
| | 152 | notes.push(element['notes']) |
| | 153 | else |
| | 154 | notes.push(false) |
| | 155 | end |
| | 156 | |
| | 157 | end |
| | 158 | else |
| | 159 | version_added.push(json['version_added']) |
| | 160 | version_removed.push(json['version_removed']) |
| | 161 | notes.push(json['notes']) |
| | 162 | end |
| | 163 | |
| | 164 | version_added.map! do |version| |
| | 165 | if version == true |
| | 166 | version = 'Yes' |
| | 167 | elsif version == false |
| | 168 | version = 'No' |
| | 169 | elsif version.is_a?(String) |
| | 170 | else |
| | 171 | version = '?' |
| | 172 | end |
| | 173 | |
| | 174 | version |
| | 175 | end |
| | 176 | |
| | 177 | if version_removed[0] |
| | 178 | format_string = "<td class=bc-supports-no>" |
| | 179 | else |
| | 180 | if version_added[0] == 'No' |
| | 181 | format_string = "<td class=bc-supports-no>" |
| | 182 | else |
| | 183 | format_string = "<td class=bc-supports-yes>" |
| | 184 | end |
| | 185 | end |
| | 186 | |
| | 187 | for value in (0..version_added.length-1) do |
| | 188 | if version_removed[value] |
| | 189 | format_string += "<div>#{version_added[value]}-#{version_removed[value]}</div>" |
| | 190 | else |
| | 191 | if version_added[value] == 'No' |
| | 192 | format_string += "<div>#{version_added[value]}</div>" |
| | 193 | else |
| | 194 | format_string += "<div>#{version_added[value]}</div>" |
| | 195 | end |
| | 196 | end |
| | 197 | |
| | 198 | if notes[value] |
| | 199 | format_string += "<div>#{notes[value]}</div>" |
| | 200 | end |
| | 201 | end |
| | 202 | |
| | 203 | else |
| | 204 | format_string = "<td class=bc-supports-no><div>?</div></td>" |
| | 205 | end |
| | 206 | |
| | 207 | entry.add_child(format_string) |
| | 208 | end |
| | 209 | |
| | 210 | end |
| | 211 | end |
| | 212 | end |