NAME
JavaScript::XRay - See What JavaScript is Doing
VERSION
Version 0.97
SYNOPSIS
I put the comments in for lazy folks like myself who cut and page the Synopsis before they thoroughly 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 definitely 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 logging function with the same name as your alias (defaults to jsxray)
jsxray("Hi there");
Scans HTML for JavaScript functions
For each function it finds it 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 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 refactor to increase performance.
Inlines external JavaScript files
If external javascript files are referenced, they can be inlined so they'll be filtered as well.
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, that's 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. Extremely 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.
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 separated list of functions (function1,function2,...)
http://someurl/somepage?jsxray=1&jsxray_only=processData,writeTopage
skip ( function1, function2, ... )
Skip comma separated 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 functions and variables 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 behavior. 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.
INLINING EXTERNAL JAVASCRIPT
One of the short comings of this module is that many people put their javascript in seperate file and reference them via the src attribute
<!-- inlining currently works via LWP::Simple -->
<script type="JavaScript"
src="http://www.jbisbee.com/js/test.js"></script>
<!-- inlining doesn't yet work, but will soon -->
<script type="JavaScript" src="/js/test.js"></script>
<!-- inlining doesn't yet work, but will soon -->
<script type="JavaScript" src="test.js"></script>
I have all the code in place to inline the src attribute, but only have the src =~ /^http/ handler working now. Still working out the details on how to handle inlining the others.
AUTHOR
Jeff Bisbee, <jbisbee at cpan.org>
TODO
Some of the things that are still in the conceptional phase
Personal proxy
Include a personal proxy script with this module so you can filter ANY webpage you go to.
Command line program
Include a 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
CPAN Ratings
RT: CPAN's request tracker
Search CPAN
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 feedback, 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.