MozRepl-RemoteObject

 view release on metacpan or  search on metacpan

lib/MozRepl/RemoteObject.pm  view on Meta::CPAN

        # It's required on Firefox 3.0 only
        my $capabilities = $options{ repl }->execute(
          join "",
              # Extract version
              'Components.classes["@mozilla.org/xre/app-info;1"].',
              'getService(Components.interfaces.nsIXULAppInfo).version+"!"',
              # Native JSON object available?
              q{+eval("var r;try{r=JSON.stringify('\u30BD');}catch(e){r=''};r")},
               # UTF-8 transport detection
              '+"!\u30BD"',
              ";\n"
        );
        $capabilities =~ s/^"(.*)"\s*$/$1/;
        $capabilities =~ s/^"//;
        $capabilities =~ s/"$//;
        #warn "Capabilities: [$capabilities]";
        my ($version, $have_native, $unicode) = split /!/, $capabilities;

        #warn $unicode;
        #warn sprintf "%02x",$_ for map{ord} split //, $unicode;
        if ($have_native eq '') {
            $options{ js_JSON } ||= "json2; No native JSON object found ($version)";
        };
        if( lc $have_native eq lc q{"\u30bd"} # values get escaped
            or $have_native eq qq{"\x{E3}\x{82}\x{BD}"} # values get encoded as UTF-8
          ) {
            # so we can transport unicode properly
            $options{ js_JSON } ||= 'native';
        } else {
            $options{ js_JSON } ||= "json2; Transport not UTF-8-safe";
        };
    };

    if ($options{ js_JSON } ne 'native') {
        # send our own JSON encoder
        #warn "Installing custom JSON encoder ($options{ native_JSON })";
        require MozRepl::Plugin::JSON2;

        my $json2 = MozRepl::Plugin::JSON2->new()->process('setup');
        $options{ repl }->execute($json2);

        # Now, immediately check whether our transport is UTF-8 safe:
        my $utf8 = $options{ repl }->execute(
              q{JSON.stringify('\u30BD')}.";\n"
        );
        $utf8 =~ s/\s*$//;
        lc $utf8 eq lc q{""\u30bd""}
            or warn "Transport still not UTF-8 safe: [$utf8].\nDo you have mozrepl 1.1.0 or later installed?";
    };

    my $rn = $options{repl}->repl;
    $options{ json } ||= JSON->new->allow_nonref->ascii; # We talk ASCII
    # Is this still true? It seems to be even when we find an UTF-8 safe
    # transport above. This needs some investigation.

    # Switch the Perl-repl to multiline input mode
    # Well, better use a custom interactor and pass JSON messages that
    # are self-delimited and contain no newlines. Newline for a new message.

    # Switch the JS-repl to multiline input mode
    $options{repl}->execute("$rn.setenv('inputMode','multiline');undefined;\n");

    # Load the JS side of the JS <-> Perl bridge
    my $c = $objBridge; # make a copy
    $c =~ s/\[%\s+rn\s+%\]/$rn/g; # cheap templating
    #warn $c;

    $package->execute_command($c, %options);

    $options{ functions } = {}; # cache
    $options{ constants } = {}; # cache
    $options{ callbacks } = {}; # active callbacks

    bless \%options, $package;
};

sub execute_command {
    my ($self, $command, %options) = @_;
    $options{ repl } ||= $self->repl;
    $options{ command_sep } ||= $self->command_sep
        unless exists $options{ command_sep };
    $command =~ s/\s+$//;
    $command .= $options{ command_sep };
    $options{repl}->execute($command);
};

=head2 C<< $bridge->expr( $js, $context ) >>

Runs the Javascript passed in through C< $js > and links
the returned result to a Perl object or a plain
value, depending on the type of the Javascript result.

This is how you get at the initial Javascript object
in the object forest.

  my $window = $bridge->expr('window');
  print $window->{title};

You can also create Javascript functions and use them from Perl:

  my $add = $bridge->expr(<<JS);
      function (a,b) { return a+b }
  JS
  print $add->(2,3);
  # prints 5

The C<context> parameter allows you to specify that you
expect a Javascript array and want it to be returned
as list. To do that, specify C<'list'> as the C<$context> parameter:

  for ($bridge->expr(<<JS,'list')) { print $_ };
      [1,2,3,4]
  JS

This is slightly more efficient than passing back an array reference
and then fetching all elements.

=cut

# This is used by ->declare() so can't use it itself
sub expr {



( run in 1.379 second using v1.01-cache-2.11-cpan-140bd7fdf52 )