todo task #556
John Williams <[email protected]>
| Newsgroups | gmane.comp.web.mason.devel |
|---|---|
| Message-ID | <[email protected]> |
> New task #556: Allow </&> tag to contain literal start path > If a <&| &> tag contains a literal string FOO (first > character one of [\w/_.]), allow either </&> or </& FOO> as > an end tag. If the tag contains an expression, only </&> can > be used. > Sat Sep 25 Jonathan Swartz created task > Jonathan Swartz set difficulty to 2 > Jonathan Swartz writes: See > http://marc.theaimsgroup.com/?t=109544641200002&r=1&w=2 for > one of many design discussions. > http://www.masonhq.com/docs/todo/access.html?id=556 You can make me the owner of this one. I don't seem to have access to change the todo list myself. I have attached the patch as it exists so far, if anyone wants to comment on it. Code and tests are done. I just need to add something to the documentation. ~ John Williams
cwcend.patch
(text/plain, 5.4 KB)
Index: lib/HTML/Mason/Compiler.pm
===================================================================
RCS file: /cvsroot/mason/mason/dist/lib/HTML/Mason/Compiler.pm,v
retrieving revision 1.109
diff -u -r1.109 Compiler.pm
--- lib/HTML/Mason/Compiler.pm 29 Mar 2004 21:55:41 -0000 1.109
+++ lib/HTML/Mason/Compiler.pm 27 Sep 2004 18:03:00 -0000
@@ -406,7 +406,7 @@
# Error if def and method defined with same name
my $other_type = $p{block_type} eq 'def' ? 'method' : 'def';
$self->lexer->throw_syntax_error
- ("Cannot define a method and subcomponent with the same name ($p{name}")
+ ("Cannot define a method and subcomponent with the same name ($p{name})")
if exists $c->{$other_type}{ $p{name} };
$c->{in_main}--;
@@ -527,19 +527,34 @@
{
my $self = shift;
my $c = $self->{current_compile};
+ my %p = @_;
- $self->lexer->throw_syntax_error("found component with content ending tag but no beginning tag")
+ $self->lexer->throw_syntax_error("Found component with content ending tag but no beginning tag")
unless @{ $c->{comp_with_content_stack} };
my $call = pop @{ $c->{comp_with_content_stack} };
+ my $call_end = $p{call_end};
+ for ($call_end) { s/^\s+//; s/\s+$//; }
+ my $comp = undef;
if ( $call =~ m,^[\w/.],)
{
my $comma = index($call, ',');
$comma = length $call if $comma == -1;
- (my $comp = substr($call, 0, $comma)) =~ s/\s+$//;
+ ($comp = substr($call, 0, $comma)) =~ s/\s+$//;
$call = "'$comp'" . substr($call, $comma);
}
+ if ($call_end) {
+ if ($call_end !~ m,^[\w/.],) {
+ $self->lexer->throw_syntax_error("Cannot use an expression inside component with content ending tag; use a bare component name or </&> instead");
+ }
+ if (!defined($comp)) {
+ $self->lexer->throw_syntax_error("Cannot match an expression as a component name; use </&> instead");
+ }
+ if ($call_end ne $comp) {
+ $self->lexer->throw_syntax_error("Component name in ending tag ($call_end) does not match component name in beginning tag ($comp)");
+ }
+ }
my $code = "} }, $call\n );\n";
Index: lib/HTML/Mason/Lexer.pm
===================================================================
RCS file: /cvsroot/mason/mason/dist/lib/HTML/Mason/Lexer.pm,v
retrieving revision 1.97
diff -u -r1.97 Lexer.pm
--- lib/HTML/Mason/Lexer.pm 16 Sep 2004 16:03:12 -0000 1.97
+++ lib/HTML/Mason/Lexer.pm 27 Sep 2004 18:03:00 -0000
@@ -484,9 +484,11 @@
{
my $self = shift;
- if ( $self->{current}{comp_source} =~ m,\G</&>,gc )
+ if ( $self->{current}{comp_source} =~ m,\G</&(.*?)>,gc )
{
- $self->{current}{compiler}->component_content_call_end;
+ my $call = $1 || '';
+ $self->{current}{compiler}->component_content_call_end( call_end => $call );
+ $self->{current}{lines} += $call =~ tr/\n//;
return 1;
}
Index: t/09a-comp_content.t
===================================================================
RCS file: /cvsroot/mason/mason/dist/t/09a-comp_content.t,v
retrieving revision 1.9
diff -u -r1.9 09a-comp_content.t
--- t/09a-comp_content.t 14 Jul 2003 18:01:12 -0000 1.9
+++ t/09a-comp_content.t 27 Sep 2004 18:03:00 -0000
@@ -432,6 +432,88 @@
#------------------------------------------------------------
+ $group->add_test( name => 'ending_tag_match',
+ description => 'Test </& comp >',
+ component => <<'EOF',
+<&|.outer &>\
+<&| .inner, dummy=>1 &>\
+This is the content
+</&.inner >
+</& .outer>
+<%def .inner>\
+% $m->print("inner: ".$m->content);
+</%def>
+<%def .outer>\
+% $m->print("outer: ".$m->content);
+</%def>
+EOF
+ expect => <<'EOF',
+outer: inner: This is the content
+EOF
+ );
+
+#------------------------------------------------------------
+
+ $group->add_test( name => 'ending_tag_nomatch',
+ description => 'Test bad </& comp > match',
+ component => <<'EOF',
+<&|.outer &>\
+<&| .inner&>\
+This is the content
+</&.outer >
+</& .inner>
+<%def .inner>\
+% $m->print("inner: ".$m->content);
+</%def>
+<%def .outer>\
+% $m->print("outer: ".$m->content);
+</%def>
+EOF
+ expect_error => 'Component name in ending tag \(\.outer\) does not match component name in beginning tag \(\.inner\)',
+ );
+
+#------------------------------------------------------------
+
+ $group->add_test( name => 'ending_tag_expr',
+ description => 'Test expr in <& expr> not matched',
+ component => <<'EOF',
+<&| ".outer" &>\
+<&| ".inner" &>\
+This is the content
+</&>
+</& .outer >
+<%def .inner>\
+% $m->print("inner: ".$m->content);
+</%def>
+<%def .outer>\
+% $m->print("outer: ".$m->content);
+</%def>
+EOF
+ expect_error => 'Cannot match an expression as a component name',
+ );
+
+#------------------------------------------------------------
+
+ $group->add_test( name => 'ending_tag_expr2',
+ description => 'Test expr in </&> not allowed',
+ component => <<'EOF',
+<&| ".outer" &>\
+<&| ".inner" &>\
+This is the content
+</&>
+</& ".inner" >
+<%def .inner>\
+% $m->print("inner: ".$m->content);
+</%def>
+<%def .outer>\
+% $m->print("outer: ".$m->content);
+</%def>
+EOF
+ expect_error => 'Cannot use an expression inside component with content ending tag',
+ );
+
+#------------------------------------------------------------
+
return $group;
}