JS-YUI-Loader
view release on metacpan or search on metacpan
lib/JS/YUI/Loader/Manifest.pm view on Meta::CPAN
use Moose;
use Algorithm::Dependency::Ordered;
use Algorithm::Dependency::Source::HoA;
# TODO use Hash::Dirty
has catalog => qw/is ro required 1 isa JS::YUI::Loader::Catalog/;
has loader => qw/is ro isa JS::YUI::Loader/;
has collection => qw/is ro required 1 lazy 1/, default => sub { {} };
has dirty => qw/is rw required 1 lazy 1 default 1/;
has include => qw/is ro required 1 lazy 1/, default => sub {
my $self = shift;
require JS::YUI::Loader::IncludeExclude;
return JS::YUI::Loader::IncludeExclude->new(manifest => $self, do_include => 1);
};
has exclude => qw/is ro required 1 lazy 1/, default => sub {
my $self = shift;
require JS::YUI::Loader::IncludeExclude;
return JS::YUI::Loader::IncludeExclude->new(manifest => $self, do_include => 0);
};
sub schedule {
my $self = shift;
my @schedule = $self->_calculate;
return wantarray ? @schedule : \@schedule;
}
my $dependency;
sub _calculate {
my $self = shift;
if (! $self->{schedule} || $self->dirty) {
$dependency ||= Algorithm::Dependency::Ordered->new(
source => Algorithm::Dependency::Source::HoA->new($self->catalog->dependency_graph),
);
my $schedule = $dependency->schedule(keys %{ $self->collection }) || [];
my @schedule = map { $self->catalog->entry($_) } @$schedule;
my (@css_schedule, @js_schedule);
for (@schedule) {
if ($_->css) {
push @css_schedule, $_;
}
else {
push @js_schedule, $_;
}
}
# my @css_schedule = grep { $_->css } @schedule;
# my @js_schedule = grep { $_->js } @schedule;
@css_schedule = sort { $a->rank <=> $b->rank } @css_schedule;
for (@js_schedule) {
push @css_schedule, $self->catalog->entry($_->name . "-skin") if $_->skin;
}
$self->{schedule} = [ map { $_->name } @css_schedule, @js_schedule ];
}
return @{ $self->{schedule} };
}
sub parse {
my $self = shift;
my @_collection = map { split m/\n/ } @_;
my @collection;
for (@_collection) {
next if m/^\s*#/;
next if m/^\s*<!--/;
next if m/^\s*$/;
chomp;
my $name = $_;
if ($name =~ m/^\s*<script/) { ($name) = $name =~ m{src="(?:[^"]*)([^/]+)\.js"} }
elsif ($name =~ m/^\s*<link/) { ($name) = $name =~ m{href="(?:[^"]*)([^/]+)\.css"} }
$name =~ s/-beta\b//;
$name =~ s/-min\b//;
$name =~ s/-debug\b//;
push @collection, $name;
}
$self->select(@collection);
}
sub select {
my $self = shift;
for my $name (@_) {
warn "Can't find \"$name\" in the catalog" and next unless $self->catalog->entry($name);
$self->collection->{$name} = "";
}
}
sub clear {
my $self = shift;
$self->{collection} = {};
}
1;
__END__
BEGIN {
my $json = JSON->new;
my $catalog = $json->decode(map { local $_ = $_; s/'/"/g; $_ } (<<_END_));
{
'animation': {
'type': 'js',
'path': 'animation/animation-min.js',
'requires': ['dom', 'event']
},
'autocomplete': {
'type': 'js',
'path': 'autocomplete/autocomplete-min.js',
'requires': ['dom', 'event'],
'optional': ['connection', 'animation'],
'skinnable': true
},
'base': {
( run in 1.461 second using v1.01-cache-2.11-cpan-71847e10f99 )