diff --git a/lib/MetaCPAN/Web/Controller/ContributingDoc.pm b/lib/MetaCPAN/Web/Controller/ContributingDoc.pm index aed05d54cd..c9a14497a2 100644 --- a/lib/MetaCPAN/Web/Controller/ContributingDoc.pm +++ b/lib/MetaCPAN/Web/Controller/ContributingDoc.pm @@ -38,7 +38,7 @@ sub get : Private { my $file = List::Util::first { $_->{name} =~ /$contributing_re/ } @$files; - if ( !exists $file->{path} ) { + if ( !$file || !exists $file->{path} ) { my $release_info = $c->model('ReleaseInfo')->get( $author, $release ); $c->stash( $release_info->get ); $c->stash( { @@ -47,17 +47,11 @@ sub get : Private { $c->response->status(404); } else { - if ( $file->{pod_lines} && @{ $file->{pod_lines} } ) { - $c->stash( - author_name => $author, - release_name => $release, - ); - $c->forward( '/view/release', [ $file->{path} ] ); - } - else { - $c->forward( '/source/view', - [ $file->{author}, $file->{release}, $file->{path} ] ); - } + $c->stash( + author_name => $author, + release_name => $release, + ); + $c->forward( '/view/release', [ $file->{path} ] ); } } diff --git a/lib/MetaCPAN/Web/Controller/MD.pm b/lib/MetaCPAN/Web/Controller/MD.pm new file mode 100644 index 0000000000..b998e73e3d --- /dev/null +++ b/lib/MetaCPAN/Web/Controller/MD.pm @@ -0,0 +1,22 @@ +package MetaCPAN::Web::Controller::MD; + +use Moose; + +use namespace::autoclean; + +BEGIN { extends 'MetaCPAN::Web::Controller' } + +sub view : Private { + my ( $self, $c, $author, $release, @path ) = @_; + + my $source = $c->model('API::File')->source( $author, $release, @path ); + + $c->stash( { + source => $source->get->{raw}, + template => 'md.tx', + } ); +} + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/lib/MetaCPAN/Web/Controller/Pod.pm b/lib/MetaCPAN/Web/Controller/Pod.pm index 6d606b8f6b..0f5f60b2ad 100644 --- a/lib/MetaCPAN/Web/Controller/Pod.pm +++ b/lib/MetaCPAN/Web/Controller/Pod.pm @@ -29,7 +29,7 @@ sub find : Path : Args(1) { # TODO: Disambiguate if there's more than one match. #176 - $c->forward( 'view', [@path] ); + $c->forward( '/view/file', [@path] ); } sub view : Private { @@ -70,11 +70,6 @@ sub view : Private { $c->detach('/not_found') if ( $pod->{code} || 0 ) > 399; - # Store at fastly for a year - as we will purge! - $c->cdn_max_age('1y'); - $c->add_dist_key( $release->{distribution} ); - $c->add_author_key( $release->{author} ); - if ( $data->{deprecated} ) { $c->stash->{notification} ||= { type => 'MODULE_DEPRECATED' }; } diff --git a/lib/MetaCPAN/Web/Controller/View.pm b/lib/MetaCPAN/Web/Controller/View.pm index 530c58f2ab..75084492f8 100644 --- a/lib/MetaCPAN/Web/Controller/View.pm +++ b/lib/MetaCPAN/Web/Controller/View.pm @@ -31,7 +31,7 @@ sub dist : Chained('/dist/root') PathPart('view') Args { %$release_data, file => $c->model('API::File')->get(@path)->get, } ); - $c->forward( '/pod/view', [@path] ); + $c->forward( 'file', [@path] ); } sub release : Chained('/release/root') PathPart('view') Args { @@ -52,7 +52,31 @@ sub release : Chained('/release/root') PathPart('view') Args { permalinks => 1, } ); - $c->forward( '/pod/view', [ $author, $release, @path ] ); + $c->forward( 'file', [ $author, $release, @path ] ); +} + +sub file : Private { + my ( $self, $c, @path ) = @_; + + my $release = $c->stash->{release}; + my $file = $c->stash->{file}; + + $c->cdn_max_age('1y'); + $c->add_dist_key( $release->{distribution} ); + $c->add_author_key( $release->{author} ); + + if ( $file->{mime} eq 'text/x-script.perl' + || $file->{mime} eq 'text/x-script.perl-module' + || $file->{mime} eq 'text/x-pod' ) + { + $c->forward( '/pod/view', \@path ); + } + elsif ( $file->{mime} eq 'text/markdown' ) { + $c->forward( '/md/view', \@path ); + } + else { + $c->forward( '/source/view', \@path ); + } } __PACKAGE__->meta->make_immutable; diff --git a/lib/MetaCPAN/Web/Model/API.pm b/lib/MetaCPAN/Web/Model/API.pm index 24fc67197d..debe3a08f7 100644 --- a/lib/MetaCPAN/Web/Model/API.pm +++ b/lib/MetaCPAN/Web/Model/API.pm @@ -19,6 +19,17 @@ use Try::Tiny qw( catch try ); use URI (); use URI::Escape qw( uri_escape ); +use Data::Dump (); +use Data::Dump::Filtered (); + +Data::Dump::Filtered::add_dump_filter( sub { + my ( $ctx, $object_ref ) = @_; + if ( $ctx->object_isa('IO::Async::Loop') ) { + return { dump => "bless({ '...' => '...' }, '" . $ctx->class . "')" }; + } + return undef; +} ); + my $loop; sub loop { diff --git a/root/base.tx b/root/base.tx index a60a66599c..d7af8c6c63 100644 --- a/root/base.tx +++ b/root/base.tx @@ -132,7 +132,7 @@
%% block breadcrumbs -> { }
-
+
%% block content -> { }
diff --git a/root/inc/link_to_file.tx b/root/inc/link_to_file.tx index 1f325f3903..b82de157c5 100644 --- a/root/inc/link_to_file.tx +++ b/root/inc/link_to_file.tx @@ -2,7 +2,7 @@ my $title = $file.documentation || $file.path; # If there is pod for this file... -if $file.documentation || $file.pod_lines.size() || $file.has_associated_pod { +if $file.documentation || $file.pod_lines.size() || $file.has_associated_pod || $file.mime == 'text/markdown' { -%] [% $source %] - %% } %% } %% else { This file cannot be displayed inline. Try the raw file. diff --git a/root/static/js/cpan.js b/root/static/js/cpan.js index 8897cb9f51..c22e63f302 100644 --- a/root/static/js/cpan.js +++ b/root/static/js/cpan.js @@ -178,7 +178,7 @@ for (const favButton of document.querySelectorAll('.breadcrumbs .favorite')) { jQuery('.dropdown-toggle').dropdown(); // bootstrap -const toc = document.querySelector('.content .toc'); +const toc = document.querySelector('main .toc'); if (toc) { formatTOC(toc); } diff --git a/root/static/js/syntaxhighlighter.mjs b/root/static/js/syntaxhighlighter.mjs index c550cbf677..72e63d644f 100644 --- a/root/static/js/syntaxhighlighter.mjs +++ b/root/static/js/syntaxhighlighter.mjs @@ -204,7 +204,7 @@ if (source) { } } -for (const code of document.querySelectorAll('.content pre > code')) { +for (const code of document.querySelectorAll('main pre > code')) { const pre = code.parentNode; const config = { diff --git a/root/static/less/global.less b/root/static/less/global.less index 34232c0375..1fa1427c50 100644 --- a/root/static/less/global.less +++ b/root/static/less/global.less @@ -409,7 +409,7 @@ h3, .content-navigation { grid-area: breadcrumbs; } -.content { +main { grid-area: content; } .content-pagination { @@ -444,7 +444,7 @@ h3, padding-left: 5px; } -.content { +main { justify-self: center; line-height: 1.54em; padding: 40px; diff --git a/root/static/less/pod.less b/root/static/less/pod.less index 05f96f5594..942aef0fba 100644 --- a/root/static/less/pod.less +++ b/root/static/less/pod.less @@ -88,7 +88,7 @@ } } -.content .toc { +main .toc { display: inline-block; border: 1px solid rgb(215, 215, 215); padding: 3px 10px; diff --git a/root/static/less/release.less b/root/static/less/release.less index 2c1d1278eb..7302e40f50 100644 --- a/root/static/less/release.less +++ b/root/static/less/release.less @@ -1,4 +1,4 @@ -.content { +main { .release-documentation, .release-modules, .release-provides { @@ -46,7 +46,7 @@ * See /release/CPAN-Changes for example */ #metacpan_last-changes { - h2:extend(.content .file-group h2) { + h2:extend(main .file-group h2) { } ul { diff --git a/root/static/less/responsive.less b/root/static/less/responsive.less index 69060207e8..a519d1fa70 100644 --- a/root/static/less/responsive.less +++ b/root/static/less/responsive.less @@ -178,7 +178,7 @@ width: 95%; } - .content { + main { padding: 20px; } diff --git a/t/controller/changes.t b/t/controller/changes.t index c45f270698..1f71d1f964 100644 --- a/t/controller/changes.t +++ b/t/controller/changes.t @@ -13,7 +13,7 @@ test_psgi app, sub { is( $res->code, 200, "200 on $url" ); my $tx = tx($res); $tx->like( - '//*[contains-token(@class, "content")]//pre[@id="metacpan_source"]', + '//main//pre[@id="metacpan_source"]', qr/^Revision history for File-Spec-Native/, 'source view for plain text change log' ); diff --git a/t/controller/contributing-to.t b/t/controller/contributing-to.t index 9d8f9d34ea..be7e6b0323 100644 --- a/t/controller/contributing-to.t +++ b/t/controller/contributing-to.t @@ -37,8 +37,7 @@ test_psgi app, sub { is( $res->code, 404, 'code 404' ); my $tx2 = tx($res); - $tx2->find_value( '//div[contains-token(@class, "content")]', - 'page has content' ); + $tx2->find_value( '//main', 'page has content' ); $tx2->like( q[//div[contains-token(@class, 'about')]], qr/No Contributing guidelines.+found/, diff --git a/t/controller/pod.t b/t/controller/pod.t index 2e92ba98c5..b3ffc4676b 100644 --- a/t/controller/pod.t +++ b/t/controller/pod.t @@ -45,11 +45,10 @@ test_psgi app, sub { ); my $tx2 = tx($res); - ok( $tx->find_value('//*[contains-token(@class, "content")]'), - 'page has content' ); + ok( $tx->find_value('//main'), 'page has content' ); is( - $tx2->find_value('//*[contains-token(@class, "content")]'), - $tx->find_value('//*[contains-token(@class, "content")]'), + $tx2->find_value('//main'), + $tx->find_value('//main'), 'content of both urls is exactly the same' ); diff --git a/t/controller/release.t b/t/controller/release.t index f95eb18c49..fb9329a424 100644 --- a/t/controller/release.t +++ b/t/controller/release.t @@ -62,12 +62,12 @@ test_psgi app, sub { ), 'contains link to "this" version' ); - my $latest = $tx->find_value('//*[contains-token(@class, "content")]'); + my $latest = $tx->find_value('//main'); ok( $res = $cb->( GET $this ), "GET $this" ); my $tx_latest = tx($res); is( $latest, - $tx_latest->find_value('//*[contains-token(@class, "content")]'), + $tx_latest->find_value('//main'), 'content of both urls is exactly the same' ); @@ -223,8 +223,7 @@ sub test_heading_order { my $heading = 0; # Boohoo... testing with XPATH :-( - my $xpath_prefix - = '//*[contains-token(@class, "content")]/div[contains-token(@class, "file-group")]'; + my $xpath_prefix = '//main/div[contains-token(@class, "file-group")]'; $tx->ok( "$xpath_prefix/h2", sub { diff --git a/t/controller/source.t b/t/controller/source.t index 00e18e34f9..524ca60e7d 100644 --- a/t/controller/source.t +++ b/t/controller/source.t @@ -87,12 +87,12 @@ test_psgi app, sub { my @tests = ( { uri => '/release/RJBS/Dist-Zilla-5.043/source/bin/dzil', - xpath => '//*[contains-token(@class, "content")]/pre/code/@class', + xpath => '//main/pre/code/@class', expected => qr/\blanguage-perl\b/, desc => 'has pre-block with expected syntax brush', }, { - uri => '/release/ETHER/Moose-2.1005/source/README.md', + uri => '/release/ETHER/Moose-2.1005/view/README.md', xpath => '//h1[@id="moose"]', expected => qr/^Moose$/, desc => 'markdown rendered as HTML',