package Firefox::Application::API35; use strict; use parent 'Firefox::Application'; use vars qw($VERSION); $VERSION = '0.71'; =head1 NAME Firefox::Application::API35 - API wrapper for Firefox 3.5+ =head1 SYNOPSIS use Firefox::Application; my $ff = Firefox::Application->new( # Force the Firefox 3.5 API api => 'Firefox::Application::API35', ); =head1 METHODS =head2 C<< $api->updateitems( %args ) >> for my $item ($api->updateitems) { print sprintf "Name: %s\n", $item->{name}; print sprintf "Version: %s\n", $item->{version}; print sprintf "GUID: %s\n", $item->{id}; }; Returns the list of updateable items. Under Firefox 4, can be restricted by the C option. =over 4 =item * C - type of items to fetch C - fetch any item C - fetch add-ons C - fetch locales C - fetch themes =back =cut sub updateitems { my ($self, %options) = @_; my $repl = delete $options{ repl } || $self->repl; my $type = $options{type} || 'ANY'; my $addons_js = $repl->declare(sprintf( <<'JS', $type), 'list'); function () { var em = Components.classes["@mozilla.org/extensions/manager;1"] .getService(Components.interfaces.nsIExtensionManager); var type = Components.interfaces.nsIUpdateItem.TYPE_%s; var count = {}; var list = em.getItemList(type, count); return list }; JS $addons_js->() }; sub addons { my $self = shift; $self->updateitems(type => 'ADDON', @_); }; sub themes { my $self = shift; $self->updateitems(type => 'THEME', @_); }; sub locales { my $self = shift; $self->updateitems(type => 'LOCALE', @_); }; sub selectedTab { my ($self,%options) = @_; my $repl = delete $options{ repl } || $self->repl; return $self->browser( $repl )->{tabContainer}->{selectedItem}; } sub addTab { my ($self, %options) = @_; my $repl = $options{ repl } || $self->repl; my $tab = $self->browser( $repl )->addTab(); if (not exists $options{ autoclose } or $options{ autoclose }) { $self->autoclose_tab($tab) }; $tab }; sub autoclose_tab { my ($self,$tab) = @_; my $release = join "", q, q, q

, q<};>, q, ; $tab->__release_action($release); }; =head2 C<< $ff->closeTab( $tab [,$repl] ) >> $ff->closeTab( $tab ); Close the given tab. =cut sub closeTab { my ($self,$tab,$repl) = @_; $repl ||= $self->repl; my $close_tab = $repl->declare(<<'JS'); function(tab) { // find containing browser var p = tab.parentNode; while (p.tagName != "tabbrowser") { p = p.parentNode; }; if(p){p.removeTab(tab)}; } JS return $close_tab->($tab); } sub openTabs { my ($self,$repl) = @_; $repl ||= $self->repl; my $open_tabs = $repl->declare(<<'JS', 'list'); function() { var idx = 0; var tabs = []; var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] .getService(Components.interfaces.nsIWindowMediator); var en = wm.getEnumerator('navigator:browser'); while( en.hasMoreElements() ) { var win= en.getNext(); var browser = win.getBrowser(); Array.prototype.forEach.call( browser.tabContainer.childNodes, function(tab) { var d = tab.linkedBrowser.contentWindow.document; tabs.push({ location: d.location.href, document: d, title: d.title, "id": d.id, index: idx++, panel: tab.linkedPanel, tab: tab, }); }); }; return tabs; } JS $open_tabs->(); } =head2 C<< $api->element_query( \@elements, \%attributes ) >> my $query = $element_query(['input', 'select', 'textarea'], { name => 'foo' }); Returns the XPath query that searches for all elements with Cs in C<@elements> having the attributes C<%attributes>. The C<@elements> will form an C condition, while the attributes will form an C condition. =cut sub element_query { my ($self, $elements, $attributes) = @_; my $query = './/*[(' . join( ' or ', map { sprintf qq{local-name(.)="%s"}, uc $_ } @$elements ) . ') and ' . join( " and ", map { sprintf q{@%s="%s"}, $_, $attributes->{$_} } sort keys(%$attributes) ) . ']'; }; 1; =head1 AUTHOR Max Maischein C =head1 COPYRIGHT (c) Copyright 2009-2012 by Max Maischein C. =head1 LICENSE This module is released under the same terms as Perl itself. =cut