From: Arthur Axel 'fREW' Schmidt Date: Tue, 1 Dec 2009 14:24:15 +0000 (-0600) Subject: CSS::Declare works with arrays instead of arrayrefs X-Git-Tag: v0.003~21^2~4 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FWeb-Simple.git;a=commitdiff_plain;h=4a610f74ec432feb55a3bb6bb1269ccbda5a3c36 CSS::Declare works with arrays instead of arrayrefs --- diff --git a/Makefile.PL b/Makefile.PL index 30db0fc..b8a521e 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -3,5 +3,6 @@ use warnings FATAL => 'all'; use inc::Module::Install 0.91; all_from 'lib/Web/Simple.pm'; +requires 'Perl6::Gather'; WriteAll; diff --git a/lib/CSS/Declare.pm b/lib/CSS/Declare.pm new file mode 100644 index 0000000..f109b8d --- /dev/null +++ b/lib/CSS/Declare.pm @@ -0,0 +1,89 @@ +package CSS::Declare; + +use strict; +use warnings; + +use Perl6::Gather; + +my $IN_SCOPE = 0; + +sub import { + die "Can't import CSS::Declare into a scope when already compiling one that uses it" + if $IN_SCOPE; + my ($class, @args) = @_; + my $opts = shift(@args) if ref($args[0]) eq 'HASH'; + my $target = $class->_find_target(0, $opts); + my $unex = $class->_export_tags_into($target); + $class->_install_unexporter($unex); + $IN_SCOPE = 1; +} + +sub _find_target { + my ($class, $extra_levels, $opts) = @_; + return $opts->{into} if defined($opts->{into}); + my $level = ($opts->{into_level} || 1) + $extra_levels; + return (caller($level))[0]; +} + +my @properties = qw{ +background +background_color +border +border_collapse +border_top +color +float +font_family +font_size +list_style_type +margin +padding +}; + +sub _export_tags_into { + my ($class, $into) = @_; + for my $property (@properties) { + my $property_name = $property; + $property_name =~ tr/_/-/; + no strict 'refs'; + *{"$into\::$property"} = sub ($) { return ($property_name => $_[0]) }; + } + return sub { + foreach my $property (@properties) { + no strict 'refs'; + delete ${"${into}::"}{$property} + } + $IN_SCOPE = 0; + }; +} + +sub _install_unexporter { + my ($class, $unex) = @_; + $^H |= 0x120000; # localize %^H + $^H{'CSS::Declare::Unex'} = bless($unex, 'CSS::Declare::Unex'); +} + +sub to_css_string { + my @css = @_; + return join q{ }, gather { + while (my ($selector, $declarations) = splice(@css, 0, 2)) { + take "$selector "._generate_declarations($declarations) + } + }; +} + +sub _generate_declarations { + my $declarations = shift; + + return '{'.join(q{;}, gather { + while (my ($property, $value) = splice(@{$declarations}, 0, 2)) { + take "$property:$value" + } + }).'}'; +} + +package CSS::Declare::Unex; + +sub DESTROY { local $@; eval { $_[0]->(); 1 } || warn "ARGH: $@" } + +1; diff --git a/t/css_declare.t b/t/css_declare.t index b9bcc23..1427940 100644 --- a/t/css_declare.t +++ b/t/css_declare.t @@ -7,11 +7,10 @@ use Test::More qw(no_plan); sub foo { use CSS::Declare; - eval "color 'red'"; - [ + return ( '*' => [ color 'red' ], 'tr, td' => [ margin '1px' ], - ]; + ); } }