Skip to content

Commit

Permalink
improved performance of Mojo::DOM::at significantly
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Dec 16, 2013
1 parent d644ac6 commit 6028ab1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 34 deletions.
4 changes: 3 additions & 1 deletion Changes
@@ -1,5 +1,7 @@

4.61 2013-12-15
4.61 2013-12-16
- Added first method to Mojo::DOM::CSS.
- Improved performance of Mojo::DOM::at significantly.

4.60 2013-12-11
- Improved Mojolicious::Validator::Validation to allow custom validation
Expand Down
20 changes: 9 additions & 11 deletions lib/Mojo/DOM.pm
Expand Up @@ -49,7 +49,11 @@ sub append_content {
return $self;
}

sub at { shift->find(@_)->[0] }
sub at {
my $self = shift;
return undef unless my $result = $self->_css->first(@_);
return $self->new->tree($result)->xml($self->xml);
}

sub attr {
my $self = shift;
Expand Down Expand Up @@ -80,17 +84,9 @@ sub content_xml {
return join '', map { _render($_, $xml) } _nodes($self->tree);
}

sub find {
my $self = shift;
my $results = Mojo::DOM::CSS->new(tree => $self->tree)->select(@_);
return $self->_collect(@$results);
}
sub find { $_[0]->_collect(@{$_[0]->_css->select($_[1])}) }

sub match {
my $self = shift;
return undef unless Mojo::DOM::CSS->new(tree => $self->tree)->match(@_);
return $self;
}
sub match { $_[0]->_css->match($_[1]) ? $_[0] : undef }

sub namespace {
my $self = shift;
Expand Down Expand Up @@ -246,6 +242,8 @@ sub _content {
return _text([_nodes($tree)], shift, _trim($tree, @_));
}

sub _css { Mojo::DOM::CSS->new(tree => shift->tree) }

sub _delegate {
my ($self, $method) = (shift, shift);
return $self->[0]->$method unless @_;
Expand Down
56 changes: 34 additions & 22 deletions lib/Mojo/DOM/CSS.pm
Expand Up @@ -33,35 +33,16 @@ my $TOKEN_RE = qr/
)?
/x;

sub first { shift->_select(1, @_) }

sub match {
my $self = shift;
my $tree = $self->tree;
return undef if $tree->[0] eq 'root';
return $self->_match($self->_compile(shift), $tree, $tree);
}

sub select {
my $self = shift;

my @results;
my $pattern = $self->_compile(shift);
my $tree = $self->tree;
my @queue = ($tree);
while (my $current = shift @queue) {
my $type = $current->[0];

# Tag
if ($type eq 'tag') {
unshift @queue, @$current[4 .. $#$current];
push @results, $current if $self->_match($pattern, $current, $tree);
}

# Root
elsif ($type eq 'root') { unshift @queue, @$current[1 .. $#$current] }
}

return \@results;
}
sub select { shift->_select(0, @_) }

sub _ancestor {
my ($self, $selectors, $current, $tree) = @_;
Expand Down Expand Up @@ -314,6 +295,30 @@ sub _regex {
return qr/^$value$/;
}

sub _select {
my ($self, $first) = (shift, shift);

my @results;
my $pattern = $self->_compile(shift);
my $tree = $self->tree;
my @queue = ($tree);
while (my $current = shift @queue) {
my $type = $current->[0];

# Tag
if ($type eq 'tag') {
unshift @queue, @$current[4 .. $#$current];
next unless $self->_match($pattern, $current, $tree);
$first ? return $current : push @results, $current;
}

# Root
elsif ($type eq 'root') { unshift @queue, @$current[1 .. $#$current] }
}

return $first ? undef : \@results;
}

sub _selector {
my ($self, $selector, $current) = @_;

Expand Down Expand Up @@ -611,6 +616,13 @@ carefully since it is very dynamic.
L<Mojo::DOM::CSS> inherits all methods from L<Mojo::Base> and implements the
following new ones.
=head2 first
my $result = $css->first('head > title');
Run CSS selector against L</"tree"> and stop immediately after the first node
matched.
=head2 match
my $bool = $css->match('head > title');
Expand Down

0 comments on commit 6028ab1

Please sign in to comment.