CSS-Scopifier

 view release on metacpan or  search on metacpan

lib/CSS/Scopifier/Group.pm  view on Meta::CPAN

package CSS::Scopifier::Group;
use strict;
use warnings;

# ABSTRACT: Like CSS::Scopifier, but can handle rule groups

use Moo;
use Types::Standard qw(:all);

use CSS::Scopifier;
use Path::Class qw(file);
use Text::Balanced qw(extract_bracketed);

has 'group_name', is => 'ro', isa => Maybe[Str], default => sub {undef};
has 'local',      is => 'ro', isa => InstanceOf['CSS::Scopifier'], default => sub { CSS::Scopifier->new };
has '_members',   is => 'ro', isa => ArrayRef, default => sub {[]};

sub scopify {
  my $self = shift;
  $_->scopify(@_) for ($self->local,@{$self->_members});
  return 1;
}

sub write_string {
  my $self = shift;
  join("\n",
    $self->local->write_string,
    map { join('',$_->group_name," \{\n",$_->write_string,"\n\}\n") } @{$self->_members}
  )
}

sub read {
  my ($class, $file) = @_;
  $class->read_string( scalar file($file)->resolve->slurp )
}


sub read_string {
    my $self = ref $_[0] ? shift : (shift)->new;
    
    my $string = shift;
    
    # Flatten whitespace and remove /* comment */ style comments (copied from CSS::Tiny)
    $string =~ tr/\n\t/  /;
    $string =~ s!/\*.*?\*\/!!g;
    
    my $local = '';
    
    while($string) {
      my ($extracted,$remainder,$skipped) = extract_bracketed( $string, '{}', '[^\{]*' );
      
      my ($pre,$inner) = ($skipped,$extracted);
      if($pre) {
        $pre =~ s/^\s+//;
        $pre =~ s/\s+$//;
      }
      if($inner) {
        $inner =~ s/^\{//;
        $inner =~ s/\}$//;
      }
      
      # we consider this to be a 'group' if it starts with '@' and contains 
      # additional curly brace(s) within (i.e. @media print { h1 { ... } })
      if($pre && $inner && $pre =~ /^\@/ && $inner =~ /\{/) {
        push @{$self->_members}, (ref $self)
          ->new({ group_name => $pre })
          ->read_string($inner)
      }
      else {
        $self->local->read_string( join('', $skipped||'', $extracted||'') )
      }
      
      $string = $remainder;
      
      last unless ($extracted);
    }



( run in 1.339 second using v1.01-cache-2.11-cpan-39bf76dae61 )