Html({
title => 'browser compatibility cheat sheet',
- version => '1.4',
+ version => '1.5',
description => [
"Compatibility table of new web features (HTML5, CSS3, SVG, Javascript)",
"comparing support and usage share for all popular browser versions.",
'p d' => 'l2',
'a d' => 'l2',
'y' => 'l5',
+ 'y #' => 'l4',
'y x' => 'l5 ex',
+ 'y x #' => 'l4 ex',
'a' => 'l3',
'a x' => 'l3 ex',
- 'p j' => 'l2',
- 'j' => 'l2',
'p' => 'l2',
- 'p p' => 'l2',
'u' => 'l0',
+ 'u d' => 'l2',
);
my %DSTATS = (
u => 'unknown',
n => 'unsupported',
p => 'plugin required',
- j => 'javascript required',
a => 'partial',
y => 'supported',
- d => 'disabled by default',
+ d => '(disabled by default)',
x => sub {
join(' ',
- 'requires prefix',
+ 'with prefix',
map {"-$_-"}
($caniuse->{agents}->{$_[0]}->{prefix_exceptions} // {})->{$_[1]}
// $caniuse->{agents}->{$_[0]}->{prefix} // (),
);
my %PSTATS = ( # score percentage
y => 1, 'y x' => .9,
- a => .5, 'a x' => .5, 'a d' => .1,
- j => .2, 'p j' => .2, 'n d' => .2, 'n x d' => .2,
- p => .2, 'p p' => .2, 'p d' => .1,
- n => 0, u => 0,
+ a => .5, 'a x' => .5, 'a d' => .2,
+ p => .2, 'p d' => .1,
+ n => 0, 'n d' => .2, 'n x d' => .2,
+ u => 0,
);
my %CSTATUS = (
unoff => 'l1', # unofficial
other => 'l0', # non-w3
);
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 ];
- }
+while (my ($browser, $row) = each %{ $caniuse->{agents} }) {
+ $versions{$browser} = [
+ sort { paddedver($a) cmp paddedver($b) } grep { defined }
+ @{ $row->{versions} }
+ ];
}
-print <<'';
-<p id="intro">Alternate rendition of Fyrd's <a href="http://caniuse.com/">when can I use...</a> page
+my $ref = showlink('Can I use', 'https://caniuse.com/');
+$ref =~ s/(?=>)/ title="updated $_"/
+ for map { s/[\sT].*//r } $caniuse->{-date} || ();
+$ref = "Fyrd's $ref page";
+say '<p id="intro">Alternate rendition of '.$ref;
my ($canihas, $usage);
my $minusage = $get{threshold} // 1;
my $ref = $canihas->{-title} || 'unknown';
$ref = showlink($ref, $_)
for $canihas->{-site} || $canihas->{-source} || ();
- $ref .= " $_" for $canihas->{-date} || ();
+ $ref =~ s/(?=>)/ title="updated $_"/ for $canihas->{-date} || ();
print "\nwith $ref browser usage statistics";
}
}
} @browsers
}; # fallback hash based on release semantics
-my $usagemax = (max(map { ref $_ eq 'HASH' && sum(values %$_) } values %$canihas) // 1) / 100;
-my $usagepct = 1; # score multiplier for 0..100 result
-# normalise usage percentage to only include shown browsers
-$usagepct = 100.01 / featurescore({ # yes for every possible version
- map { $_ => { map {$_ => 'y'} map { @{$_} } @{$versions{$_}} } } keys %versions
-});
+# score multiplier for percentage of all browser versions
+my $usagepct = 99.99 / sum(
+ map { $_->{-total} // values %{$_} } values %{$canihas}
+);
+
+$_->{usage} = featurescore($_->{stats}) * $usagepct
+ for values %{ $caniuse->{data} };
print '<table class="mapped">';
print '<col span="3">'; # should match first thead row
# preceding row without any colspan to work around gecko bug
print "\n<tr>";
for my $browser (@browsers) {
- for (@{ $versions{$browser} }) {
- my $lastver = $_->[-1];
- my $release = $caniuse->{agents}->{$browser}->{verrelease}->{$lastver};
- my $future = defined $release;
+ for my $span (@{ $versions{$browser} }) {
+ my $lastver = first {
+ !defined $caniuse->{agents}->{$browser}->{verrelease}->{$_} # stable
+ } reverse @{$span};
printf('<td title="%s"%s>%s',
join(' ',
- sprintf('%.1f%%', sum(@{ $canihas->{$browser} }{@$_}) * $usagepct),
- $future ? 'development' : (),
- 'version ' . join(', ', @{$_}),
+ sprintf('%.1f%%', sum(@{ $canihas->{$browser} }{ @{$span} }) * $usagepct),
+ 'version ' . showversions(@{$span}, undef),
+ $span->[-1] eq $lastver ? () : '(development)',
),
- $future && ' class="ex"',
- showversions($lastver),
+ !defined $lastver && ' class="ex"',
+ showversions($lastver // $span->[0]),
);
}
}
|| 'u' # unsure
);
unless (!defined $prev or $prev ~~ $compare) {
- my $usage = sum(@{ $canihas->{$browser} }{ map { @{$_} } @span });
+ my @vercover = (map { @{$_} } @span);
+ for ($ver ? @{$ver} : ()) {
+ $data->{$_} eq $data->{$vercover[-1]} or last;
+ push @vercover, $_; # matches from next span start
+ }
+ my $usage = sum(@{ $canihas->{$browser} }{@vercover});
# strip #\d note references from support class
my @notes;
while $prev =~ s/\h \# (\d+) \b//x;
# prepare version hover details
- my $title = sprintf('%.1f%% %s', $usage * $usagepct, join(', ',
- map { ref $_ eq 'CODE' ? $_->($browser, $span[0]->[0]) : $_ }
- map { $DSTATS{$_} // () }
- map { split / /, $_ }
- $prev
+ my $title = sprintf('%.1f%% %s', $usage * $usagepct, join(' ',
+ (map { ref $_ eq 'CODE' ? $_->($browser, $vercover[0]) : $_ }
+ map { $DSTATS{$_} // () }
+ map { split / /, $_ }
+ $prev
+ ),
+ 'in', $caniuse->{agents}->{$browser}->{abbr},
+ showversions(@vercover, undef),
));
$title .= "\n$_" for notestotitle(@notes);
+ $prev .= ' #' if @notes and $prev =~ /^y/;
printf('<td class="%s" colspan="%d" title="%s">%s',
join(' ',
X => $CSTATS{$prev},
sprintf('p%01d', $usage * ($usagepct - .0001) / 10),
sprintf('p%02d', $usage * ($usagepct - .0001)),
),
- sprintf('pp%02d', $usage / $usagemax),
),
scalar @span,
$title,
- showversions($span[0]->[0], @span > 1 ? ($span[-1]->[-1]) : ()),
+ showversions($span[0]->[0], @span > 1 && defined $ver ? $span[-1]->[-1] : ()),
);
undef $prev;
@span = ();
sub sayusagecol {
my ($id) = @_;
- print '<td>', int featurescore($caniuse->{data}->{$id}->{stats}) * $usagepct;
+ print '<td>', int $caniuse->{data}->{$id}->{usage};
}
say '<tbody>';
for my $id (sort {
- featurescore($caniuse->{data}->{$b}->{stats})
- <=> featurescore($caniuse->{data}->{$a}->{stats})
+ $caniuse->{data}->{$b}->{usage} <=> $caniuse->{data}->{$a}->{usage}
} keys %{ $caniuse->{data} }) {
$caniuse->{data}->{$id}->{stats} or next; # skip metadata [summary]
printf '<tr id="%s">', $id;
sub paddedver {
# normalised version number comparable as string (cmp)
- shift =~ /(?:.*-|^)(\d*)(.*)/;
+ $_[0] =~ m/(?:.*-|^)(\d*)(.*)/;
# matched (major)(.minor) of last value in range (a-B)
- return sprintf('%02d', $1 || 99) . $2;
+ return sprintf('%02d', length $1 ? $1 : 99) . $2;
}
sub showversions {
- my @span = ($_[0], @_>1 ? $_[-1] : ());
- s/-.*// for $span[0];
- for (@span) {
- s/^\./0./;
- s/x$/.*/;
- s/.*-//;
- }
+ # title to describe minumum version and optional maximum for multiple cells
+ my @span = (map { split /-/ } grep { defined } @_);
+ return $span[0] =~ s/\.0\z//r if @_ <= 1;
+ splice @span, 1, -1;
return join('‒', @span);
}
<div class="legend">
<table class="glyphs"><tr>
<td class="X l5">supported
+ <td class="X l4">annotated
<td class="X l3">partial
<td class="X l2">optional
<td class="X l1">missing
</div>
<script type="text/javascript" src="/searchlocal.js"></script>
-<script type="text/javascript"> prependsearch(document.getElementById('intro')) </script>
+<script type="text/javascript"><!--
+ prependsearch(document.getElementById('intro'));
+//--></script>