<(common.inc.plp)><: use 5.010; Html({ title => 'browser compatibility cheat sheet', version => 'v1.0', description => "caniuse.", keywords => [qw'html css browser feature'], stylesheet => [qw'light dark circus mono red'], data => ['caniuse.js'], }); :>

Browser compatibility

Alternate view of Fyrd's when can I use... site.

<: use JSON; use File::Slurp 'read_file'; my $source = read_file('caniuse.js'); for ($source) { # cleanup # convert seperate variables to hash keys s/\A/{/; s/^caniuse\.(\w+) = /"$1":/gm; s/;$/,/gm; s/,\s*\Z/\n}/; # fractions not supported by barekey s/(?<=[,{]) (\d*\.\d) (?=:')/"$1"/gx; # escapes not supported in singlequote s{'((?:[^\\']+|\\.)*)'}{ my $_ = $1; s/"/\\"/g; s/\\'/'/g; qq("$_"); }ge; } my $caniuse = from_json($source, { # allow_singlequote => 1, allow_barekey => 1, }); my %CSTATS = ( n => 'di-b', y => 'di-a', a => 'di-d', j => 'di-prop', p => 'di-prop', 'y x' => 'di-a', ); my %CSTATUS = ( unoff => 'di-rare', # unofficial wd => 'di-b', # draft pr => 'di-prop', # proposed cr => 'di-d', # candidate rec => 'di-a', # recommendation ietf => 'di-a', # standard ); my @browsers = qw(trident gecko webkit_saf presto); my %versions; if (my ($somerow) = values %{ $caniuse->{data} }) { while (my ($browser, $row) = each %{ $somerow->{stats} }) { $versions{$browser} = [ sort { paddedver($a) cmp paddedver($b) } keys %$row ]; } } print ''; print '' x 2; printf '', scalar @{ $versions{$_} } for @browsers; print "\n"; print ''; print "'; print '\n"; sub featurerank { # relative amount of support for given feature state $statspts = { y=>10, 'y x'=>9, a=>5, j=>2, p=>1 }; my ($id) = @_; my $rank = 0; if (my $row = $caniuse->{data}->{$id}->{stats}) { while (my ($browser, $vercols) = each %versions) { my $div = 0; # multiplier exponent (decreased to lower value) my @vers = map { $row->{$browser}->{$_} } @$vercols; if (my $current = $caniuse->{agents}->{$browser}->{versions}->[-3]) { my @future; # find upcoming releases (after current) for (reverse @$vercols) { last if $_ eq $current; push @future, pop @vers; $_ eq 'u' and $_ = $vers[-1] for $future[-1]; # inherit latest value if unknown } splice @vers, -1, 0, @future; # move ahead to decrease precedence } $rank += $statspts->{$_} * 2**($div--) for reverse @vers; } } return $rank; } for my $id (sort { featurerank($b) <=> featurerank($a) } keys %{ $caniuse->{data} }) { my $row = $caniuse->{data}->{$id}; my $data = $row->{stats} or next; # skip metadata [summary] printf '', $id; printf '
$_" for qw(feature status); printf '%s', scalar @{ $versions{$_} }, $caniuse->{agents}->{$_}->{browser} for @browsers; # preceding row without any colspan to work around gecko bug print '
' x $_ for 2, map { scalar @{ $versions{$_} } } @browsers; print "
%s', $row->{description}, $row->{title}; printf '%s', $caniuse->{statuses}->{$_}, $CSTATUS{$_} // '', $_ for $row->{status}; for my $browser (@browsers) { my ($prev, @span); for my $ver (@{ $versions{$browser} }, undef) { unless (!defined $prev or $data->{$browser}->{$prev} ~~ $data->{$browser}->{$ver}) { printf '%s', $CSTATS{ $data->{$browser}->{$prev} }, scalar @span, join('‒', $span[0], @span > 1 ? $span[-1] : ()); undef $prev; @span = (); } push @span, $ver; $prev = $ver; } } print '', int featurerank($id); } print '
'; sub paddedver { # normalised version number comparable as string (cmp) shift =~ /^(\d*)(.*)/; return sprintf('%02d', $1) . $2; } :>
yes almost plugin or js no