Hello community, here is the log from the commit of package perl-Mojolicious-Plugin-AssetPack for openSUSE:Factory checked in at 2016-07-20 09:29:30 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Mojolicious-Plugin-AssetPack (Old) and /work/SRC/openSUSE:Factory/.perl-Mojolicious-Plugin-AssetPack.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Mojolicious-Plugin-AssetPack" Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Mojolicious-Plugin-AssetPack/perl-Mojolicious-Plugin-AssetPack.changes 2016-07-12 23:51:20.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.perl-Mojolicious-Plugin-AssetPack.new/perl-Mojolicious-Plugin-AssetPack.changes 2016-07-20 09:29:32.000000000 +0200 @@ -1,0 +2,13 @@ +Tue Jul 19 05:30:47 UTC 2016 - co...@suse.com + +- updated to 1.17 + see /usr/share/doc/packages/perl-Mojolicious-Plugin-AssetPack/Changes + + 1.17 2016-07-18T18:43:23+0200 + - Removed Mojolicious::Plugin::AssetPack::Asset::tag_helper() + - Add Mojolicious::Plugin::AssetPack::tag_for() + - Add Mojolicious::Plugin::AssetPack::Asset::url_for() + - Add EXPERIMENTAL Mojolicious::Plugin::AssetPack::Pipe::Favicon + - Add support for gif, ico, mp3, mp4, ogg, ogv, svg and webm. + +------------------------------------------------------------------- Old: ---- Mojolicious-Plugin-AssetPack-1.16.tar.gz New: ---- Mojolicious-Plugin-AssetPack-1.17.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Mojolicious-Plugin-AssetPack.spec ++++++ --- /var/tmp/diff_new_pack.dWRlGo/_old 2016-07-20 09:29:33.000000000 +0200 +++ /var/tmp/diff_new_pack.dWRlGo/_new 2016-07-20 09:29:33.000000000 +0200 @@ -17,7 +17,7 @@ Name: perl-Mojolicious-Plugin-AssetPack -Version: 1.16 +Version: 1.17 Release: 0 %define cpan_name Mojolicious-Plugin-AssetPack Summary: Compress and convert css, less, sass, javascript and coffeescript files ++++++ Mojolicious-Plugin-AssetPack-1.16.tar.gz -> Mojolicious-Plugin-AssetPack-1.17.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/Changes new/Mojolicious-Plugin-AssetPack-1.17/Changes --- old/Mojolicious-Plugin-AssetPack-1.16/Changes 2016-06-29 19:05:43.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/Changes 2016-07-18 18:43:23.000000000 +0200 @@ -1,5 +1,12 @@ Revision history for perl distribution Mojolicious-Plugin-AssetPack +1.17 2016-07-18T18:43:23+0200 + - Removed Mojolicious::Plugin::AssetPack::Asset::tag_helper() + - Add Mojolicious::Plugin::AssetPack::tag_for() + - Add Mojolicious::Plugin::AssetPack::Asset::url_for() + - Add EXPERIMENTAL Mojolicious::Plugin::AssetPack::Pipe::Favicon + - Add support for gif, ico, mp3, mp4, ogg, ogv, svg and webm. + 1.16 2016-06-29T19:05:43+0200 - Improved documentation for store() #101 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/MANIFEST new/Mojolicious-Plugin-AssetPack-1.17/MANIFEST --- old/Mojolicious-Plugin-AssetPack-1.16/MANIFEST 2016-06-29 19:05:44.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/MANIFEST 2016-07-18 18:43:25.000000000 +0200 @@ -18,6 +18,7 @@ lib/Mojolicious/Plugin/AssetPack/Pipe/CoffeeScript.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Combine.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Css.pm +lib/Mojolicious/Plugin/AssetPack/Pipe/Favicon.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Fetch.pm lib/Mojolicious/Plugin/AssetPack/Pipe/JavaScript.pm lib/Mojolicious/Plugin/AssetPack/Pipe/Jpeg.pm @@ -47,8 +48,17 @@ t/assets/css-0-two.css t/assets/css/c.css t/assets/example.css +t/assets/image/master_favicon_thumbnail.png t/assets/image/photo-1429734160945-4f85244d6a5a.jpg t/assets/image/sample.png +t/assets/other/dummy.gif +t/assets/other/dummy.ico +t/assets/other/dummy.mp3 +t/assets/other/dummy.mp4 +t/assets/other/dummy.ogg +t/assets/other/dummy.ogv +t/assets/other/dummy.svg +t/assets/other/dummy.webm t/assets/recreate.css t/assets/sass/70-utf8.scss t/assets/sass/_sass-1-blocks.scss @@ -62,6 +72,7 @@ t/coffee.t t/css.t t/Dynamic.pm +t/favicon.t t/fetch-all.t t/font-awesome.t t/google-font.t @@ -108,6 +119,7 @@ t/old-sprites.t t/old-twice.t t/old-undefined.t +t/other.t t/png.t t/public/anotherdir/subdir/_issue-60.scss t/public/css/1w.css diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/META.json new/Mojolicious-Plugin-AssetPack-1.17/META.json --- old/Mojolicious-Plugin-AssetPack-1.16/META.json 2016-06-29 19:05:44.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/META.json 2016-07-18 18:43:25.000000000 +0200 @@ -48,5 +48,5 @@ "url" : "https://github.com/jhthorsen/mojolicious-plugin-assetpack.git" } }, - "version" : "1.16" + "version" : "1.17" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/META.yml new/Mojolicious-Plugin-AssetPack-1.17/META.yml --- old/Mojolicious-Plugin-AssetPack-1.16/META.yml 2016-06-29 19:05:44.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/META.yml 2016-07-18 18:43:24.000000000 +0200 @@ -25,4 +25,4 @@ bugtracker: https://github.com/jhthorsen/mojolicious-plugin-assetpack/issues homepage: https://github.com/jhthorsen/mojolicious-plugin-assetpack repository: https://github.com/jhthorsen/mojolicious-plugin-assetpack.git -version: '1.16' +version: '1.17' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/README new/Mojolicious-Plugin-AssetPack-1.17/README --- old/Mojolicious-Plugin-AssetPack-1.16/README 2016-06-29 19:05:43.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/README 2016-07-18 18:43:24.000000000 +0200 @@ -3,7 +3,7 @@ javascript and coffeescript files VERSION - 1.16 + 1.17 SYNOPSIS Application @@ -96,7 +96,7 @@ Used by Mojolicious::Plugin::AssetPack::Pipe::JavaScript. HELPERS -asset + asset $self = $app->asset; $self = $c->asset; $bytestream = $c->asset($topic, @args); @@ -144,6 +144,26 @@ Holds a Mojolicious::Plugin::AssetPack::Store object used to locate, store and serve assets. + tag_for + $self = $self->tag_for(sub { my ($asset, $c, \%args, @attrs) = @_; }); + $code = $self->tag_for; + + Holds a sub reference that returns a Mojo::Bytestream object containing + the markup required to render an asset. + + $asset is a Mojolicious::Plugin::AssetPack::Asset object, $c is an + Mojolicious::Controller object and @attrs can contain a list of HTML + attributes. %args currently contains: + + * base_url + + See "ASSETS FROM CUSTOM DOMAIN" in + Mojolicious::Plugin::AssetPack::Guides::Cookbook. + + * topic + + Name of the current topic. + ua $ua = $self->ua; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Asset.pm new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Asset.pm --- old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Asset.pm 2016-05-15 11:40:08.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Asset.pm 2016-07-18 14:52:52.000000000 +0200 @@ -12,13 +12,13 @@ ? Mojo::URL->new($self->url)->path->[-1] : (split m!(\\|/)!, $self->url)[-1]; - return $name =~ /\.(\w+)$/ ? $1 : ''; + return $name =~ /\.(\w+)$/ ? lc $1 : ''; }; has minified => sub { shift->url =~ /\bmin\b/ ? 1 : 0 }; has mtime => sub { shift->_asset->mtime }; -has tag_helper => sub { shift->format eq 'js' ? 'javascript' : 'stylesheet' }; +sub tag_helper { warn "DEPRECATED in v1.17! This attribute does nothing." } has _asset => sub { my $self = shift; @@ -69,6 +69,8 @@ sub path { $_[0]->_asset->isa('Mojo::Asset::File') ? $_[0]->_asset->path : '' } sub size { $_[0]->_asset->size } +sub url_for { $_[1]->url_for(assetpack => $_[0]->TO_JSON); } + sub _reset { my $self = shift; delete $self->{$_} for qw(checksum format mtime); @@ -142,14 +144,7 @@ =head2 tag_helper - $self = $self->tag_helper("stylesheet"); - $str = $self->tag_helper; - -Used to get the Mojolicious L<tag helper|Mojolicious::Plugin::TagHelpers> which -should be used to render this asset. - -This could be set to "image" by a pipe, but defaults to either "stylesheet" or -"javascript", based on L</format>. +Replaced by L<Mojolicious::Plugin::AssetPack/tag_for>. =head2 url @@ -190,6 +185,13 @@ See L<Mojo::Asset/size>. +=head2 url_for + + $url = $self->url_for($c); + +Returns a L<Mojo::URL> object for this asset. C<$c> need to be a +L<Mojolicious::Controller>. + =head2 FROM_JSON $self = $self->FROM_JSON($hash_ref); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Guides/Tutorial.pod new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Guides/Tutorial.pod --- old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Guides/Tutorial.pod 2016-06-29 18:48:26.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Guides/Tutorial.pod 2016-07-18 15:57:03.000000000 +0200 @@ -75,15 +75,37 @@ Minify CSS. +=item * L<Mojolicious::Plugin::AssetPack::Pipe::Favicon> + +There is a special topic called "favicon.ico", combined with the +L<Mojolicious::Plugin::AssetPack::Pipe::Favicon> pipe which can be used to +describe favicons, touch icons and tile icons. + +=item * L<Mojolicious::Plugin::AssetPack::Pipe::Fetch> + +Will look for "url(...)" in CSS files and download the related assets. + =item * L<Mojolicious::Plugin::AssetPack::Pipe::JavaScript> Minify JavaScript. +=item * L<Mojolicious::Plugin::AssetPack::Pipe::Jpeg> + +Used to crush "jpeg" image files. + =item * L<Mojolicious::Plugin::AssetPack::Pipe::Less> Process Less CSS files. Should be loaded before L<Mojolicious::Plugin::AssetPack::Pipe::Css>. +=item * L<Mojolicious::Plugin::AssetPack::Pipe::Png> + +Used to crush "png" image files. + +=item * L<Mojolicious::Plugin::AssetPack::Pipe::Reloader> + +EXPERIMENTAL pipe for reloading the page when the assets change. + =item * L<Mojolicious::Plugin::AssetPack::Pipe::Riotjs> Process L<http://riotjs.com/> tag files. Should be loaded before @@ -267,6 +289,39 @@ (L<JavaScript::Minifier::XS>, L<CSS::Sass>) to be required while developing, but can be skipped when installing an already built application. +=head2 Assets without topics + +One nifty feature is to use L<Mojolicious::Plugin::AssetPack> for assets which +does not have any pipe to process them. The reason why this comes in handy is +to avoid cache issues, since changing the file on disk will generate a new URL. + +These assets can also be defined directly in the templates, without having to +be defined in the application startup process. Examples: + + # <img src="/asset/52e98718f0/foo.gif"> + %= asset "/image/foo.gif" + + # <img src="/asset/87652910af/baz.svg"> + %= asset "/image/baz.svg" + + # <link rel="icon" href="/asset/65428718f1/bar.ico"> + %= asset "/image/bar.gif" + + # <source src="/asset/87652718f0/baz.mp3" type="audio/mpeg"> + %= asset "/audio/baz.mp3" + + # <source src="/asset/52e87652f0/foo.mp4" type="video/mp4"> + %= asset "/video/foo.mp4" + + # <source src="/asset/52eaz7613a/bar.ogg" type="audio/ogg"> + %= asset "/audio/bar.ogg" + + # <source src="/asset/baf72618f1/foo.ogv" type="audio/ogv"> + %= asset "/video/foo.ogv" + + # <source src="/asset/92118711f0/bar.webm" type="audio/webm"> + %= asset "/video/bar.webm" + =head1 SEE ALSO L<Mojolicious::Plugin::AssetPack> and diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Pipe/Favicon.pm new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Pipe/Favicon.pm --- old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Pipe/Favicon.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Pipe/Favicon.pm 2016-07-18 18:41:52.000000000 +0200 @@ -0,0 +1,193 @@ +package Mojolicious::Plugin::AssetPack::Pipe::Favicon; +use Mojo::Base 'Mojolicious::Plugin::AssetPack::Pipe'; + +use Mojo::DOM; +use Mojo::Util; +use Mojolicious::Plugin::AssetPack::Util qw(diag load_module DEBUG); + +# this should be considered private +our $URL = 'http://realfavicongenerator.net/api/favicon'; + +has api_key => sub { die 'api_key() must be set' }; +has design => sub { +{desktop_browser => {}} }; +has settings => sub { +{error_on_image_too_small => Mojo::JSON->true} }; + +has _icons => sub { [] }; + +sub process { + my ($self, $assets) = @_; + return unless $self->topic eq 'favicon.ico'; + + my $store = $self->assetpack->store; + my $asset = $assets->first; + my $attrs = $asset->TO_JSON; + my ($db, $files, $markup, @icons); + + $attrs->{key} = join '-', sort keys %{$self->design} + or die '[AssetPack] Invalid pipe("Favicon")->design({})'; + + if ($db = $store->load($attrs)) { + ($files, $markup) = split /__MARKUP__/, $db->content; + $files = [grep {/\w/} split /\n/, $files]; + } + else { + ($files, $markup) = $self->_generate($assets); + $db = join "\n", @$files, __MARKUP__ => $markup; + $store->save(\$db, $attrs); + } + + for my $url (@$files) { + push @icons, $store->asset($url) + or die "AssetPack was unable to fetch icon asset $url"; + } + + $self->assetpack->{by_checksum}{$_->checksum} = $_ for @icons; + $self->assetpack->{by_topic}{$self->topic} = Mojo::Collection->new(@icons); + + for my $child (Mojo::DOM->new($markup)->children->each) { + my $key = $child->{content} ? 'content' : 'href'; + push @{$self->_icons}, [$key => $child, shift @icons]; + } + + if (@icons) { + my $child + = Mojo::DOM->new('<link rel="shortcut icon" href="favicon.ico">')->children->first; + push @{$self->_icons}, [href => $child, shift @icons]; + } +} + +sub render { + my ($self, $c) = @_; + my $icons = $self->_icons; + $_->[1]{$_->[0]} = $_->[2]->url_for($c) for @$icons; + return Mojo::ByteStream->new(join "\n", map { $_->[1] } @$icons); +} + +sub _generate { + my ($self, $assets) = @_; + my $res = $self->assetpack->ua->post($URL, json => $self->_request($assets))->res; + + unless ($res->code eq '200') { + my $json = $res->json || {}; + die sprintf '[AssetPack] Could not generate favicon: %s', + $json->{favicon_generation_result}{result}{error_message} || $res->error->{message}; + } + + my $data = $res->json->{favicon_generation_result}{favicon}; + my $files = $data->{files_urls} || []; + my $markup = $data->{html_code} + or die qq|[AssetPack] No html_code generated. Invalid pipe("Favicon")->design({})..?|; + return ($files, $markup) if @$files; + die qq|[AssetPack] No favicons generated. Invalid pipe("Favicon")->design({})..?|; +} + +sub _request { + my ($self, $assets) = @_; + + return { + favicon_generation => { + api_key => $self->api_key, + favicon_design => $self->design, + settings => $self->settings, + files_location => {type => 'path', path => '/'}, + master_picture => + {content => Mojo::Util::b64_encode($assets->first->content), type => 'inline'} + } + }; +} + +1; + +=encoding utf8 + +=head1 NAME + +Mojolicious::Plugin::AssetPack::Pipe::Favicon - Generate favicons + +=head1 SYNOPSIS + +=head2 Application + + plugin AssetPack => {pipes => ["Favicon"]}; + app->asset->pipe("Favicon")->api_key("fd27cc5654345678765434567876545678765556"); + app->asset->process("favicon.ico" => "images/favicon.png"); + +Note that the topic must be "favicon.ico". + +The input image file should be 260x260 for optimal results. + +=head2 Template + + %= asset "favicon.ico" + +The above template will expand to whatever HTML that +L<http://realfavicongenerator.net> has generated, based on L</design>. Example: + + <link rel="icon" type="image/png" href="/asset/52eaz7613a/favicon-16x16.png" sizes="16x16"> + <link rel="icon" type="image/png" href="/asset/65428718f1/favicon-32x32.png" sizes="32x32"> + <link rel="apple-touch-icon" sizes="114x114" href="/asset/9aab8718f1/apple-touch-icon-114x114.png"> + <link rel="apple-touch-icon" sizes="152x152" href="/asset/feee661542/apple-touch-icon-152x152.png"> + <meta name="msapplication-square310x310logo" content="/asset/123ab718f1/largelogo.png"> + <meta name="msapplication-wide310x150logo" content="/asset/a827bfddf0/widelogo.png"> + +By default this pipe will only create desktop icons. Configure L</design> for +more icons. + +=head1 DESCRIPTION + +L<Mojolicious::Plugin::AssetPack::Pipe::Favicon> uses +L<http://realfavicongenerator.net> to generate all the different favicons that +is required for your site. + +This pipe is EXPERIMENTAL. Let me know if you are using it. + +=head1 ATTRIBUTES + +=head2 api_key + + $self = $self->api_key($key); + $str = $self->api_key; + +An API key obtained from L<http://realfavicongenerator.net/api/>. + +=head2 design + + $hash = $self->design; + $self = $self->design({desktop_browser => {}, ios => {}, windows => {}}); + +Can be used to customize the different designs. Look for "favicon_design" on +L<http://realfavicongenerator.net/api/non_interactive_api> for details. + +=head2 settings + + $hash = $self->settings; + $self = $self->settings({compression => 3}); + +Can be used to customize the different settings. Look for "settings" on +L<http://realfavicongenerator.net/api/non_interactive_api> for details. + +=head1 METHODS + +=head2 process + +See L<Mojolicious::Plugin::AssetPack::Pipe/process>. + +=head2 render + + $bytestream = $self->render($c); + +Used to render the favicons as HTML. + +=head1 TODO + +Add support for different icons for each platform. + +=head1 SEE ALSO + +L<http://realfavicongenerator.net>. + +L<https://css-tricks.com/favicon-quiz/>. + +L<Mojolicious::Plugin::AssetPack>. + +=cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Pipe/Jpeg.pm new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Pipe/Jpeg.pm --- old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Pipe/Jpeg.pm 2016-05-09 22:09:31.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Pipe/Jpeg.pm 2016-07-18 14:52:52.000000000 +0200 @@ -21,7 +21,6 @@ $attrs->{key} = sprintf '%s-min', $self->app; $attrs->{minified} = 1; return if $asset->format !~ /^jpe?g$/ or $asset->minified; - $asset->tag_helper('image'); return unless $self->assetpack->minify; return $asset->content($file)->minified(1) if $file = $store->load($attrs); diag 'Process "%s", with checksum %s.', $asset->url, $attrs->{checksum} if DEBUG; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Pipe/Png.pm new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Pipe/Png.pm --- old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack/Pipe/Png.pm 2016-05-09 21:55:17.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack/Pipe/Png.pm 2016-07-18 18:41:52.000000000 +0200 @@ -23,7 +23,6 @@ $attrs->{key} = sprintf '%s-min', $self->app; $attrs->{minified} = 1; return if $asset->format ne 'png' or $asset->minified; - $asset->tag_helper('image'); return unless $self->assetpack->minify; return $asset->content($file)->minified(1) if $file = $store->load($attrs); diag 'Process "%s", with checksum %s.', $asset->url, $attrs->{checksum} if DEBUG; @@ -54,18 +53,20 @@ Mojolicious::Plugin::AssetPack::Pipe::Png - Crush PNG image files +=head1 SYNOPSIS + =head2 Application plugin AssetPack => {pipes => ["Png"]}; # Forces the use of "optipng -clobber -preserve $input" - $self->pipe("Png")->app("optipng"); + app->asset->pipe("Png")->app("optipng"); # Forces the use of "pngquant --speed 2 -" - $self->pipe("Png")->app("pngquant"); + app->asset->pipe("Png")->app("pngquant"); # Set custom application arguments: - $self->pipe("Png")->app("pngquant")->app_args([qw(--speed 10 --ordered -)]); + app->asset->pipe("Png")->app("pngquant")->app_args([qw(--speed 10 --ordered -)]); =head1 DESCRIPTION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack.pm new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack.pm --- old/Mojolicious-Plugin-AssetPack-1.16/lib/Mojolicious/Plugin/AssetPack.pm 2016-06-29 19:05:43.000000000 +0200 +++ new/Mojolicious-Plugin-AssetPack-1.17/lib/Mojolicious/Plugin/AssetPack.pm 2016-07-18 18:43:23.000000000 +0200 @@ -6,7 +6,14 @@ use Mojolicious::Plugin::AssetPack::Store; use Mojolicious::Plugin::AssetPack::Util qw(diag has_ro load_module DEBUG); -our $VERSION = '1.16'; +our $VERSION = '1.17'; + +my %TAG_TEMPLATE; +$TAG_TEMPLATE{css} = [qw(link rel stylesheet href)]; +$TAG_TEMPLATE{ico} = [qw(link rel icon href)]; +$TAG_TEMPLATE{js} = [qw(script src)]; +$TAG_TEMPLATE{$_} = [qw(img src)] for qw(gif jpg jpeg png svg); +$TAG_TEMPLATE{$_} = [qw(source src)] for qw(mp3 mp4 ogg ogv webm); has minify => sub { shift->_app->mode eq 'development' ? 0 : 1 }; @@ -24,6 +31,23 @@ ); }; +has tag_for => sub { + my $self = shift; + my $favicon = $self->pipe('Favicon') ? 1 : 0; + + Scalar::Util::weaken($self); + return sub { + my ($asset, $c, $args, @attrs) = @_; + return $self->pipe('Favicon')->render($c) + if $args->{topic} eq 'favicon.ico' and $favicon; + my $url = $asset->url_for($c); + my @template = @{$TAG_TEMPLATE{$_->format} || $TAG_TEMPLATE{css}}; + splice @template, 1, 0, type => $c->app->types->type($asset->format) + if $template[0] eq 'source'; + return $c->tag(@template, Mojo::URL->new("$args->{base_url}$url"), @attrs); + }; +}; + has_ro ua => sub { Mojo::UserAgent->new->max_redirects(3) }; sub pipe { @@ -68,10 +92,7 @@ $self; } -sub processed { - my ($self, $topic) = @_; - return $self->{by_topic}{$topic}; -} +sub processed { $_[0]->{by_topic}{$_[1]} } sub register { my ($self, $app, $config) = @_; @@ -93,7 +114,7 @@ if ($config->{pipes}) { $self->_pipes($config->{pipes}); - $app->helper($helper => sub { @_ == 1 ? $self : $self->_tag_helpers(@_) }); + $app->helper($helper => sub { @_ == 1 ? $self : $self->_render_tags(@_) }); } else { $app->log->warn('Loading DEPRECATED Mojolicious::Plugin::AssetPack::Backcompat.'); @@ -161,6 +182,20 @@ $self; } +sub _render_tags { + my ($self, $c, $topic, @attrs) = @_; + my $route = $self->route; + my $assets = $self->{by_topic}{$topic} ||= $self->_static_asset($topic); + my %args; + + $args{base_url} = $route->pattern->defaults->{base_url} || ''; + $args{base_url} =~ s!/+$!!; + $args{topic} = $topic; + + return $assets->grep(sub { !$_->isa('Mojolicious::Plugin::AssetPack::Asset::Null') }) + ->map($self->tag_for, $c, \%args, @attrs)->join("\n"); +} + sub _reset { my ($self, $args) = @_; @@ -187,24 +222,13 @@ $c->rendered; } -sub _tag_helpers { - my ($self, $c, $topic, @attrs) = @_; - my $route = $self->route; - my $base_url = $route->pattern->defaults->{base_url} || ''; - my $assets = $self->{by_topic}{$topic} +sub _static_asset { + my ($self, $topic) = @_; + my $asset = $self->store->asset($topic) or die qq(No assets registered by topic "$topic".); - - $base_url =~ s!/+$!!; - $base_url = Mojo::URL->new($base_url) if $base_url; - - return $assets->grep(sub { !$_->isa('Mojolicious::Plugin::AssetPack::Asset::Null') }) - ->map( - sub { - my $tag_helper = $_->tag_helper; - my $url = Mojo::URL->new($base_url . $c->url_for(assetpack => $_->TO_JSON)); - $c->$tag_helper($url, @attrs); - } - )->join("\n"); + my $assets = Mojo::Collection->new($asset); + $self->{by_checksum}{$_->checksum} = $_ for @$assets; + return $assets; } sub DESTROY { @@ -222,7 +246,7 @@ =head1 VERSION -1.16 +1.17 =head1 SYNOPSIS @@ -334,7 +358,7 @@ =head1 HELPERS -=head1 asset +=head2 asset $self = $app->asset; $self = $c->asset; @@ -386,6 +410,30 @@ Holds a L<Mojolicious::Plugin::AssetPack::Store> object used to locate, store and serve assets. +=head2 tag_for + + $self = $self->tag_for(sub { my ($asset, $c, \%args, @attrs) = @_; }); + $code = $self->tag_for; + +Holds a sub reference that returns a L<Mojo::Bytestream> object containing the +markup required to render an asset. + +C<$asset> is a L<Mojolicious::Plugin::AssetPack::Asset> object, C<$c> is an +L<Mojolicious::Controller> object and C<@attrs> can contain a list of +HTML attributes. C<%args> currently contains: + +=over 4 + +=item * base_url + +See L<Mojolicious::Plugin::AssetPack::Guides::Cookbook/ASSETS FROM CUSTOM DOMAIN>. + +=item * topic + +Name of the current topic. + +=back + =head2 ua $ua = $self->ua; Files old/Mojolicious-Plugin-AssetPack-1.16/t/assets/image/master_favicon_thumbnail.png and new/Mojolicious-Plugin-AssetPack-1.17/t/assets/image/master_favicon_thumbnail.png differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.gif new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.gif --- old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.gif 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.gif 2016-07-18 14:52:52.000000000 +0200 @@ -0,0 +1 @@ +dummy.gif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.ico new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.ico --- old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.ico 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.ico 2016-07-18 14:52:52.000000000 +0200 @@ -0,0 +1 @@ +dummy.ico diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.mp3 new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.mp3 --- old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.mp3 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.mp3 2016-07-18 14:52:52.000000000 +0200 @@ -0,0 +1 @@ +dummy.mp3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.mp4 new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.mp4 --- old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.mp4 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.mp4 2016-07-18 14:52:52.000000000 +0200 @@ -0,0 +1 @@ +dummy.mp4 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.ogg new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.ogg --- old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.ogg 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.ogg 2016-07-18 14:52:52.000000000 +0200 @@ -0,0 +1 @@ +dummy.ogg diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.ogv new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.ogv --- old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.ogv 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.ogv 2016-07-18 14:52:52.000000000 +0200 @@ -0,0 +1 @@ +dummy.ogv diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.svg new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.svg --- old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.svg 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.svg 2016-07-18 14:52:52.000000000 +0200 @@ -0,0 +1 @@ +dummy.svg diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.webm new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.webm --- old/Mojolicious-Plugin-AssetPack-1.16/t/assets/other/dummy.webm 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/assets/other/dummy.webm 2016-07-18 14:52:52.000000000 +0200 @@ -0,0 +1 @@ +dummy.webm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/favicon.t new/Mojolicious-Plugin-AssetPack-1.17/t/favicon.t --- old/Mojolicious-Plugin-AssetPack-1.16/t/favicon.t 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/favicon.t 2016-07-18 18:43:12.000000000 +0200 @@ -0,0 +1,21 @@ +use t::Helper; + +plan skip_all => 'TEST_REALFAVICONGENERATOR_API_KEY=is_not_set' + unless $ENV{TEST_REALFAVICONGENERATOR_API_KEY}; + +my $t = t::Helper->t(pipes => [qw(Favicon)]); +$t->app->asset->pipe('Favicon')->api_key($ENV{TEST_REALFAVICONGENERATOR_API_KEY}); +$t->app->asset->process('favicon.ico' => '/image/master_favicon_thumbnail.png'); +$t->get_ok('/')->status_is(200)->element_exists('[sizes="16x16"]') + ->element_exists('[sizes="32x32"]'); + +like $t->tx->res->dom->at('[rel="shortcut icon"]')->{href}, qr{/favicon\.ico$}, + 'plain favicon'; +$t->get_ok($t->tx->res->dom->at('[sizes="16x16"]')->{href})->status_is(200); + +done_testing; + +__DATA__ +@@ index.html.ep +favicon! +%= asset 'favicon.ico' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Mojolicious-Plugin-AssetPack-1.16/t/other.t new/Mojolicious-Plugin-AssetPack-1.17/t/other.t --- old/Mojolicious-Plugin-AssetPack-1.16/t/other.t 1970-01-01 01:00:00.000000000 +0100 +++ new/Mojolicious-Plugin-AssetPack-1.17/t/other.t 2016-07-18 14:52:52.000000000 +0200 @@ -0,0 +1,37 @@ +use t::Helper; + +my %expected_element = ( + gif => q(img[src="/asset/d220f096b3/dummy.gif"]), + ico => q(link[rel="icon"][href="/asset/40c24538f4/dummy.ico"]), + mp3 => q(source[type="audio/mpeg"][src="/asset/1710ca7e28/dummy.mp3"]), + mp4 => q(source[type="video/mp4"][src="/asset/228088807c/dummy.mp4"]), + ogg => q(source[type="audio/ogg"][src="/asset/641f8d27ad/dummy.ogg"]), + ogv => q(source[type="video/ogg"][src="/asset/cbfe0298bd/dummy.ogv"]), + svg => q(img[src="/asset/64705cb07d/dummy.svg"]), + webm => q(source[type="video/webm"][src="/asset/fc19b68890/dummy.webm"]), +); + +my $t = t::Helper->t(pipes => ['Combine']); + +for my $ext (sort keys %expected_element) { + my $attr = $ext =~ /ico/ ? 'href' : 'src'; + + $t->get_ok('/')->status_is(200)->element_exists($expected_element{$ext}, $ext); + next unless my $elem = $t->tx->res->dom->at($expected_element{$ext}); + $t->get_ok($elem->{$attr})->status_is(200) + ->header_is('Content-Type' => $t->app->types->type($ext)); +} + +done_testing; + +__DATA__ +@@ index.html.ep +hey! +%= asset '/other/dummy.gif' +%= asset '/other/dummy.ico' +%= asset '/other/dummy.mp3' +%= asset '/other/dummy.mp4' +%= asset '/other/dummy.ogg' +%= asset '/other/dummy.ogv' +%= asset '/other/dummy.svg' +%= asset '/other/dummy.webm'