File Coverage

blib/lib/Mozilla/Mechanize/GUITester/Gesture.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1 11     11   62 use strict;
  11         23  
  11         491  
2 11     11   67 use warnings FATAL => 'all';
  11         26  
  11         628  
3              
4             package Mozilla::Mechanize::GUITester::Gesture;
5 11     11   58 use base 'Class::Accessor';
  11         19  
  11         12124  
6 11     11   45946 use Mozilla::DOM;
  0            
  0            
7             use X11::GUITest qw(GetWindowPos MoveMouseAbs);
8             use Mozilla::DOM::ComputedStyle;
9             use Carp;
10              
11             __PACKAGE__->mk_accessors(qw(element element_top element_left window_x
12             zoom window_y dom_window window_id));
13              
14             sub _D { print STDERR "# $_[0]\n" if $ENV{MMG_DEBUG}; }
15              
16             sub _get_window_position {
17             my $self = shift;
18             my ($x, $y) = GetWindowPos($self->window_id);
19             $self->window_x($x);
20             $self->window_y($y);
21             }
22              
23             sub _calculate_element_position {
24             my $self = shift;
25             my ($top, $left) = (0, 0);
26             my $elem = $self->element;
27             my $iid = Mozilla::DOM::NSHTMLElement->GetIID;
28             while ($elem) {
29             $elem = $elem->QueryInterface($iid) or last;
30             $top += $elem->GetOffsetTop * $self->zoom;
31             $left += $elem->GetOffsetLeft * $self->zoom;
32             $elem = $elem->GetOffsetParent;
33             }
34             $self->element_top($top);
35             $self->element_left($left);
36             }
37              
38             sub _adjust_one {
39             my ($e, $what, $d, $max) = @_;
40             my $set = "SetScroll$what";
41             my $get = "GetScroll$what";
42             my $g = $e->$get or return;
43             _D("begin _adjust_one $g $what $d $max");
44             $e->$set($g + $d) if ($d < 0 || $d > $max);
45             }
46              
47             sub _adjust_scrolls {
48             my ($self, $by_x, $by_y) = @_;
49             confess "No element" unless $self->element;
50             my $iid = Mozilla::DOM::NSHTMLElement->GetIID;
51             my $elem = $self->element->QueryInterface(Mozilla::DOM::Node->GetIID);
52             my $pos = Get_Computed_Style_Property($self->dom_window, $elem , "position");
53              
54             $elem->QueryInterface($iid)->ScrollIntoView(1);
55             my ($left, $top) = ($self->element_left, $self->element_top);
56             _D("begin _adjust_scrolls $left $top");
57             goto OUT if ($pos eq 'fixed');
58             while ($elem = $elem->GetParentNode) {
59             goto OUT if Get_Computed_Style_Property($self->dom_window, $elem
60             , "position") eq 'fixed';
61              
62             my $e;
63             eval { $e = $elem->QueryInterface($iid); };
64             next unless $e;
65              
66             _adjust_one($e, "Top", $by_y, $e->GetClientHeight);
67             _adjust_one($e, "Left", $by_x, $e->GetClientWidth);
68              
69             _D("adjusting scrolls $left $top "
70             . Mozilla::Mechanize::GUITester->qi($e)->GetTagName . " "
71             . $e->GetScrollLeft . " " . $e->GetScrollTop);
72              
73             $top -= $e->GetScrollTop * $self->zoom;
74             $left -= $e->GetScrollLeft * $self->zoom;
75             }
76             OUT:
77             return ($left + $by_x, $top + $by_y);
78             }
79              
80             sub element_x { return $_[0]->element_left + $_[0]->window_x; }
81             sub element_y { return $_[0]->element_top + $_[0]->window_y; }
82              
83             sub new {
84             my $self = shift()->SUPER::new(@_);
85             $self->_get_window_position;
86             $self->_calculate_element_position;
87             return $self;
88             }
89              
90             sub element_mouse_move {
91             my ($self, $by_x, $by_y) = @_;
92             confess "No x given " unless defined($by_x);
93             confess "No y given " unless defined($by_y);
94             _D("element_mouse_move $by_x $by_y");
95             my ($left, $top) = $self->_adjust_scrolls($by_x, $by_y);
96             _D("after _adjust_scrolls $left $top");
97             MoveMouseAbs($left + $self->window_x, $top + $self->window_y);
98             }
99              
100             sub window_mouse_move {
101             my ($self, $by_x, $by_y) = @_;
102             MoveMouseAbs($self->window_x + $by_x, $self->window_y + $by_y);
103             }
104              
105             1;