first go a a test and method to convert tags to events people/nap/zoom_evented_xmltags
John Napiorkowski [Mon, 21 Feb 2011 04:13:51 +0000 (23:13 -0500)]
t/tags_as_zoom_events.t [new file with mode: 0644]

diff --git a/t/tags_as_zoom_events.t b/t/tags_as_zoom_events.t
new file mode 100644 (file)
index 0000000..465b7df
--- /dev/null
@@ -0,0 +1,134 @@
+use strict;
+use warnings FATAL => 'all';
+use Test::More;
+
+{
+  eval "use HTML::Zoom; 1" ?
+    plan qw(no_plan) :
+    plan skip_all => "HTML::Zoom is not installed";
+}
+
+{
+  package BasicPage;
+  use HTML::Tags;
+
+  sub show_landing_html {
+    as_html(\&landing, (
+      title => "Welcome to the Demo Home",
+      site_version => 10,
+      new_user_link => 'create_user.html',
+    ));
+  }
+
+  sub show_landing_events {
+    as_events(\&landing, (
+      title => "Welcome to the Demo Home",
+      site_version => 10,
+      new_user_link => 'create_user.html',
+    ));
+  }
+
+  sub layout {
+    my (%data) = @_;
+    \'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+    <html>,
+      <head>,
+        <!-- here is a comment -->,
+        <title>, ($data{title} || 'Hello World'), </title>,
+      </head>,
+      <body>,
+        @{$data{content}},
+      </body>,
+    </html>;
+  }
+
+  sub landing {
+    my (%data) = @_;
+    <p>, "Hi, I'm version: ", $data{site_version}, </p>,
+    <p>, "Here's some interesting things about me", </p>,
+    <img src="smilyface.png" alt="smiles" />,
+    <ul>,
+        <li>, <a href="/user">, "My Users", </li>,
+        <li>, <a href="/user/$data{new_user_link}">, "Create", "New User", </li>,
+    </ul>;
+  }
+
+  sub process_templates {
+    my ($templates, %data) = @_;
+    for my $template(@$templates) {
+        my @processed = $template->(%data);
+        $data{content} = \@processed;
+    }
+    return @{$data{content}};
+  }
+
+  sub as_html {
+    my ($template, %data) = @_;
+    my @content = process_templates([$template, \&layout], %data);
+    return join '', HTML::Tags::to_html_string(@content);
+  }
+
+  sub as_events {
+    my ($template, %data) = @_;
+    my @content = process_templates([$template, \&layout], %data);
+    return [_convert_to_events(@content)];
+  }
+
+  sub _convert_to_events {
+    map {
+      my $raw = ref $_ ? $$_ : $_;
+      my @info = ($raw =~m{
+      (
+        (?:[^<]*) < (?:
+            ( / )? ( [^/!<>\s"'=]+ )
+            ( (?:"[^"]*"|'[^']*'|[^"'<>])+? )?
+        |   
+            (!-- .*? -- | ![^\-] .*? )
+        ) (\s*/\s*)? >
+      )
+      ([^<]*)
+      }x);
+
+      my ($whole, $is_close, $tag_name, $attrs, $comment_or_directive, 
+      $in_place_close)  = @info;
+
+      if($comment_or_directive) {
+        +{ type => 'SPECIAL', raw => $raw };
+      } elsif(!scalar(@info)) {
+        +{ type => 'TEXT', raw => $raw };
+      } else {
+        if($is_close) {
+          $tag_name =~ tr/A-Z/a-z/;
+          +{ type => 'CLOSE', name => $tag_name, raw => $raw};
+        } else {
+          $attrs = '' if !defined($attrs) or $attrs =~ /^ +$/;
+          +{
+            type => 'OPEN',
+            name => $tag_name,
+            is_in_place_close => $in_place_close,
+            HTML::Zoom::Parser::BuiltIn::_hacky_attribute_parser($attrs),
+            raw_attrs => $attrs||'',
+            raw => $whole,
+          }, $in_place_close ? 
+            +{
+              type => 'CLOSE',
+              name => $tag_name, 
+              raw => '', 
+              is_in_place_close => 1,
+            } :
+            +();
+        }
+      }
+    } @_;
+  }
+}
+
+ok my $html = BasicPage->show_landing_html;
+ok my $zoom = HTML::Zoom->from_html($html);
+ok my $events = BasicPage->show_landing_events;
+
+use Data::Dump 'dump';
+warn dump $html;
+warn dump $zoom->to_events;
+warn dump $events;
+