NAME
    JavaScript::XRay - See What JavaScript is Doing

VERSION
    Version 0.94

SYNOPSIS
    I put the comments in for lazy folks like myself who cut and page the
    Synopsis before they throughly read the pod.

     #!/usr/bin/perl
     use strict;
     use warnings;
     use JavaScript::XRay;

     # HTML page with a <body> tag and hopefully some JavaScript
     # if you're using this module :)

     my $html_page = do { local $/; <> };

     # the 'alias' is the prefix which all your switches will be 
     # prefixed with and helps "scope" the injected JavaScript
     # variables and functions so they don't collide with 
     # anything in your page.

     my $alias = 'jsxray';    # jsxray is the default

     # switches is just a hash ref that could be build for 
     # incoming parameters on a query string or passed 
     # via options via a command line script

     # In the future, hooks may be built for building the 
     # switches for popular frameworks.  The idea is that you
     # want to look through the incoming param list and pass
     # anything that matches your alias.  This interface isn't
     # the cleanest, but just wanted to make it generic.  It
     # can definately be improved...

     # via CGI.pm

     # my $q = CGI->new;
     # my $switches = { 
     #     map  { $_ => $q->param($_) }
     #     grep { /^$alias/ } $q->param
     # };

     # via mod_perl

     #  my $req = Apache::Request->new($r);
     #  my $switches = { 
     #    map { $_ => $req->param($_) } 
     #    grep { /^$alias/ } $req->param
     # };

     # Catalyst

     #  my $req = $c->request;
     #  my $switches = { 
     #    map { $_ => $req->param($_) } 
     #    grep { /^$alias/ } $req->param
     # };

     # or just hard coded to get something to work

     my $switches = { $alias => 1 };

     # now we only want to filter if its turned on so we can 
     # you may want put your switch building inside this 
     # conditional as well and just check for your alias 

     # ATTENTION - also if enable filtering in your 
     # production environment, maybe have special cookie 
     # that needs to be set as well in order to enable 
     # filtering. (so Joe Somebody or Ex-Employee can't 
     # turn it on)

     if ( $switches->{$alias} == 1 ) {
         my $js_xray = JavaScript::XRay->new(
             alias    => $alias,
             switches => $switches,
         );
         $html_page = $js_xray->filter($html_page);
     }

     print $html_page;

DESCRIPTION
    JavaScript::XRay is an HTML source filter. It was developed as a tool to
    help figure out and debug large JavaScript frameworks.

    The main idea is that you hook it into your application framework and
    give you the ability to 'flip a switch' an inject a JavaScript function
    tracing console into your out going page.

  Some of the things it does...
    *   Injects an IFrame logging console

        It finds the body tag in the document and injects the IFrame just
        after it along with all the JavaScript to drive it. It also provides
        you with a method (whatever you used as alias - defaulted to
        jsxray).

           jsxray("Hi there");

    *   Scans HTML for JavaScript functions

        For each function it finds it inserts inserts a call to this method
        which logs the function call along with the value of the function
        arguments.

            function sum ( x, y ) {

        becomes

            function sum ( x, y ) {
                jsxray( "sum( " + x + ", " + y + " )" );

        so now any call this this function and its arguments will get logged
        to the IFrame.

    *   Switches to limit what you log

        You can manually skip specific functions, choose to see only
        functions you specify, or filter functions matching a specified
        string. ( see "Switches" )

    *   Provide execution counts

        Provides a method to see how often your functions are being called.
        This can be helpful to target which functions to rewrite to increase
        performance.

    *   Save the log for later.

        You can cut and paste the IFrame to a text file to analyze later by
        hand or munge the results with perl. Extremely helpful in moments
        when you have a lot of code executing and your just trying to get a
        handle on what's happening.

  Switches
    The module's initial design was for it to be used via a query string and
    the switches evolved from there. (In other words, if this switch
    interface feels clunky, thats the reason why)

    Also not the below examples use the alias 'jsxray' but if you use a
    custom alias, the urls with change accordingly.

    *   uncomment ( string1, string2, ... )

        Uncomment lines prefix with these strings. Helpful with injecting
        timing code, or more specific debugging code. You can deploy
        commented logging code to production and turn it on when your turn
        on filtering. Extremly helpful when diagnosing problems you can't
        reproduce in your development environment.

            http://someurl/somepage?jsxray=1&jsxray_uncomment=DEBUG1,DEBUG3

        will turn this...

            //DEBUG1 jsxray("Hey this is debug1");
            //DEBUG2 jsxray("Hey this is debug2");
            //DEBUG3 jsxray("Hey this is debug3");

        into this

            jsxray("Hey this is debug1");
            //DEBUG2 jsxray("Hey this is debug2");
            jsxray("Hey this is debug3");

    *   anon (bool)

        Include filtering of anonymous functions. ( bool )

            http://someurl/somepage?jsxray=1&jsxray_anon=1

    *   no_exec_count ( bool )

        Don't inject code that keeps track of how many times a function was
        called.

            http://someurl/somepage?jsxray=1&jsxray_no_exec_count=1

    *   only ( function1, function2, ... )

        Only filter comma seperated list of functions
        (function1,function2,...)

            http://someurl/somepage?jsxray=1&jsxray_only=processData,writeTopage

    *   skip ( function1, function2, ... )

        Skip comma seperated list of functions

            http://someurl/somepage?jsxray=1&jsxray_skip=formatNumber

    *   skip ( /^string/ )

        Only filter function that match string

            http://someurl/somepage?jsxray=1&jsxray_filter=ajax

CONSTRUCTOR
  JavaScript::XRay->new( %hash );
    Create a new instance with the following arguments

    *   alias

        Think of this as a JavaScript namespace. All injeted JavaScript
        fuctions and varibles are prefixed with this alias to avoid
        colliding with any code that currently exists on your page. It also
        is the prefix used for all the switches to toggle things on and off.

    *   switches

        Hash reference containing switches to change filtering behavor. See
        the "Switches" section for more details.

    *   iframe_height

        The height of your logging IFrame, defaults to 200 pixels.

    *   css_inline

        Change the style of the logging IFrame via inline CSS.

    *   css_external

        Change the style of the logging IFrame via an external stylesheet.

METHODS
  $jsxray->filter( $html );
    Pass HTML in, get modified HTML out.

INTERNAL METHODS
  _inject_js_css
    Hook to inject the alias prefixed JavaScript and CSS into the page.

  _inject_console
    Hook to inject HTML and the IFrame into the page.

  _css
    Hook to inject alias prefixed CSS into the iframe and page.

  _init_switches
    Take alias prefixed switches passed in and strip off the alias and
    repackage them.

  _warn
    Hook to warn to the JavaScript IFrame log.

AUTHOR
    Jeff Bisbee, "<jbisbee at cpan.org>"

TODO
    Some of the things that are still in the conceptional phase

    *   Inlining external JavaScript files

        The biggest short coming of this module is that fact that it doesn't
        process external JavaScript files :( I have a couple of ways to do
        this in mind but want not of them are elegant. I figured I just
        release the module first and see what ideas other folks and come up
        with a solution.

    *   Personal proxy

        Include a personal proxy script with this module so you can filter
        ANY webpage you go to.

    *   Command line filter

        Include a command line script that will just filter HTML file from
        the command line. This way you just save a page with your browser
        and you can filter it if you want. ( excellent for reverse
        engineering)

    *   Add a user interface to the console to control the switches

        Add a form to the console that will allow you to see the values of
        the switches and then resubmit the url to have the changes take
        affect.

BUGS
    Please report any bugs or feature requests to "bug-JavaScript-xray at
    rt.cpan.org", or through the web interface at
    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=JavaScript-XRay>. I will
    be notified, and then you'll automatically be notified of progress on
    your bug as I make changes.

SUPPORT
    You can find documentation for this module with the perldoc command.

        perldoc JavaScript::XRay

    You can also look for information at:

    *   AnnoCPAN: Annotated CPAN documentation

        <http://annocpan.org/dist/JavaScript-XRay>

    *   CPAN Ratings

        <http://cpanratings.perl.org/d/JavaScript-XRay>

    *   RT: CPAN's request tracker

        <http://rt.cpan.org/NoAuth/Bugs.html?Dist=JavaScript-XRay>

    *   Search CPAN

        <http://search.cpan.org/dist/JavaScript-XRay>

ACKNOWLEDGEMENTS
    *   Senta Mcadoo

        Providing the JavaScript DOM logging code in order to do the reverse
        logging (solved the scrolling problem).

    *   Ronnie Paskin

        General hacking on the code, good feedbak, and for being a sounding
        board to work out issues.

    *   Tony Fernandez

        Giving me the green light to publish this on the CPAN.

COPYRIGHT & LICENSE
    Copyright 2006 Jeff Bisbee, all rights reserved.

    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.